#ifndef CMOTORDRIVER_ACS_H
#define CMOTORDRIVER_ACS_H
#include <WinSock2.h>
#include "ACSC.h"
#include "cmotordriver_base.h"

#define RESERVE_BUFF 30
#define MAX_BUFF 31
enum MoveStatus
{
    deceleration_buildup = 5,
    constantdeceleration = 6,
    deceleration_finishing = 7,
    kill_deceleration = 8,

};
class MOTOR_DRIVER_IMPL_EXPORT CMotorDriver_ACS : public CMotorDriver_Base
{
public:
    enum msg_id
    {
        MOTORDRIVER_PEG_MSG_ID = MAX_MOTORDRIVER_MSG_ID,
        MAX_MOTORDRIVER_PEG_MSG_ID,

    };
    CMotorDriver_ACS(const QString& name, int32_t id);
    ~CMotorDriver_ACS();

    //virtual void limit_checked(int32_t motorId, double targetPos, bool bRealMove=false);

private:
    HANDLE m_AcsHandle;
public:
    void SendCommand(const char* pCommand, char* pResponse);
    virtual int32_t init_driver() override;
    virtual int32_t exit_driver() override;
public:
    int32_t freshio(int32_t ioid, int32_t ioidx) override;
    int32_t freshio_multi(int32_t ioid, int32_t idxstart, int32_t idxend) override;
    int32_t setio(int32_t ioid, int32_t ioidx, float64_t fdata) override;

public:
    int32_t freshpos(int32_t motorid) override;
    int32_t freshPos_multi(int32_t maxaxiss) override;
    float64_t freshAPos(int32_t motorid) override;
    float64_t freshFPos(int32_t motorid) override;

    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 = true) override;
    int32_t absmove_direct(int32_t motorid, float64_t fpos, bool bwaitfinished = true);

    int32_t startmove(int32_t motorid, float64_t  dspd) override;
    int32_t stopmove(int32_t motorid) override;
    int32_t stopmove_all();
    int32_t abortprm(int32_t buffid);
    int32_t abortprm_all();
    int32_t preparehome(int32_t motorid) override;
    int32_t home(int32_t motorid, bool_t bwait = false) override;
    int32_t wait_home_finished(int32_t motorid) override;
    virtual int32_t afterhome(int32_t motorid) override;
    int32_t home_all(int32_t style) override;

    int32_t setdefaultspeed(int32_t motorid) override;
    int32_t setspeed(int32_t motorid, float64_t fspd, float64_t faccspd, float64_t fdecspd,
                     float64_t fjerk, float64_t fkdec) override;
    int32_t emg_on(bool bon) override;
    int32_t wait_move_finished(int32_t motorid, bool bcheckLimit = true) override;
    virtual int32_t wait_move_finished_block(int32_t motorid, int iMS) override;
    int32_t wait_prg_finished(int32_t buffid) override;
    virtual int32_t wait_prg_finished_block(int32_t bufferid) override;
    int32_t wait_prg_finished_all();
public:
    bool_t is_prg_finished(int32_t buffid);
    bool_t is_move_finished(int32_t motorid) override;
    bool_t is_motor_enabled(int32_t motorid) override;
    bool_t is_motor_onpaslimit(int32_t motorid) override;
    bool_t is_motor_onnaglimit(int32_t motorid) override;

    int32_t get_prg_remain_size(int32_t buffid);
    int32_t pause_prg(int32_t buffid, int iMode);
    int32_t resume_prg(int32_t buffid);
public:
    void offsetHomePos(int32_t motorid);
    void setHomeStatus(int32_t motorid, bool bhasHomed);
    void freshHomeStatus(int32_t motorid);
    int32_t enable_axis(int32_t motorid, bool_t bEnable);
public:
    //PEG操作
    int PEGMove(int32_t motorid, double dStartPos, double dEndPos, double* pegpos, int* state, int isize);
    BOOL IsPEGREADY(int32_t motorid);
    int WaitPegReady(int32_t motorid);
    int PegStart(int32_t motorid, int isize);
    int PegStop(int32_t motorid);
public:
    int PEGMove_BuffGate(int32_t motorid, int32_t gateIoIdx, 
                                 double dStartPos, double dEndPos, 
                                 double* pegpos, int isize, 
                                 bool bEnableLaser)  override;
    int LoadBufferGate(int32_t motorId, int32_t bufferIdx, int32_t gateIoIdx, 
                               double dStartPos, double dEndPos, bool bEnableLaser)  override;
public:
    int CircleMove();
    int WaitSegmentFinshed(int32_t motorId);
    BOOL IsSegFinished(int32_t motorId);
    int MultAxisMultiMove(bool bCyclic);
public:
    int SegmentCircleMove(double startPosX, double startPosY,
                          double endPosX, double endPosY,
                          double centerX, double centerY,
                          double angle, double speed);
public:
    int LoadMachineGateCtrlBuf(bool bOn);
    int LoadIOGateCtrlBuf_TILL_cmd(int BufIdx, int IoPortBit, double StartPOS, double EndPOS, double StopPOS);
public:
    int WaitForStatus(int32_t motorid, MoveStatus status);
    int GetMotorStatus(int32_t motorid);
    int WriteDouble(LPCTSTR lpArrayName, double* pArray, int iSize, int iBuff = ACSC_NONE);
    int WriteInt(LPCTSTR lpArrayName, int* pArray, int iSize, int iBuff = ACSC_NONE);
    int StartBuff(int iBuffID);
    int StopBuff(int iBuffID);
    int MultiPointMove(int32_t motorid, double* pPoint, int iPointSize, BOOL bCyclic = TRUE, double* pVel = NULL) override;

    bool is_prg_err(int32_t buffid);
    friend class CLaserDriver_JDSU;
    void ReadGlobalInt(const char* varName, int& iValue);
    void ReadGlobalReal(const char* varName, double& fValue);
public:

};

#endif // CMOTORDRIVER_ACS_H
