#pragma once

#include <array>
#include <vector>
#include <string>
#include <functional>

#include <winsock2.h>
#include <ws2tcpip.h>

#include "Run.h"
#include "Runtask.h"
#include "CheckSwitch.h"
#include "structure.h"
#include "EMS.h"
#include "SemiE10RS.h"
#include "CurrentMsTime.h"
#include "Thread.h"
#include "ConcurrentQueue.h"
#include "MsgDecode.h"

#include "DllDefines.h"

#include "MotorPositionParser.h"
#include "MotorSpeedParser.h"

#include "MaintStructs.h"

#define STRING_RELAY_SET_GEN_MSG   _T("POSTMSGREPLY")
#define RELAY_SET_GEN_MSG_NUM_ARFG 2

#define STRING_MSG_OUTPUT_TRIGGER _T("OUTPUTTRIGGER")

#define STRING_MSG_WAFERUPDATE _T("WAFERUPDATE")

#define STRING_MSG_WAFERSETUP_DIEMOV _T("WAFERDIEMOVE")

#define STRING_REPLY_MAINTENANCEMODE_JOBDONE _T("MAINTENANCEMODE_JOBDONE,") // add comma (reply)

#define NUM_PARAM_OUTPUT_TRIGGER 4

// command strings list
#define CMD_START     _T("START")
#define CMD_STOP      _T("STOP")
#define CMD_RESET     _T("RESET")
#define CMD_RESTART   _T("RESTART")
#define CMD_PURGE     _T("PURGE")
#define CMD_INITPARAM _T("INITPARAMETERS")
#define CMD_OPENLOT   _T("OPENLOT")
#define CMD_CLOSELOT  _T("CLOSELOT")
#define CMD_JOG       _T("JOG")
#define CMD_MOTOR     _T("MOTOR")

// close app
#define CMD_CLOSEAPP ("CLOSEAPP")

#define CMD_COM _T("COM")
#define CMD_TCP _T("TCP")

// COM command Param list
#define CMD_COM_OPEN  _T("OPEN")
#define CMD_COM_SEND  _T("SEND")
#define CMD_COM_CLOSE _T("CLOSE")

// TCP command Param list
#define CMD_TCP_CONNECT    _T("CONNECT")
#define CMD_TCP_DISCONNECT _T("DISCONNECT")
#define CMD_TCP_SEND       _T("SEND")

enum COM_PARAMS
{
    COM_CMD_PARAM,
    COM_PORT_PARAM,
    COM_BAUD_PARAM,
    COM_BITS_PARAM,
    COM_PARITY_PARAM,
    COM_STOPBIT_PARAM,
    COM_FLOWCTRL_PARAM,
    COM_MSG_PARAM,
    MAX_COM_PARAMS,

};

enum TCP_PARAMS
{
    TCP_CMD_PARAM,
    TCP_IPADDRESS_PARAM,
    TCP_PORT_PARAM,
    TCP_MSG_PARAM,
    MAX_TCP_PARAMS,

};

// command Param list
#define CMD_PARAM_MTR_HOME _T("HOME")
#define CMD_PARAM_MTR_ON   _T("ON")
#define CMD_PARAM_MTR_OFF  _T("OFF")
#define CMD_PARAM_MTR_STOP _T("STOP")
#define CMD_PARAM_MTR_MOVE _T("MOVE")

// command Param number_of
#define NUM_PARAM_MOTOR_NON_MOV 4 // non move (but include homing)
#define NUM_PARAM_MOTOR_ACT_MOV 7 // actual move

#define MTR_CMD_PARAM_NUM            0
#define MOV_SEQENCE_PARAM_NUM        1
#define MOV_MODULE_PARAM_NUM         2
#define MOV_MOTOR_PARAM_NUM          3
#define MOV_MOTOR_POS_PARAM_NUM      4
#define MOV_MOTOR_DOUB_POS_PARAM_NUM 5
#define MOV_SPEED_MODE_PARAM_NUM     6

// string messsage
#define STRING_MSG_MAINTENANCE           _T("MAINTENANCEMODE")
#define STRING_MSG_MAINTENANCEMODE_RESET _T("MAINTENANCEMODE_RESET")
#define STRING_MSG_SYSWARN               _T("SET_SYSTEM_WARNING")
//
#define STRING_MSG_TASKMODE       _T("TASKMODE")
#define STRING_MSG_TASKMODE_RESET _T("TASKMODE_RESET")

#define STRING_MSG_POSTWINMSG ("POSTWINMSG") // format "POSTWINMSG:1000,1,1" or "POSTWINMSG:winMsg,wp,lp"
#define NUM_PARAM_POSTWINMSG  3

#define DEFAULT_MSG_PORT "7468"

enum MACHINE_MSG_TYPE
{
    STRING_RC = 1,
    COMMAND_RC,
    JAM_RC,
    WARNING_RC,
    WINMSG_RC
};

// OPE machine status
enum OPE_MACHINE_STATUS
{
    OPE_APPLICATION_START,
    OPE_IDLE,
    OPE_LOT_OPEN,
    OPE_LOT_CLOSE,
    OPE_MC_START,
    OPE_MC_AUTO_STOP,
    OPE_MC_MANUAL_STOP,
    OPE_MC_JAM_STOP,
    OPE_MC_EMERGENCY_STOP,
    OPE_MC_JAM,
    OPE_MC_JAM_RESET,
    OPE_MC_STOP_DUE_TO_WARNING,
    OPE_NO_MATERIAL_MODE,
    OPE_PRODUCTION_MODE,
    OPE_SCHEDULED_ACTIVITY_MODE,
    OPE_ENGINEERING_MODE,
};

// OPE machine stop mode
enum MC_STOP_MODE
{
    MC_STOP_MODE_AUTO,
    MC_STOP_MODE_MANUAL,
    MC_STOP_MODE_JAM,
};


enum TowerLightState
{
    TLIGHT_OFF_ = 0,
    TLIGHT_ON_,
    TLIGHT_ONOFF_,
    MAX_LIGHT_MAX_STATE
};

const std::array<std::string, MAX_LIGHT_MAX_STATE> TLightState{
    "Off",
    "On",
    "OnOff"
};

class MCCTRDLLCLASS CRunCtrl : public CRunTask
{
public:
    CRunCtrl(const std::vector<std::unique_ptr<CRun>>& pRuns, const std::vector<int>& sequenceModuleNo);
    ~CRunCtrl();

protected:
    //
    void strHandler(const std::string& strMsg);
    void cmdHandler(const std::string& strMsg);
    void jamHandler(const std::string& strMsg);
    void wrnHandler(const std::string& strMsg);

public:
    // list of available callback feature
    enum eFN_DELEGATE_CALLBACK
    {
        //
        eFN_STR_DELEGATE,
        eFN_CMD_DELEGATE,
        eFN_JAM_DELEGATE,
        eFN_WRN_DELEGATE,
        MAX_DELEGATE_CALLBACK_FN,
    };

    enum eFN_CALLBACK
    {
        //
        eFN_BEFORE_INITPARAMS,
        eFN_AFTER_INITPARAMS,
        // to facilitate control report summary for ui to decode
        eFN_AFTER_CRUN_EOL_COMPLETE,
        MAX_CALLBACK_FN,
    };

    // for implementation of application call
    void RegCallbackFn(eFN_CALLBACK eFn, std::function<void(void)> fn);

    void RegDelegateCallbackFn(eFN_DELEGATE_CALLBACK eFn, std::function<void(const std::string&)> fn);

    // method to query if lot is opened
    bool IsLotOpened();

    // method to informed runctrl that lot is opened and ready for run and
    // it is used only during recovery when application restarted during processing
    // of a lot.
    // During normal operation, this method is not used.
    void LotOpened();

    bool IsMaintenanceOperationCompleted(int nModuleNo);
    void StopMaintenanceOperation(int nModuleNo);
    void StartMaintenanceOperation(int nModuleNo);
    void UpdateEMSUnitCount();
    void SetEMSOutput(int nNo, COutput* pOutput);
    void SetEMSInput(int nNo, CInput* pInput);
    bool CanMachineRun();
    void InformAllRunCurtainSensorActivated();
    void DisableJogMode();
    void EnableJogMode();
    bool SetOutputState(int nOutput, bool bState);
    bool IsHardwareSafetyBypass();
    bool IsStopButtonActivated(void);
    bool IsDoorOpen();
    void SetSafetySwitch(int nSwitch, bool bSafety);

    void BypassDoor(bool bState);
    void BypassCurtain(bool bState);
    void SetSystemOutput(int nOutput, COutput* pOutput);
    bool IsEngineeringBypass();
    bool IsCurtainBypass();
    bool IsDoorBypass();
    void SetSystemInput(int nSwitch, CInput* pInput);
    void ResetPowerUpComplete(void);
    void SetModuleWarning(bool bState);
    void SetSystemWarning(bool bState);
    void SetIndicator(int nIndicator, COutput* output);
    void GetLightStatus(std::vector<int>& vecLight);
    void InitParameters(void);

    void InitMotorPosition();
    void InitMotorSpeed();

    void InitRunRecipeInfo(const void* runtimeRecipeInfo);
    void InitRunPackageInfo(const void* runtimePackageInfo);

    const stRuntimeMotorPosition& GetMotorPosition() { return m_stMotorPosition; }
    const stRuntimeMotorSpeed&    GetMotorSpeed() { return m_stMotorSpeed; }

    // to implement by application
    virtual void InitRecipeInfo()  = 0;
    virtual void InitPackageInfo() = 0;

    void CloseLot(void);
    void EmStopRelease(void);
    // Operations
    int Start();

    // added parameter to indicate if the stop operation is Manual or Auto Stop
    void Stop(bool bAuto = true);

    void Reset();
    void Restart();
    void EmStop();

    void SetTaskMode();
    void ResetTaskMode();
    bool IsTaskMode();

    //  GUI will call this function to set all sequence to Maintenance Mode
    void SetMaintenanceMode();

    //  GUI will call this function to clear all sequence Maintenance Mode
    void ResetMaintenanceMode();

    //  GUI will call this determine in  Maintenance Mode
    bool IsInMaintenanceMode();

    //  Gui will call this function to home motor in Maintenance Mode
    void MaintenanceHomeMotor(int iRunSeqNo, int iMaintModuleNo, int iMotor);

    //  Gui will call this function to Move motor in Maintenance Mode
    void MaintenanceMoveMotor(int iRunSeqNo, int iMaintModuleNo, int iMotor, int iPos,
        double dPos, int iSpeed);

    //  GUI will call this function to Stop motor in Maintenance Mode
    void MaintenanceStopMotor(int iRunSeqNo, int iMaintModuleNo, int iMotor);

    //  GUI will call this function to on/off output in Maintenance Mode
    void MaintenanceOutput(int iRunSeqNo, int iMaintModuleNo, int iOutputNo, bool bOn);

    //  GUI will call this function to turn on/off motor in  Maintenance Mode
    void MaintenanceMotorOnOff(int iRunSeqNo, int iMaintModuleNo, int iMtrNo, bool bOn);

    void StopAllMotor();

    // Purging

    // Threads
    UINT RunThread();

    // Utilities
    int  GetMcState();
    bool IsModified();
    void DisplayMsg(CDC* pDC, std::string& msg, int xOff, int yOff, bool debug = false, bool debug_jam = false);

    bool IsAllPowerUp(void);

    //  open lot
    void OpenLot();

    //  get all SemiE10 timing
    StSemiE10 GetCurrentTimeInfo();
    void      SetCurrentTimeInfo();
    StSemiE10 m_stSemiE10;
    //  Get Semi Timing Time
    long double GetSemiE10Time(int iEvt);

    //  get total uptime and down equipment state
    long double GetTotalTime();

    //  get non scheduled time
    long double GetNonScheduledTime();

    //  get operations time
    long double GetOperationsTime();

    //  get uptime
    long double GetUptime();

    //  get Downtime
    long double GetDowntime();

    //  get engineering time
    long double GetEngineeringTime();

    //  get manufacturing time
    long double GetManufacturingTime();

    //  get productive time
    long double GetProductiveTime();

    //  get standby time
    long double GetStandbyTime();

    //  get unscheduled downtime
    long double GetUnscheduledDowntime();

    //  get scheduled downtime
    long double GetScheduledDowntime();

    //  Get Assist time in mins
    long double GetAssistTime();

    //  get failure time in mins
    long double GetFailureTime();

    //  get Mean Time Between Assist
    long double GetMTBA();

    //  get Mean Time between Failure
    long double GetMTBF();

    //  get Mean Time To Repair
    long double GetMTTR();

    //  get Mean Time Between Interrupt
    long double GetMTBI();

    //  get Units Per Hour
    long GetUPH();

    //  get jam count
    long GetJamCnt();

    //  get assist count
    long GetAssistCnt();

    //  get failure count
    long GetFailureCnt();

    //  save lot info to database
    void SaveLotInfo(LPCTSTR lpLotNo, LPCTSTR lpCurTime);

    //  get Lot record semie10 timing
    StSemiE10 GetLotRecord(const std::string& csLotNo, const std::string& csLotStartTime);

    //  Delete lot record
    void DeleteLotRecord(std::string csLotNumber, double dStartDateTime);

    //  Get SemiE10 table name
    std::string GetSemiE10TableName();

    //  get all equipment substate field name
    std::vector<std::string> GetAllSemiE10FieldName();

    //  Start all equipment state. Possible to start all equipment state?
    void StartAllEquipState();

    //  Stop all equipment state
    void StopAllEquipState();

    //  Reset all equipment state
    void ResetAllEquipState();

    //  Get jam start date time
    COleDateTime GetJamStartTime();

    //  Get jam End date time
    COleDateTime GetJamEndTime();

    //  Get current Date time
    COleDateTime GetCurrentTime();

    //  Get current Window;
    HWND GetMainGuiWnd();

    //  send com data to all run modules in maintenance mode
    void MaintenanceSendCom(LPCTSTR lpcComPort, int iBaudRate, int iDataBits,
        LPCTSTR lpcParity, float fStopBits, LPCTSTR lpcFlowCtrl, LPCTSTR lpcSendMsg);

    //  send open com to all run modules in maintenance mode
    void MaintenanceOpenCom(LPCTSTR lpcComPort, int iBaudRate, int iDataBits,
        LPCTSTR lpcParity, float fStopBits, LPCTSTR lpcFlowCtrl);

    //  send close com to all run modules in maintenance mode
    void MaintenanceCloseCom(LPCTSTR lpcComPort, int iBaudRate, int iDataBits,
        LPCTSTR lpcParity, float fStopBits, LPCTSTR lpcFlowCtrl);

    //  send packet in maintenance mode
    void MaintenanceSendPacket(LPCTSTR IpAddress, int iPortNo, LPCTSTR lpcSendMsg);

    //  connect port in maintenance mode
    void MaintenanceConnectPort(LPCTSTR IpAddress, int iPortNo);

    //  connect port in maintenance mode
    void MaintenanceDisconnectPort(LPCTSTR IpAddress, int iPortNo);

    // setup SeqRun Module Mapping
    int GetSequenceModuleNo(int nModuleIndex);

    //  find Gui Window Handler
    void FindGuiWindow(CWnd* pMainWnd = nullptr);

    //  Gui Separator
    void InitGuiSeparator(void);

    //  Pass General Message to one or all modules(iModuleNo = -1)
    void SetGenMsg(int iModuleNo, int iMsg);

    SOCKET GetClientSock();

    //
    bool SendMachineMsgGrp(int msgType, const std::string& strMsg);

    bool PostRelayedMsg(UINT wp, UINT lp, UINT winMsg);
    bool PostAlarmMsg(UINT wp, UINT lp, MACHINE_MSG_TYPE alarmMsgType);
    bool PostMaintenanceClearMsg(UINT wp, UINT lp);
    // Attributes
    int m_mcState;

    bool m_bDiagnose{ false };

    bool* m_pbMaintenanceMode{ nullptr };

    enum
    {
        ALL_MODULES = -1,
    };

    // change this object from private to public
    CSemiE10RS m_SemiE10;

    CConcurrentQueue<std::shared_ptr<MC_DATA>> m_strMcMsgQueue;

    // implement Warning Message with Buzzer disable feature, END
    // as well as Authroization Level to clear Jam

    //  Set to True to Disable CRunCtrl Door Control Seqence when Machine state is not MC_RUNNING Or MC_INITIALIZING
    void ByPassDoorControl(bool bByPassDoorCtrl);

    //  return true when acknowledged that Door Control has been by passed
    bool IsDoorControlByPassed();

    /// Set whether run modules init parameters concurrently
    void SetConcurrentIniPara(bool bConcurrentIniPara);

    /// returns true if run modules init parameters concurrently else returns false
    bool GetConcurrentIniPara();

    void OnDestroy();

    void ReadParameters();

    void AllModuleReadParam();

    void ResetRunPuComplete();
    void CheckResetRunPuComplete();

    //  send com data to all run modules in maintenance mode
    void OnMaintenanceSendCom(LPCTSTR lpcComPort, int iBaudRate, int iDataBits, LPCTSTR lpcParity, float fStopBits,
        LPCTSTR lpcFlowCtrl, LPCTSTR lpcSendMsg);

    //  send open com to all run modules in maintenance mode
    void OnMaintenanceOpenCom(LPCTSTR lpcComPort, int iBaudRate, int iDataBits,
        LPCTSTR lpcParity, float fStopBits, LPCTSTR lpcFlowCtrl);

    //  send close com to all run modules in maintenance mode
    void OnMaintenanceCloseCom(LPCTSTR lpcComPort, int iBaudRate, int iDataBits,
        LPCTSTR lpcParity, float fStopBits, LPCTSTR lpcFlowCtrl);

    //  send packet in maintenance mode
    void OnMaintenanceSendPacket(LPCTSTR IpAddress, int iPortNo, LPCTSTR lpcSendMsg);

    //  connect port in maintenance mode
    void OnMaintenanceConnectPort(LPCTSTR IpAddress, int iPortNo);

    //  disconnect port in maintenance mode
    void OnMaintenanceDisconnectPort(LPCTSTR IpAddress, int iPortNo);

    void SetCustomizedTowerLight(int customLightId);
    void ClearCustomizedTowerLight();
    bool GetCustomizedTowerLight();

private:
    void OnPowerUpCompleted();
    void DoorControl();
    enum
    {
        ESTOP_MC,
        STOP_MC,
        ESTOP_RELEASE_MC,
        START_MC,
        RESET_MC,
        RESTART_MC,
        MAX_MC_CTRL,
    };

    void SetLightStatus(void);
    void InitLocalParameters(void);
    void InitTowerlightConfig();
    bool IsCloseLotComplete(void);
    bool IsWarning(void);
    // Operations
    void        JamResetAllRun(void);
    void        RestartAllRun();
    void        SuspendAllRun();
    bool        ResumeAllRun();
    inline void SetMcState(int state);
    bool        IsJam();

    // Run Time Operations
    void StartRunTime();
    void StopRunTime(int state);

    //
    void OnMcStopped();

    // Machine State
    bool CheckMachineState();
    void SaveMachineState();

    void TaskProcessRxMsgFn();
    void TaskTcpIPServerFn();

    std::string ConnectionString(const std::string& strDbName);

    void EndAllRun(void);

    //  check current mode is to set or reset maintenance mode
    void CheckMaintMode();

    //  start jam time
    void StartJamTime();

    //  update time for euipment time calculation
    void UpdateTime();

    //  Emergency stop release control
    void EmStopReleaseCtrl(void);

    //  start machine control
    int StartCtrl();

    //  stop machine control
    // void StopCtrl();

    // added parameter to indicate if the stop operation is Manual or Auto Stop
    void StopCtrl(int nStopCode);

    //  jam reset machine control
    void ResetCtrl();

    //  restart machine control
    void RestartCtrl();

    //  Emstop machine control
    void EmStopCtrl();

    //  check current machine control
    void CheckMcCtrl();

    //  reset all machine contrl flag
    void ResetMcCtrlFlag();

    //  check current machine no material
    void CheckMcNoMaterial();

    //  post jam reset message to gui
    void PostJamResetToGui();

    //  check whether to post clear no material warning
    void CheckClearNoMaterialWarn();

    //  inform all run modules close lot has completed
    void OnCloseLotCompleted();

    /// Inform all Run Modules EStop Pressed
    void InformAllRunEStopPressed();

    // method to inform UI of OPE Status
    bool PostOPESignal(unsigned int uintSignal);

    bool PostOPEStopCode(int nStopCode);

    void CheckFindGuiWindowRun();

    void CheckOpenLot();
    void SetOpenLot();

    bool CheckProcessMaintCmd();

    void ResetAllMaintCmd();

    // private : only accessible by CRunCtrl
    void CallbackFn(eFN_CALLBACK eFn);

    void DelegateCallbackFn(eFN_DELEGATE_CALLBACK eFn, const std::string& strMsg);

    //  Attributes

    CMutex m_maintMutex;  // mutex to synchronised set or reset maintenance mode
    CMutex m_mcCtrlMutex; // mutex to synchronised machine control

    // run modules
    const std::vector<std::unique_ptr<CRun>>& m_pRuns;

    bool m_bCloseLot{ false };

    std::array<LIGHT_CONFIG, NUM_MC_STATE>     m_lightConfig;
    std::array<LIGHT_CONFIG, CUSTOM_LIGHT_MAX> m_customLightCfg;

    LIGHT_CONFIG m_currentLightStatus;
    bool         m_bBlink{ false };

    COutput* m_copLightRed{ nullptr };
    COutput* m_copLightAmber{ nullptr };
    COutput* m_copLightGreen{ nullptr };
    COutput* m_copBuzzer{ nullptr };

    COutput* m_copStartIndicator{ nullptr };
    COutput* m_copStopIndicator{ nullptr };
    COutput* m_copResetIndicator{ nullptr };

    bool m_bSystemWarning{ false };
    bool m_bModuleWarning{ false };

    bool m_bResetMaintMode{ false };    // flag to detemine reset maintenance mode
    bool m_bMaintMode{ false };         // flag to determine set to maintenance mode
    bool m_bCloseLotCompleted{ false }; // flag to determine close lot completed
    bool m_bInMaintenanceMode{ false }; // flag to indicate at least one module is in maintenance

    //
    bool m_bTaskMode{ false };      // flag to set Task mode
    bool m_bResetTaskMode{ false }; // flag to reset Task mode
    bool m_bInTaskMode{ false };

    std::array<bool, MAX_MC_CTRL> m_bMcCtrl; // flag to determine machine control

    //  flag to determine whether no material warning has been post to GUI before
    //  true  = post no material warning before
    //  false = have not post no material warning
    bool m_bPostNoMaterial{ false };

    COleDateTime m_odtCurrentTime;  // current time
    COleDateTime m_odtJamStartTime; // jam Start time
    COleDateTime m_odtJamEndTime;   // jam end time

    HWND m_hwndMainApp{ nullptr }; // gui window handler

    CCheckSwitch m_runCheckSwitch;

    CEMS m_runEMS;

    // indicate if in Jog Mode for stepping purpose
    bool m_bJogMode{ false };

    // flag to disable buzzer during warning in Machine Stop Mode
    bool m_bBuzzerOff{ false };

    // flag to indicate if it's a manual/auto stop
    bool m_bAutoStopRequested{ false };

    // flag to indicate if a lot is open and machine is allowed to operate
    bool m_bLotOpened{ false };

    // true = By Pass Door Control when  machine state is not initialising or not running
    bool m_bByPassDoorControl{ false };

    //  true = runctrl acknowledged control of door lock has been by passed
    bool m_bDoorControlByPassed{ false };

    /// true == call run modules initparameters concurrently else call run modules initparameters sequently as in VC6 MITLIB
    bool m_bConcurrentIniPara{ false };

    bool m_bAllRunsRdy{ false };
    bool m_bInformUiRdy{ false };

    bool m_bFindWindow{ false };

    bool m_bIniParameters{ false };

    bool m_bResetRunPuComplete{ false };

    //  Maintenance mode variables
    stMaintParameters m_stMaintHmParams;
    stMaintParameters m_stMaintMvParams;
    stMaintParameters m_stMaintStopParams;
    stMaintParameters m_stMaintOutputParams;
    stMaintParameters m_stMaintMtrOnOffParams;

    double m_dCurrentTime;  // current time
    double m_dJamStartTime; // jam Start time
    double m_dJamEndTime;   // jam end time

    enum
    {
        NO_CMD = -1,
        SEND_COM,
        OPEN_COM,
        CLOSE_COM,
        SEND_PACKET,
        CONNECT_PORT,
        DISCONNECT_PORT,
    };

    int   m_iComCmd{ NO_CMD };
    char  m_lpcComPort[10];
    int   m_iBaudRate;
    int   m_iDataBits;
    char  m_lpcParity[10];
    float m_fStopBits;
    char  m_lpcFlowCtrl[10];
    char  m_lpcSendMsg[100];

    char m_IpAddress[100];
    int  m_iPortNo;

    CEvt m_evtIpControllerStartUpdate{ "INPUT CONTROLLER START UPDATE" };
    CEvt m_evtOpControllerStartUpdate{ "OUTPUT CONTROLLER START UPDATE" };
    CEvt m_evtMotionControllerStartUpdate{ "MOTION CONTROLLER START UPDATE" };

    // To inform GUI the InitParameters is completed
    CEvt m_evtInitParameterCompleted{ "INIT PARAMETERS COMPLETED" };

    bool m_bOnOpenLot{ false };
    bool m_bIsTcpEnabled{ false };

    SOCKET m_TcpListenSocket{ INVALID_SOCKET };
    SOCKET m_TcpClientSocket{ INVALID_SOCKET };

    std::unique_ptr<CThread> m_thdTcpIPServer;
    std::unique_ptr<CThread> m_thdProcessRxMsg;

    bool m_bIsCustomizedTowerLight{ false };
    int  m_nCurCustomLightId{ -1 };

    // add capability - in order to share with ui code using shm design, unable to use vector
    // TODO: to review shm if needed
    const std::vector<int>& m_vecSequenceModuleNo;

    // to store list of callback
    std::array<std::function<void(void)>, MAX_CALLBACK_FN> m_fnCallback;

    std::array<std::function<void(const std::string&)>, MAX_DELEGATE_CALLBACK_FN> m_fnDelegateCallback;

    //
    stRuntimeMotorPosition m_stMotorPosition;
    stRuntimeMotorSpeed    m_stMotorSpeed;
};
