// MotionControllerBase.h: interface for the CMotionControllerBase class.
//
//////////////////////////////////////////////////////////////////////
#pragma once

#include "Motor.h"
#include "hardwareini.h"

#ifdef BUILD_IODLL
#define IODLLCLASS __declspec(dllexport)
#else
#define IODLLCLASS __declspec(dllimport)
#endif

class IODLLCLASS CMotionControllerBase : public CCard
{
    friend UINT MotionThreadFn(LPVOID pParam);

protected:
    int         m_CardType{ -1 };
    int         m_nNoOfCard{ 0 };
    int         m_index{ 0 };
    std::string m_szCardName{ "" };

public:
    CMotionControllerBase(int index, const std::string& pMutexName);
    virtual ~CMotionControllerBase();

    void         SetCardInfo(int nCardType, const std::string& cardName);
    int          GetCardType() const;
    std::string  GetCardName() const;

    virtual BOOL Init(int& nNoOfMtr) = 0;
    virtual void Close();

    // get the IOs status of the motor
    virtual unsigned short GetMotionIOStatus(const CMtrProfile& mtrProfile);

    //  get Motion status of motor
    virtual int GetMotionStatus(const CMtrProfile& mtrProfile);

    //  get Motor Pos value
    virtual double GetMtrPos(const CMtrProfile& mtrProfile);

    //  get position error value
    virtual double GetPosErr(const CMtrProfile& mtrProfile);

    //  check if motor is at home sensor position
    virtual BOOL IsHomed(const CMtrProfile& mtrProfile);

    // check motor in position signal
    virtual BOOL IsInPosition(const CMtrProfile& mtrProfile);

    // check if motor negative/ccw limit is triggered
    virtual BOOL IsNegLimHit(const CMtrProfile& mtrProfile);

    // check if motor positive/cw limit hit
    virtual BOOL IsPosLimHit(const CMtrProfile& mtrProfile);

    //  check if motor driver alarm
    virtual BOOL IsMotorAlarm(const CMtrProfile& mtrProfile);

    //  check if motor is ready
    virtual BOOL IsMotorReady(const CMtrProfile& mtrProfile);

    //  check if motor is on
    virtual BOOL IsMtrOn(const CMtrProfile& mtrProfile);

    BOOL TestIOStatus(const CMtrProfile& mtrProfile, unsigned short bitmask);

    struct signal_mask
    {
        // home signal bit mask
        unsigned short m_usHomeBitMask;

        // index signal bit mask
        unsigned short m_usIndexBitMask;

        // CW Limit signal bit mask
        unsigned short m_usCWLimitBitMask;

        // CCW Limit signal bit mask
        unsigned short m_usCCWLimitBitMask;

        // Motor Ready signal bit mask
        unsigned short m_usReadyBitMask;

        // Motor On signal bit mask
        unsigned short m_usOnBitMask;

        // Alarm signal bit mask
        unsigned short m_usAlarmBitMask;

        // In Position signal bit mask
        unsigned short m_usInPositionBitMask;

        signal_mask()
        {
            m_usHomeBitMask       = 0;
            m_usIndexBitMask      = 0;
            m_usCWLimitBitMask    = 0;
            m_usCCWLimitBitMask   = 0;
            m_usReadyBitMask      = 0;
            m_usOnBitMask         = 0;
            m_usAlarmBitMask      = 0;
            m_usInPositionBitMask = 0;
        }
    } m_structSignalMask;

    void        RegisterMotor(const CMtrProfile& mtrProfile, CMotorBase* pMotor);
    void        UnRegisterMotor(const CMtrProfile& mtrProfile);
    CMotorBase* GetMotor(const CMtrProfile& mtrProfile);

protected:
    CMutex m_mutexMotion;

    CHardwareIni               m_iniHardware;
    std::map<int, CMotorBase*> m_motors;
};
