
#include "define.h"
#include "MasterCtrlInterface.h"
#ifdef USE_WINC1500  
#else  
#include "TCPIP_Stack/TCPIP.h"
#endif
#include "NetworkProtocol.h"
#include "ProtocolDefs.h"
#include "timer.h"
#include <stdio.h>
#include "ValveCtrl.h"
#include "FlowMeter.h"

#ifdef USE_WINC1500 
#else
TCP_SOCKET MySocket;
static BYTE MasterIP[] = "192.168.0.100";
DWORD MasterPort = 2182;
#endif

int mConnectionState = MASTER_STATE_DISCONNECTED;


int InitMasterCtrlIF()
{
    ProtocolInit();
    TimerStart(MASTER_CONNECTION_TIMER,MASTER_RECONNECTION_TIMEOUT);
    return 1;
}

int ConnectToMasterCtrl()
{
#ifdef USE_WINC1500 
#else
    MySocket = TCPOpen((DWORD) (PTR_BASE) & MasterIP[0], TCP_OPEN_RAM_HOST, MasterPort, TCP_PURPOSE_GENERIC_TCP_CLIENT);

    // Abort operation if no TCP socket of type TCP_PURPOSE_GENERIC_TCP_CLIENT is available
    // If this ever happens, you need to go add one to TCPIPConfig.h
    if (MySocket == INVALID_SOCKET)
    {
        printf("Could not open socket to MasterCtrl\n");
        return 0;
    }
    printf("MasterCtrl Socket opened\n");
#endif
    return 1;
}

void TickMasterCtrlInterface()
{
#ifdef USE_WINC1500 
#else
    WORD Pending = TCPIsGetReady(MySocket);
    if (Pending != 0)
    {
      //  printf("Rx %d bytes\n",Pending);
        int i = 0;
        for(i = 0; i < Pending; i++)
        {
            BYTE Byte;
            if(TCPGet(MySocket,&Byte) == TRUE)
            {
                ProtocolAnalyzeNewData(Byte);
            }
        }
    }
    
#ifdef CONNECT_DEVICE_TO_NETWORK
    if(mConnectionState == MASTER_STATE_DISCONNECTED)
    {
        if(IsTimerExpired(MASTER_CONNECTION_TIMER))
        {
           TimerStart(MASTER_CONNECTION_TIMER,MASTER_RESPONSE_TIMEOUT);
           mConnectionState = MASTER_STATE_CONNECTING;
           ConnectToMasterCtrl();
        }
    }
    else if(mConnectionState == MASTER_STATE_CONNECTING)
    {
//       if(IsTimerExpired(MASTER_CONNECTION_TIMER) == true)  //
//        {
//           TCPClose(MySocket);
//           TimerStart(MASTER_CONNECTION_TIMER,MASTER_RESPONSE_TIMEOUT);
//           ConnectToMasterCtrl();
//        } 
    }
    else if(mConnectionState == MASTER_STATE_CONNECTED)
    {
    //    if(IsTimerExpired(MASTER_CONNECTION_TIMER))
        {
            if(TCPIsConnected(MySocket) == FALSE)
            {
                //we got disconnected...
                mConnectionState = MASTER_STATE_DISCONNECTED;
                TCPClose(MySocket);
                
                printf("Connection with MasterCtrl lost..\n");
            }
            TimerStart(MASTER_CONNECTION_TIMER,MASTER_RECONNECTION_TIMEOUT);
        }
        
    }
#endif
#endif
}

void NewMasterMessageReceived(char* Message)
{
   // char Sender = Message[FRAME_SENDER_DEVICE_ID_INDEX];
    char Target = Message[FRAME_DEST_DEVICE_ID_INDEX];
    unsigned char Command = Message[FRAME_COMMAND_INDEX];
    char *Data = &Message[FRAME_DATA_INDEX];
    
 //   printf("MasterMsgReceived %d \n",Command);
    
    if(Target == ID_ETHERNET_VIRTUAL)
    {
        switch(Command)
        {
            case  ETH_NETWK_DEVICE_INFO_REQUEST:
            {
                char Data[2];
                Data[0] = ID_SPRINKLER_DEVICE;
                Data[1] = MY_DEVICE_ADDRESS; //Address
                SendFrame(ID_MASTER,MASTER_ADDRESS,ID_ETHERNET_VIRTUAL, ETH_NETWK_DEVICE_INFO_RESPONSE, Data,2,0);
                printf("Rx Device info request\n");
//                int FrameSize = -1;
//                unsigned char *FramePtr = ProtocolGetFrame(ID_MASTER,MASTER_ADDRESS,ID_ETHERNET_VIRTUAL, ETH_NETWK_DEVICE_INFO_RESPONSE, Data,2,0, &FrameSize);
//                
//                if(FrameSize > 0)
//                {
//                    TCPPutArray(MySocket,FramePtr,FrameSize);
//                }
                
                break;
            }
            case ETH_NETWK_CONNECTION_REFUSED:
            {
                printf("Connection to server refused\n");
                break;
            }
            case ETH_NETWK_SET_DEVICE_INFO_ACK:
            {
                //Connected!
                mConnectionState = MASTER_STATE_CONNECTED;
                TimerStart(MASTER_CONNECTION_TIMER,MASTER_RECONNECTION_TIMEOUT);
                printf("Connected to server\n");
                break;
            }
            case ETH_NETWK_DEVICE_INFO_RESPONSE:
            default:
            {
                //error...                                                     
                break;
            }
        }
        
    }
    else if(Target == ID_SPRINKLER_DEVICE)
    {
        switch(Command)
        {
            case SPRINKLER_DEVICE_ACK:
            {
                break;
            }
            case SPRINKLER_DEVICE_STATUS_REQUEST:
            {
                unsigned char data[6];
                data[0] = (unsigned char)GetValveState();
                GetCurrentFlowBytes(&data[1]);
                data[3] = 0;
                data[4] = 0;
                data[5] = 0;
                SendFrame(ID_MASTER,MASTER_ADDRESS,ID_SPRINKLER_DEVICE, SPRINKLER_DEVICE_STATUS_RESPONSE, data,6,0);
              //  printf("Status sent\n");
                break;
            }
            case SPRINKLER_DEVICE_SET_SPRINKLER_STATE_REQUEST:
            {
                unsigned char *MsgData;
                char data;
                
                MsgData = ProtocolMsgDataPtr();
                if(*MsgData == 1)
                {
                    SetValve(VALVE_ON);
                    data = 1;
                }
                else if(*MsgData == 1)
                {
                    SetValve(VALVE_OFF);
                    data = 1;
                }
                else
                {
                    data = 0;
                }
                
                SendFrame(ID_MASTER,MASTER_ADDRESS,ID_SPRINKLER_DEVICE, SPRINKLER_DEVICE_SET_SPRINKLER_STATE_ACK,&data,1,0);
                break; 
            }
            case SPRINKLER_DEVICE_GET_SPRINKLER_STATE_REQUEST:
            {
                unsigned char data;
                data = (unsigned char)GetValveState();
                SendFrame(ID_MASTER,MASTER_ADDRESS,ID_SPRINKLER_DEVICE, SPRINKLER_DEVICE_GET_SPRINKLER_STATE_RESPONSE,&data,1,0);
                break;
            }
            case SPRINKLER_DEVICE_GET_WATER_FLOW_REQUEST:
            {
                unsigned char data[2];
                GetCurrentFlowBytes(data);
                SendFrame(ID_MASTER,MASTER_ADDRESS,ID_SPRINKLER_DEVICE, SPRINKLER_DEVICE_GET_WATER_FLOW_RESPONSE,data,2,0);
                break;
            }
            case SPRINKLER_DEVICE_GET_MOISTURE_REQUEST:
            {
               break; 
            }
            case SPRINKLER_DEVICE_SET_PROGRAM_REQUEST:
            {
                break;
            }
            case SPRINKLER_DEVICE_GET_PROGRAM_REQUEST:
            {
                break;
            }
            case SPRINKLER_DEVICE_SET_PARAMETERS_REQUEST:
            {
               break; 
            }
            case SPRINKLER_DEVICE_GET_PARAMETERS_REQUEST:
            {
                break;
            }
           
            case SPRINKLER_DEVICE_STATUS_RESPONSE:
            case SPRINKLER_DEVICE_SET_SPRINKLER_STATE_ACK:
            case SPRINKLER_DEVICE_GET_SPRINKLER_STATE_RESPONSE:
            case SPRINKLER_DEVICE_GET_WATER_FLOW_RESPONSE:
            case SPRINKLER_DEVICE_GET_MOISTURE_RESPONSE:
            case SPRINKLER_DEVICE_SET_PROGRAM_ACK:
            case SPRINKLER_DEVICE_GET_PROGRAM_RESPONSE:
            case SPRINKLER_DEVICE_SET_PARAMETERS_ACK:
            case SPRINKLER_DEVICE_GET_PARAMETERS_RESPONSE:
            default:
            {
                //error
                break;
            }
        }
    }
    else
    {
        //Ignore..???
    }
}

bool SendFrame(unsigned char DestDevice,unsigned char DestAddress, unsigned char SenderDevice, unsigned char Cmd, unsigned char *Data,unsigned int Size,unsigned char Flags)
{
    
    int FrameSize = -1;
    unsigned char *FramePtr = ProtocolGetFrame(DestDevice,DestAddress,SenderDevice, Cmd, Data,Size,Flags,&FrameSize);
    
    if(FrameSize > 0)
    {
#ifdef USE_WINC1500 
#else
        TCPPutArray(MySocket,FramePtr,FrameSize);
#endif
  
    }
    else
    {
        return false;
    }
    
    
    return true;
}