
//---------------------------------------------------------------------------
#ifndef VMSCThreadH
#define VMSCThreadH
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Sockets.hpp>
#include "AppGlobalF.h"
#include "VmsPasigProtocolF.h"
#include "VMSDataTypeF.h"
#include "TVmsCtlrF.h"
#include "ITSLogF.h"
//---------------------------------------------------------------------------

//#define CLIENT_SND_BUF_SIZE             65536       /* message buffer size */
//#define CLIENT_SND_BUF_SIZE             111717     /* message buffer size */
#define CLIENT_SND_BUF_SIZE             200000     /* message buffer size */
#define CLIENT_RCV_BUF_SIZE             4096       /* max packet size */

#define CLIENT_CONNECT_RETRY_TIME       60          /* connect retry time */
#define CLIENT_CHANGE_TIME              5           /* change wait time */

// client thread
typedef struct client_thread_struct
{
	BYTE       Idx;                         /* information index */

	AnsiString IpAddress;                   /* IP주소 */
    int        Port;                        /* 포트번호 */
    int        TimeOut;                     /* 시간초과 */
    int        Addr;                        /* local id */
	AnsiString VmsId;        	            /* VMS ID */

    int        State;                       /* for the statemachine */


    TDateTime  reqStatusTimer;              /* timer for state check sending */
    int        pollingCycleTime;            /* 정보요청주기 */

    int        sendRetry;                   /* retry count */
    TDateTime  sendTimer;                   /* timer for command timeout check */

	AnsiString LocalCenterId;               /* 로컬 센터ID */
	AnsiString LocalDomainNm;               /* 로컬 도메인명칭 */
	AnsiString CenterId;                    /* 센터ID */
	AnsiString DomainNm;   		            /* 도메인명칭 */
	AnsiString UserName;                    /* 사용자명 */
	AnsiString UserPasswd;                  /* 사용자비밀번호 */

	int        MaxHeartbeatTime;     	    /* 최대허트비트지속시간 */
	int        DatagramSize;         	    /* 데이터그램 크기 */
} CLIENT_THREAD_STRUCT;


typedef enum en_client_machine_state
{
	/* common */
	CT_IDLE = 1,
	CT_LOGIN,
	CT_SECTION,
	CT_CLOSE,

    CT_REGIST,
    CT_REGIST_COMMAND,
    CT_REGIST_WAIT,
	/* sender */
	CT_LOCAL_COMMAND,
	CT_CLIENT_COMMAND,

	/* receiver */
	CT_LOGIN_WAIT,
    CT_FRED_WAIT,
	CT_LOCAL_WAIT,
	CT_CLIENT_WAIT
} EN_CLIENT_MACHINE_STATE;

enum
{
	SET_CLIENT_SUCC,
	SET_CLIENT_FAIL
};

/* 설정 정보 */
typedef struct tag_set_info_struct
{
	BYTE VmsId[INT_VMS_MAX_ID+1];		    /* VMS ID */
	BYTE CtlType;                       /* 제어유형 */
	union
    {
		struct
        {
			BYTE Result;					/* 제어결과 */
			BYTE OperId[INT_VMS_MAX_OPER_ID+1];	/* 제어운영자ID */
		} Control;

		struct
        {
			int SchMsgTime;                 /* 계획된 메시지 동작시간 */
			int ModuleTemp;                 /* 모듈전원 OFF 온도 */
			int FanTemp;                    /* Fan동작 기준온도 */
			int HeaterTemp;                 /* Heater동작 기준온도 */
			int ModuleFail;                 /* 모듈장애 판단율 */
			int RetryCount;                 /* 재시도 횟수 */
			int TimeOut;                    /* 최대응답대기시간 */
		} Para;
	} Data;
} TSET_INFO_STRUCT;


//---------------------------------------------------------------------------
class TVMSCThread : public TThread
{
private:
	TTcpClient *TcpClient;
    bool *ThreadActiveIndicator;

    TVmsCtlr    *FVmsObj;

	AnsiString m_strName;						/* thread name */

    int  m_RxDataLen;
    int  m_RxPktLen;
    int  m_RxState;
    int  m_RxLen;
    BYTE m_RxBuff[CLIENT_RCV_BUF_SIZE];	        /* receive data buffer */
    BYTE m_TxBuff[CLIENT_SND_BUF_SIZE];	        /* send data buffer */

    TDateTime m_rcvPacketTimer;                 /* timer for receiver */
    TDateTime m_WatchDogTimer;                  /* watchdog timer */

    CLIENT_THREAD_STRUCT FClient;              /* client thread */

    DWORD m_DataPacketNumber;                   /* DataPacket Number */
    DWORD m_SubscribeSerialNbr;                 /* Subscribe Serial Nbr */

	LOCAL_COMMAND       FLocalCmd;              //

    VMS_CONTROL_INFO    FCliCmd;                //클라이언트 제어 메지시

    ////////
	VMS_SERVER_CTL_INFO FSvrCtl;                /* local control */

	CLIENT_COMMAND      m_Req;                  /* client request */
	TSET_INFO_STRUCT    m_Set;					/* client set */
    //REQUEST_REGISTERED  m_Registered;           /* local command */
    ////////


    TVmsFormManager   *m_pVmsFormList;          /* VmsFormList */

	INT_VMS_STATE     *m_pState;                /* VMS 상태 정보 */

    TITSLog           *FLogFile;

    int                FErrLine;

    void __fastcall InitRx();
	void __fastcall ClientInitInfo(void);
	void __fastcall ClientTerminate(void);

	int __fastcall SaveStatusData(BYTE *pGS);

	int __fastcall RecvPacket(BYTE *ABuffer, int ALen);
	int __fastcall ProcessRecvPacket(BYTE *ABuffer, int ARcvLen);
	int __fastcall ResVmsStatus(BYTE *ABuffer, int ARcvLen);
	int __fastcall ResVmsModuleStatus(BYTE *ABuffer, int ARcvLen);
	int __fastcall ResVmsMsgDownload(BYTE *ABuffer, int ARcvLen);
	int __fastcall ResVmsLibDownload(BYTE *ABuffer, int ARcvLen);
	int __fastcall ResVmsSignboardPowerControl(BYTE *ABuffer, int ARcvLen);
	int __fastcall ResVmsInitialize(BYTE *ABuffer, int ARcvLen);

	int __fastcall SendPacket(BYTE *ACmdBuff, int AReqSendLen);
	int __fastcall ProcessSendPacket(BYTE AOpCode, COMMAND_ARGUMENT *AArg);
	int __fastcall MakeMsgDownload(BYTE *ABuff, COMMAND_ARGUMENT *AArg);
	int __fastcall MakeLibDownload(BYTE *ABuff, COMMAND_ARGUMENT *AArg);

	int __fastcall ClientStateMachine(void);
	int __fastcall ProcErrorState(bool flag, int result);
	int __fastcall SetClientState(int ACase);
	int __fastcall CheckLocalData(bool &ARequest);
	int __fastcall CheckClientData(bool &ARequest);

	int __fastcall SendDbThreadMessage(UINT Msg, int wParam, int lParam);
    int __fastcall SendDbThreadDataMessage(UINT Msg, void *pData, int iLen);
	void __fastcall ClientResponse(int error);

protected:
	void __fastcall Execute();
	void __fastcall TcpClientConnect(TObject *Sender);
	void __fastcall TcpClientCreateHandle(TObject *Sender);
	void __fastcall TcpClientDestroyHandle(TObject *Sender);
	void __fastcall TcpClientDisconnect(TObject *Sender);
	void __fastcall TcpClientError(TObject *Sender, int SocketError);
	void __fastcall TcpClientReceive(TObject *Sender, char *Buf, int &DataLen);
	void __fastcall TcpClientSend(TObject *Sender, char *Buf, int &DataLen);
    bool __fastcall SocketActivity(bool &AError);
    bool __fastcall SocketActivity();
    void __fastcall Close(void);

    int __fastcall SendSubRegister(int AObj);

    void __fastcall DebugState();
    bool __fastcall IsCommandTimeout();

    void __fastcall InfoPacket(BYTE *ABuff, int ALen, bool ASend, int AResult=0);

public:
	__fastcall TVMSCThread(bool CreateSuspended, int Tag, bool *ActiveIndicator);
	__fastcall ~TVMSCThread();

    IPC_LOG_MESSAGE FLogMsg;
    int LogData(char *ASndRcv, BYTE *AData, int ALen);
    int LogWrite(int ALogKind, char *AFmt, ...);
    int SysLogWrite(int ALogKind, char *AFmt, ...);

    bool FUserTerm;
    void ReqStatus();
};
//---------------------------------------------------------------------------
#endif
