#ifndef IAXISMANAGER_H
#define IAXISMANAGER_H

#include "JAxis.h"
#include "ICoord.h"
#include <map>


//运动等待模式
enum emum_Wait_Action
{
    WAIT = 0,//等待所有移动结束
    NO_WAIT//不等待移动结束
};

enum Response_Status
{
    Response_OK = 0,//过程OK
    Response_Abort,//过程取消
    Response_Error,//过程出错
};

struct ProcessResponse
{
    Response_Status eStatus = Response_OK; //过程状态
    int ErrorCode = 0; //错误码
    std::string sErrorMessage = ""; //错误信息
};

//联锁轴状态
enum emum_Interlock_Axis_Action
{
    ALARM,//若联锁轴不在安全位置则取消移动并报警
    //ABORT,//若联锁轴不在安全位置则取消移动但不报警
    TRIGGER,//必须的情况下触发联锁轴移动到安全位置
    COMPEL//任何情况下强制联锁轴移动到安全位置
};

//自动避障枚举
enum Collision_Detect_Mode
{
    ColDetect_BothAvoid, //Go-Over和Go-Around NGZ均进行自动避让
    ColDetect_OverAvoid_AroundInhibit, //Go-Over NGZ自动避让,Go-Around NGZ禁止自动避让(禁止移动并报警)
    ColDetect_BothInhibit, //Go-Over和Go-Around NGZ均禁止自动避让(禁止移动并报警)
    ColDetect_BothInhibit_Manual, //用于手动鼠标移动,Go-Over和Go-Around NGZ均禁止自动避让(禁止移动并报警),但不考虑Highway和Bond的配置兼容性
    ColDetect_Disable //关闭碰撞识别(谨慎使用此模式,关闭碰撞识别可能造成碰撞!)
};

class IAxisManager
{
public:
    IAxisManager(){};
    ~IAxisManager(){};

    //初始化AxisManager
    virtual ProcessResponse Init(std::map<std::string,JAxis*> &mpAxis, std::map<std::string,ICoord*> &mpCoord) = 0;
    //退出AxisManager
    virtual ProcessResponse Exit() = 0;

    /*********************
     * 设置轴中的参数
     * *********************/
    /**
     * @brief SetMotionTimeout 设置运动超时时间(ms)
     * @brief ClearMotionTimeout 清除运动超时时间
     * 设置运动超时时间后,后续的WAIT运动都会以此时间进行运动超时判断及报警,直到清除运动超时时间为止,
     * 期间可再次调用SetMotionTimeout设置新的超时时间(对后续运动均生效)
     */
    virtual ProcessResponse SetMotionTimeOut(int nTime_ms) = 0;
    virtual ProcessResponse ClearMotionTimeOut() = 0;

    /**
     * @brief 设为true时设为急停状态并清除各轴已回零状态
     */
    virtual ProcessResponse SetEmergencyStopStatus(bool bStatus) = 0;


    /**
     * @brief 设置轴点位运动速度,设置的为速度比率
     */
    virtual ProcessResponse SetAxisVel(std::string sAxisName, double dVelRatio) = 0;

    /**
     * @brief 设置轴点位运动速度及加速度,设置的为速度比率,对Acc会乘dVelRatio*dVelRatio
     */
    virtual ProcessResponse SetAxisVelAcc(std::string sAxisName, double dVelRatio) = 0;

    /**
     * @brief 设置轴点位运动加速度,设置的为加速度比率
     * bIsAccRatio==false时输入的为速度比率,Acc乘dVelOrAccRatio*dVelOrAccRatio.
     * bIsAccRatio==true时输入的为加速度比率,Acc乘dVelOrAccRatio.
     */
    virtual ProcessResponse SetAxisAcc(std::string sAxisName, double dVelOrAccRatio, bool bIsAccRatio = false) = 0;


    /*********************
     * 参数获取
     * *********************/
    /**
     * @brief 获取轴状态,获取轴状态结构体
     */
    virtual ProcessResponse GetAxisStatus(std::string sAxisName,AxisStatus& stAxisStatus) = 0;

    /**
     * @brief 获取轴当前的位置
     */
    virtual double GetAxisActualPos(std::string sAxisName,ProcessResponse &stResponse) = 0;
    /**
     * @brief 获取轴当前的速度
     */
    virtual double GetAxisActualVel(std::string sAxisName,ProcessResponse &stResponse) = 0;
    /**
     * @brief 获取轴当前的加速度
     */
    virtual double GetAxisActualAcc(std::string sAxisName,ProcessResponse &stResponse) = 0;


    /**
     * @brief 监控并等待运动结束(单轴)
     * @param nMonitorInterval 运动状态监控及查询周期(ms),>0时优先使用该参数,设为<=0时会使用MachineConfigJson中的设置值
     * @param bInstantStopMode true=bStop变量为true时运动立即停止并返回Response_Abort,false=bStop变量为true时完成当前运动并返回Response_Abort
     */
    virtual ProcessResponse WaitForMotionComplete(JAxis* pAxis, int nMonitorInterval, const bool& bStop = false,
                                                  bool bInstantStopMode = false) = 0;

    /**
     * @brief 检查轴故障、使能、回零等状态(单轴)
     * @param sAxisName 当前查询轴的名称
     */
    virtual ProcessResponse CheckAxisStatus(std::string sAxisName) = 0;


    /**
     * @brief 判断当前是否为急停状态
     */
    virtual bool isEmergencyStop(std::string sAxisName) = 0;




    /*********************
     * 单轴运动
     * *********************/


    /**
     * @brief 单轴运动一定距离,正常点位/点动模式
     */
    virtual ProcessResponse MoveToTrap( std::string sAxisName,double dPosOrDist,double dVelRatio,
                               emum_Wait_Action eWaitAction,const bool& bStop = false) = 0;

    /**
     * @brief 单轴运动一定距离,Gear齿轮
     */
    virtual ProcessResponse MoveToGear(std::string sAxisName,std::string sMasterName,double dPosOrDist,
                               long nMasterEven,long nSlaveEven,long nSlopeOrFollowDis = 0) = 0;
    /**
     * @brief 单轴运动一定距离,Follow凸轮
     */
    virtual ProcessResponse MoveToFollow(std::string sAxisName,std::string sMasterName,double dPosOrDist,
                                         long nMasterEven,long nSlaveEven,long nSlopeOrFollowDis = 0) = 0;


    /**
     * @brief 单轴运动一定距离,正常点位/点动模式
     */
    virtual ProcessResponse MoveTrap( std::string sAxisName,double dPosOrDist,double dVelRatio,emum_Wait_Action eWaitAction) = 0;
    /**
     * @brief 单轴运动,点动模式
     */
    virtual ProcessResponse Jog(std::string sAxisName,double dVelRatio) = 0;
    /**
     * @brief 单轴运动一定距离,Gear齿轮
     */
    virtual ProcessResponse MoveGear(std::string sAxisName,std::string sMasterName,double dPosOrDist,
                             long nMasterEven,long nSlaveEven,long nSlopeOrFollowDis = 0) = 0;
    /**
     * @brief 单轴运动一定距离,Follow凸轮
     */
    virtual ProcessResponse MoveFollow(std::string sAxisName,std::string sMasterName,double dPosOrDist,
                               long nMasterEven,long nSlaveEven,long nSlopeOrFollowDis = 0) = 0;

    /**
     * @brief 调用对应轴的回零运动
     */
    virtual ProcessResponse AxisHoming(std::string sAxisName, const bool& bStop = false) = 0;



    /*********************
     * 设置多轴(坐标系)参数
     **********************/
    /**
     * @brief 将轴的合成速度,加速度,加加速度一次性根据与VelRatio的关系设置
     */
    virtual ProcessResponse SetCrdSynAllRatio(double dVelRatio) = 0;
    /**
     * @brief 设置轴的合成速度
     */
    virtual ProcessResponse SetCrdSynVelRatio(double dVelRatio) = 0;



    /*********************
     * 多轴运动
     **********************/


    /*
     * 多轴协同点位运动(绝对位移)
     * 前面几种都使用坐标系实现,XYZRF五个轴需要自己加轴实现
     */

    virtual ProcessResponse XYMoveTo(std::string sCrdName,double dXPos, double dYPos, bool& bExit, bool bWaitStop) = 0;
    virtual ProcessResponse XYZMoveTo(std::string sCrdName,double dXPos, double dYPos, double dZPos, bool& bExit, bool bWaitStop) = 0;
    virtual ProcessResponse XYRMoveTo(std::string sCrdName,double dXPos, double dYPos, double dRPos,bool& bExit, bool bWaitStop) = 0;
    virtual ProcessResponse XYZRMoveTo(std::string sCrdName,double dXPos, double dYPos, double dZPos,double dRPos,bool& bExit,
                                       bool bWaitStop) = 0;

    virtual ProcessResponse XZMoveTo(std::string sCrdName,double dXPos, double dZPos, bool& bExit, bool bWaitStop) = 0;
    virtual ProcessResponse XRMoveTo(std::string sCrdName,double dXPos, double dRPos, bool& bExit, bool bWaitStop) = 0;
    virtual ProcessResponse XZRMoveTo(std::string sCrdName,double dXPos, double dZPos, double dRPos, bool& bExit, bool bWaitStop) = 0;

    virtual ProcessResponse YZMoveTo(std::string sCrdName,double dYPos, double dZPos, bool& bExit, bool bWaitStop) = 0;
    virtual ProcessResponse YRMoveTo(std::string sCrdName,double dYPos, double dRPos, bool& bExit, bool bWaitStop) = 0;
    virtual ProcessResponse YZRMoveTo(std::string sCrdName,double dYPos, double dZPos, double dRPos, bool& bExit, bool bWaitStop) = 0;

    virtual ProcessResponse ZRMoveTo(std::string sCrdName,double dZPos, double dRPos, bool& bExit, bool bWaitStop) = 0;

};

#endif // IAXISMANAGER_H