#pragma once

#include "IIO.h"
#include "IAxisManager.h"
#include "JSMotion.h"
#include "ICard.h"
#include <vector>
#include  <map>


/*
 * 原先在抽象ICard中定义的数字移入此处
 * by liuyenuo 2024/10/21
*/
#define c_nMaxCardNum 1
#define c_nMaxAxisNum 4

#define c_nMaxDigitModuleNum 1
#define c_nDigitIndex0_ModuleNo 0

class AxesParamPage;
class AxesMapPage;
class IOMapPage;
class CoordTest;

struct bInitOK
{
    bool bCardInitOK = false;
    bool bIOInitOK = false;
    bool bAxisInitOK = false;
    bool bCrdInitOK = false;
};

class DLL_API JMotion
{

public:
    JMotion();
    ~JMotion();
    //初始化
    bool Init();

    //显示参数页面
    bool ShowParaPage();
    //显示调试页面
    bool ShowAdjustPage();
    //显示IO调试界面
    bool ShowIOMap();
    //显示Coord坐标系测试界面(不必要长期保留)
    bool ShowCoordPage();
    //获取轴参数界面指针
    AxesParamPage* getAxesParaPage();
    AxesMapPage* getMapPage();
    IOMapPage* getIOPage();
    //获取轴对象
    std::vector<JAxis *> getAxesObject();
    //根据名称获取单轴对象
    JAxis* getSingleAxis(std::string sName);
    //获取卡对象
    std::vector<ICard *> getCardObject();
    //获取坐标系对象
    std::vector<ICoord *> getCoordObject();
    ICoord* getSingleCoord(std::string sName);
    //获取轴管理对象指针
    IAxisManager* getAxisManagerObject();


    //下面是获取各个IO对象
    std::vector<CDigitInput*> getDi();
    CDigitInput* getSingleDi(std::string sName);

    std::vector<CDigitInputS*> getDiS();
    CDigitInputS* getSingleDiS(std::string sName);

    std::vector<CDigitOutput*> getDo();
    CDigitOutput* getSingleDo(std::string sName);

    std::vector<CDigitOutputS*> getDoS();
    CDigitOutputS* getSingleDoS(std::string sName);

    std::vector<CAnalogOutput*> getAo();
    CAnalogOutput* getSingleAo(std::string sName);

    std::vector<CAnalogInput*> getAi();
    CAnalogInput* getSingleAI(std::string sName);



private:

    //退出或者关闭
    bool Exit();
    void createPage();
    //模板清除对象
    template <typename objType>
    void closeObject(std::vector<objType> &objDelete);
    //记录当前轴之前的卡含有的轴总数
    // void RecordCardAxis();


private:
    /*
     *判断是否整个运动库是否初始化成功的标志位
     */
    bool m_bInitOK = false;

    /*
     *一个对应轴名称和其轴前面卡轴数量的map
     */
    // std::map<std::string,int> m_mpFormerCardAxis ;


    /*
     *下面为UI界面的指针
     */
    AxesParamPage *m_pParamPage =nullptr;
    AxesMapPage* m_pAxesMapPage = nullptr;
    IOMapPage* m_pIOMapPage = nullptr;
    CoordTest* m_pCoordTestPage = nullptr;

    /*
     * 下面为JMotion中使用的轴,卡,IO信息,坐标系
     * 1、每一张卡需要对应一个IO输入,IO输出;以及若干轴;
     * 2、每一个Coord都对应若干轴,Coord是唯一在其中有使用其他子模块的
    */
    std::vector<JAxis*> m_vAxes;//[c_nMaxCardNum*c_nMaxAxisNum];
    //通过唯一的轴名称来获得轴
    std::map<std::string,JAxis*> m_mpAxes;


    //数据库中获取的轴数据
    std::vector<ServoAxisData> m_vServoAxisData;
    std::vector<StepAxisData> m_vStepAxisData;
    std::vector<ForcerAxisData> m_vForceAxisData;


    //数据库中获取的IO数据
    std::vector<DIOData> m_vDIOData;
    std::vector<AIOData> m_vAIOData;
    std::vector<CoordPara> m_vCoordData;

    std::vector<CDigitInput*> m_vDi;
    std::vector<CDigitOutput*> m_vDo;
    std::map<std::string,CDigitInput*> m_mpDi;
    std::map<std::string,CDigitOutput*> m_mpDo;

    std::vector<CDigitInputS*> m_vDiS;
    std::vector<CDigitOutputS*> m_vDoS;
    std::map<std::string,CDigitInputS*> m_mpDiS;
    std::map<std::string,CDigitOutputS*> m_mpDoS;

    std::vector<CAnalogOutput*> m_vAo;
    std::vector<CAnalogInput*> m_vAi;
    std::map<std::string,CAnalogOutput*> m_mpAo;
    std::map<std::string,CAnalogInput*> m_mpAi;


    // 多卡多数字模块的输入输出
    // 如:m_pExtDi(0,0)代表0号卡的0号数字模块
    std::vector<std::vector<CDigitInput*>> m_vExtDi;//[c_nMaxCardNum][c_nMaxDigitModuleNum];
    std::vector<std::vector<CDigitOutput*>> m_vExtDo;//[c_nMaxCardNum][c_nMaxDigitModuleNum];


    //对应的多坐标系
    std::vector<ICoord *> m_vCoord;//[c_nMaxCardNum]
    std::map<std::string,ICoord*> m_mpCoord;

    //对应的多张卡
    std::vector<ICard *> m_vCard;//[c_nMaxCardNum]
    //轴管理对象
    IAxisManager *m_cAxisManager;
};