#ifndef CMOTORDRIVER_BASE_H
#define CMOTORDRIVER_BASE_H

#include "cmotordriver.h"
#include "logic_eap.h"
//#include "logic_io_define.h"
#include "export_motor_driver_impl.h"
class MOTOR_DRIVER_IMPL_EXPORT CMotorDriver_Base : public CMotorDriver
{
public:
    CMotorDriver_Base(const QString& name, int32_t id);
    int32_t absmove(int32_t motorid, float64_t fpos, bool_t bwaitfinished = true) override;
    int32_t relmove(int32_t motorid, float64_t fdis, bool_t bwaitfinished) override;
    int32_t freshpos(int32_t motorid) override;
    float64_t freshAPos(int32_t motorid) override;
    float64_t freshFPos(int32_t motorid) override;

    float64_t get_iodata_analog(int32_t cid, int32_t ioid, bool bfresh);

    virtual int32_t wait_move_finished_block(int32_t motorid, int iMS = 30000);
    virtual int32_t wait_prg_finished_block(int32_t bufferid);


    void setHomeStatus(int32_t motorid, bool bhasHomed) override;
    int32_t preparehome(int32_t motorid) override;
    int32_t home(int32_t motorid, bool_t bwait = false) override;
    int32_t afterhome(int32_t motorid) override;

    int32_t setio(int32_t cid, int32_t ioid, float64_t fdata) override;

    virtual int PEGMove_BuffGate(int32_t motorid, int32_t gateIoIdx, double dStartPos, double dEndPos, double* pegpos, int isize, bool bEnableLaser);
    virtual int LoadBufferGate(int32_t motorId, int32_t bufferIdx, int32_t gateIoIdx, double dStartPos, double dEndPos, bool bEnableLaser);
    virtual int MultiPointMove(int32_t motorid, double* pPoint, int iPointSize, BOOL bCyclic = TRUE, double* pVel = NULL);
public:
    /*!
     * @brief 限位检测.
     * 
     */
    std::function<void(int32_t motorId, double targetPos)> m_pfnLimitCheck = nullptr;
    /*!
     * @brief 是否可以移动检测.
     * 
     */
    std::function<void(int iMotorID, bool checklimit, int idirect, double dTargetPos, bool bIsHoming)> m_pfnMoveAvaliable = nullptr;
    /*!
     * @brief IO是否可以设置检测.
     * 
     */
    std::function<void(int32_t ioid, int32_t fdata)> m_pfnIOAvaliable = nullptr;
    /*!
     * @brief 准备回零前处理，用于处理其他轴到位置或安全检查.
     * 
     */
    std::function<void(int32_t motorId)> m_pfnPrepareHome = nullptr;
    /*!
     * @brief 回零后处理，用于回初始位置等.
     * 
     */
    std::function<void(int32_t motorId)> m_pfnAfterHome = nullptr;
    /*!
     * @brief 检查当前IO是否设置激光Gate为关光状态.
     * 
     * @retval true 关光状态
     * @retval false 非激光器的IO，或非关光状态
     */
    std::function<bool(int32_t ioid, int32_t idata)> m_pfnSetLaserOff = nullptr;
    /*!
     * @brief 轴运动过程中检查.
     * 
     * @details 检查为true时，立即停止运动，throw sExceptionInfo
     */
    std::function<bool(int32_t motorId, std::string& sExceptionInfo)> m_pfnMovingDetected = nullptr;

    /*!
     * @brief 主气压检测.
     * 
     * @datails 检查主气压，如果未检测到主气压，throw异常
     */
    std::function<void(void)> m_pfnMainPresureDetected = nullptr;


public:
    /*!
     * \brief set_cylinder
     * 设置气缸开并检查输入状态，检查iTimeOut ms
     * \param IOOutput
     * \param IOInput
     * \param bset
     * \param iTimeOut
     * \return
     */
    virtual int32_t set_cylinder(int32_t IOOutput, int32_t IOInput, bool_t bset = true, int iTimeOut = 0) override;
    int32_t check_cylinder(int32_t IOOutput, int32_t IOInput, bool bset = true, int iTimeOut = 0);

    virtual int cylindermove(int32_t IOOUTStart, int32_t IOINEnd, int32_t IOOutCtrl1,
                     int32_t IOOutCtrl2,
                     bool_t bCtrl1Set, bool_t bCtrl2Set, int32_t IOINAlm, int iTimeOut = 0) override;
    virtual int cylinderhome(int32_t IOOUTHome, int32_t IOINHome, int32_t IOINAlm, int iTimeOut = 0) override;

    //检查位置是否在限位上
    virtual void limit_checked(int32_t motorId, double targetPos, bool bRealMove = false);
};

#endif // CMOTORDRIVER_BASE_H
