// Motor_7856.h: interface for the CMotor_1203 class.
//
//////////////////////////////////////////////////////////////////////
#pragma once

#include <map>

#include "MotorAdlinkBase.h"

#define MAX_AXIS_SIMULTANEOUS_MOV_ETHERCAT 8

class CMotor_1203 : public CMotorAdlinkBase
{
public:
    CMotor_1203(CMtrProfile mtrProfile, double* dpPos, CMotionControllerBase* pBaseController);
    virtual ~CMotor_1203();

    // **************************************************************
    // Methods declaration
    // **************************************************************

    // method to close the axis
    void CloseAxis() override;

    void ConstructAxis() override;

    // method to initialize and configure the axis
    void ConstructMotor() override;

    //  method to On/Off motor
    bool OnMotor() override;
    bool OffMotor() override;

    //  method to stop motor with decceleration
    bool DecelStop() override;

    //  method to trigger Emergency stop the motor  int EStop();
    bool EmergStop() override;

    // method to get commanded position
    bool GetMotorCommandedPosition(int nMtrNo, double* pRaw) override;

    // method to get other motor axis IO status
    int GetMotionIOStatus(const CMtrProfile& mtrProfile) override;

    // method to get other motor axis current position
    bool GetMotorPosition(const CMtrProfile& mtrProfile, double* pRawPosition) override;

    // method to get motor axis current position error
    bool GetMotorPositionError(double* pRawPositionError) override;

    bool FindHome(HOME_DIR homeDir, MOTION_SPEED speed, bool bToggleHomeSensor);

    // Home by sensor or by limit
    BOOL HomeByHomeMode(int homeMode);

    // method to do homing by limit sensor
    BOOL HomingByLimit() override;

    // method to do homing by index signal
    BOOL HomeByIndex() override;

    // method to do homing by Home Sensor
    BOOL HomeBySensor() override;

    // method to home by home mode 27: (EL On Then reverse to count EZ number and reset counter)
    BOOL HomeByLimitThenIndex() override;

    // method to move absolute
    bool AbsoluteMove(double dPosition, int nMode, PROFILE_CURVE curve) override;

    // method to move continuously
    int MoveContinuously(bool bCW = true) override;

    // method to move relative distance
    bool RelativeMove(double dDistance, PROFILE_CURVE curve) override;

    // method to process interrupt to decode what happen to the motor
    void ProcessInt(int nIntCode = 0) override;

    // method to reset single trigger
    int ResetSingleTrigger(double dPosition = 0.0) override;

    // method to set the commanded position register
    bool SetMotorCommandedPosition(double dPosition) override;

    // method to set the mechanical coversion factor
    bool RefreshMotorConversionFactor() override;

    // method to set homing modes
    bool SetMotorHomeMode(int iHomeMode) override;

    int SetMultipleTrigger(double* pPosition, int nNoOfTrigger, int nCmpSource = 1) override;

    // method to set multiple trigger
    bool SetMotorMultipleTrigger(const multiple_trigger& trigger) override;

    // method to force set the current position
    bool SetMotorPosition(double dPosition) override;

    // method to arm controller axis for single trigger
    int SetSingleTrigger(double dPosition, int nCmpSource = 1, int nPulseStretch = STRETCH_NON) override;

    // method to arm multiaxis for simultaneous motion
    bool SetupAbsoluteSimultaneousMove(int nNoOfAxis, short* sAxis, double* dPosition, double* dStartVel, double* dMaxVel, double* dAcc, double* dDec) override;
    bool SetupRelativeSimultaneousMove(int nNoOfAxis, short* sAxis, double* dPosition, double* dStartVel, double* dMaxVel, double* dAcc, double* dDec) override;
    bool StartSimultaneousMove(int nFirstAxisNo) override;
    // - use MotorAdLinkBase Simultaneous move Move - Lim HS

    // method to move motor in s-curve continuously
    int SMoveContinuously(bool bCW = true) override;

    void SetMotorProfile(double dValue, motion_profile::PROFILE_TYPE type) override;

    // method to set the motor type and encoder input type
    bool SetMotorType(int iMtrType) override;

    // method to set the motor alarm signal logic
    bool SetMotorAlarmLogic(int iALM) override;

    // method to set the home sensor signal logic
    bool SetMotorHomeSensorLogic(int iORGI) override;

    // method to set the encoder Index signal logic
    bool SetMotorIndexLogic(int iIndexLogic) override;

    // method to set the in position signal logic
    bool SetMotorINPLogic(int iINP) override;

    // method to set clk type, out/dir or cw/ccw
    bool SetMotorClk(int iClk) override;

    // Method to reset driver alarm via MotionNet
    int ResetAlarm(bool bReset) override;
    bool IsSimultaneousMoveSupported(void) override;

    virtual double ConvertAccToMtrUnits(double dAcc, double dNumPulsePerMM) override;

private:
    typedef struct _stSimMoveInfo
    {
        unsigned short shMode; // 0 = ABs, 1 = Rel
        double dMasterPos;
        // ctor
        _stSimMoveInfo()
        {
            shMode     = 0;
            dMasterPos = 0;
        }
    } stSimMoveInfo;

    UINT_PTR m_hAxis;

    int Home(bool bHomeReverse, bool bSlowSpeed);

    bool PrepareMotionCurve(PROFILE_CURVE curve);

    enum PROFILE_TYPE
    {
        ACC,
        DEC,
        START_VEL,
        MAX_VEL,
    };

    ULONG GetHwHomeMode(int iHomeMode);

    bool SetMotionProfile(PROFILE_TYPE profileType);

    bool BeginContinuousMove(bool bDirection);

    bool ContinuousMove(PROFILE_CURVE profileCurve, bool bDir);

    bool PrepareForMove(PROFILE_CURVE profileCurve);
    bool PrepareSimultaneousMove(const std::vector<UINT_PTR>& vecAxisHandle, double* dPosition, double* dStartVel, double* dMaxVel, double* dAcc, double* dDec);

    stSimMoveInfo m_stSimMove;
    long m_AxisId[MAX_AXIS_SIMULTANEOUS_MOV_ETHERCAT];
    long m_Posn[MAX_AXIS_SIMULTANEOUS_MOV_ETHERCAT];
    long m_MaxVel[MAX_AXIS_SIMULTANEOUS_MOV_ETHERCAT];
};

