// InputBase.h: interface for the CInputBase class.
//
//////////////////////////////////////////////////////////////////////
#pragma once

#include "HardwareIni.h"

class CInputSetting;

class CInputBase : public CCard, public CMyWait
{
public:
    CInputBase(const std::string& csMutexName, const CInputSetting& Setting);
    virtual ~CInputBase();

    // virtual method to query if input is OFF
    virtual BOOL IsOff();

    // virtual method to query if input is ON
    virtual BOOL IsOn();

    // virtual method to query Analog input voltage
    virtual BOOL GetVoltage(double& dVoltage, int nRange);

    // virtual method to set the last Analog Input Channel for HSL ONLY
    virtual BOOL SetLastAICh(int nLastChannel);

    // virtual method to set the Configuration of Analog Input for HSL ONLY
    virtual BOOL SetAIConfig(int nSignalRange);

    // virtual method to start read
    virtual BOOL StartRead();

    // virtual method to get voltage only
    virtual BOOL GetVoltageOnly(double& dVoltage, int nRange);

    // virtual method to stop read
    virtual BOOL StopRead();

    /***********************************************************************/
    /*********************currently for 9222 ONLY***************************/

    // virtual method to setup general counter
    virtual BOOL SetupCounter(int nMode);

    // virtual method to cater for auto reset counter using Org Signal
    virtual BOOL SetupCounter(int nMode, unsigned int LReg1_Val, unsigned int LReg2_Val);

    // virtual method to clear counter
    virtual BOOL ClearCounter();

    // virtual method to enable counter counting
    virtual BOOL EnableCounter();

    // virtual method to disable counter counting
    virtual BOOL DisableCounter();

    // virtual method read the counter
    virtual unsigned long ReadCounter();

    virtual int GetState() = 0;

    /********************************************/
    // method for input thread
    /********************************************/

    // method to query is input thread working
    BOOL IsThreadChecking();

    // method to reset input thread working flag
    void ResetThreadChecking();

    // method to turn on Thread Is Checking flag
    void ThreadChecking();

    // method to stop reset abort check flag
    void ResetAbortCheck();

    // method to stop input thread checking
    void AbortCheck();

    // method to query if the abort check flag is ON/OFF
    BOOL IsAbortCheck();

    // method to get input ON/OFF event
    HANDLE GetEvt(BOOL bState);

    void StartWait(BOOL bState, DWORD dwDebounce, DWORD dwTimeout);

    BOOL Wait(BOOL bState, DWORD dwDebounce, DWORD dwTimeout);

    CEvent m_evtCheck{ FALSE, TRUE, nullptr, nullptr };
    CEvent m_evtKillThread{ FALSE, TRUE, nullptr, nullptr };
    DWORD m_dwDebounce{ 0 };
    DWORD m_dwTimeout{ 0 };
    BOOL m_bWaitState{ FALSE };

    // input ON event when using thread to wait upon ON State
    CEvent m_evtOn{ FALSE, TRUE, nullptr, nullptr };

    // input OFF event when using thread to wait upon OFF State
    CEvent m_evtOff{ FALSE, TRUE, nullptr, nullptr };

    std::string GetName(void);

    enum
    {
        INPUT_UNKNOWN,
        INPUT_ON,
        INPUT_OFF,
    };

protected:
    CMutex m_mutexInput;

    // the input point name
    std::string m_strName;

    // the ON Logic
    BOOL m_bOnState;

    // the input point number
    int m_nPt;

    // the slave module number (for distributed control - HSL)
    int m_nSlaveID;

    // the input point number (for distributed control - HSL)
    int m_nPtrNo;

    // the input board type
    int m_nBoardType;

    // the input card number in the PC
    int m_nCardNo;

    // the input card ID
    int m_nCardID;

    CWinThread* m_pThread{ nullptr };
    BOOL m_bAbortCheck{ FALSE };
    BOOL m_bThreadChecking{ FALSE };

    // currently these 2 functions are for 9112 and 9222 cards
    bool IsDigitalInput(int nPt);

    bool IsAnalogInput(int nPt);
};
