#pragma once
#include "CppSQLite3.h"
#include "dt.h"
#include "CMathCalc.h"
#include <string>
#include <windows.h>
#include <mutex>


#include "CDataBaseOperate.h"

namespace ns_db
{

	using namespace std;

#ifdef MACHINE_CALIBRATION_DLL
#define DLL_MACHINE_CALIBRATION_API __declspec(dllexport)
#else
#define DLL_MACHINE_CALIBRATION_API
#endif

#define MACHINE_CALIBRATION_DATABASE_NAME			    ROOT_PATH##"\\db\\MachineCalibration.db"
#define CTD_CALIB_TABLE_NAME		                    "Calib_CameraTipDis"
#define XY_CALIB_TABLE_NAME		                        "Calib_XY"
#define R_CALIB_TABLE_NAME		                        "Calib_R"
#define STEP_R_CALIB_RESULT_TABLE_NAME		            "Calib_R_Result"
#define FORCE_CONTROL_TABLE_NAME                        "Force_Control"
#define HORIZONTAL_MEASURE_TABLE_NAME                   "Horizontal_Measure"
#define VERTICAL_MEASURE_TABLE_NAME                     "Vertical_Measure"
#define TIP_CALIB_RESULT                                "Tip_R_CTD_CalibResult"


#pragma region 标定参数
    struct CALIB_XY {
        int m_nId = 0;
        string m_sName = "";
        double m_dCenterPosX = 0;               //九点中间点的X坐标
        double m_dCenterPosY = 0;               //九点中间点的Y坐标
        double m_dGrabPosZ = 0;                 //标定时Z轴位置
        double m_dCalibStepX = 0;               //相机标定步进X
        double m_dCalibStepY = 0;               //相机标定步进Y
        int m_nTempId = 0;                      //策略id
        string m_sResultMatrix = "";             //标定结果矩阵

        //结果矩阵,暂时屏蔽

        //double m_dA = 1.0; // 缩放因子x
        //double m_dB = 0.0; // 旋转因子
        //double m_dC = 0.0; // 旋转因子
        //double m_dD = 1.0; // 缩放因子y
        //double m_dTx = 5.0; // 平移x
        //double m_dTy = 10.0; // 平移y
    };



    typedef struct _R_Calib_Result
    {
        int m_nId;
        string m_sName;
        int nIndex;
        DOUBLE dAngle;                                //旋转角度
        DOUBLE dOffset_X;                        //旋转后X偏差
        DOUBLE dOffset_Y;                        //旋转后Y偏差
    }Step_RCalib_Result;


    struct CALIB_R {
        int m_nId;
        string m_sName;
        double m_dCalibPosX = 0;
        double m_dCalibPosY = 0;
        double m_dAngleStep = 1;                                    //标定时旋转角度,角度单位
        double m_dAngleLower = -90;                                 //标定时角度下限
        double m_dAngleUpper = 90;                                  //标定时角度上限
        XY_DOUBLE_STRUCT m_stRotateCenter = { 0,0 };                //旋转中心
        double m_dRad = 0;                                              //旋转半径
        double m_dStartAngle = 0;
        double m_dRotationAngle = 20;                               //旋转角度
        int m_nRotationNum = 3;                                     //旋转次数
        double m_dGrabPosZ = 0;                                     //拍照位
        int m_nTempId = 0;
    };


    struct CALIB_LOOKUP {
        int m_nId = 0;
        string m_sName = "";
        bool m_bHaveHeadPos = false;//已完成旋转中心标定	
        double m_dCameraPosX = 0;;			//下视标定时X位置
        double m_dCameraPosY = 0;			//下视标定时Y位置
        double m_dCameraPosZ = 0;			//下视标定时Z位置

        double m_dHeadPosX = 0;         //头位置X
        double m_dHeadPosY = 0;         //头位置Y
        double m_dHeadPosZ = 0;         //头位置Z

        double m_dCameraToHeadPosX = 0;		//相机移动到头的相对位置
        double m_dCameraToHeadPosY = 0;     //

        double m_dHeadActualPosX = -1;
        double m_dHeadActualPosY = -1;

        double m_dCameraActualPosX = -1;    //标定相机和上视相机对准时,绑头获取的位置
        double m_dCameraActualPosY = -1;    //标定相机和上视相机对准时,绑头获取的位置

        int m_nBondTempID = 0;			//绑头相机拍Mark点模板ID
        int m_nLookUpTempID = 0;		//上视相机拍Mark点模板ID
        int m_nTipTempID = 0;        //上视相机拍吸嘴模板
    };

    struct FORCE_CONTROL {
        //得到关系式: 力 = 电流 * A + B
        int nHeadId = 0;
        std::string sHeadName = "";
        double dA1 = 1;     //电流系数
        double dA2 = 1;     //弹簧系数
        double dB = 0;
        double dGivenForceZPos = 0;//压合距离,用于判断接触
        vector<POINTF> vetPts;   //POINTF的x为力或电流
        double dGivenCurrent = 0;//压合距离,用于判断接触
        vector<POINTF> vetForcePos;   //POINTF的x为力或电流

        double dFTestSearchPosZ = 0;//力控测试搜索位置
        double dTestPosX = 0;
        double dTestPosY = 0;
        double dFSearchDis = 0;//力控搜索距离
        double dSearchVel = 0;//力控搜索速度
        int nPressDelay = 0;//力控测试时延时
        double dInitPosZ = 0;//Z轴测完上升的初始位
    };

    struct HORIZ_MEASURE{
        int nTableID = 0;
        double dTestPosX1 = 0;
        double dTestPosY1 = 0;
        double dTestPosX2 = 0;
        double dTestPosY2 = 0;
        double dTestPosX3 = 0;
        double dTestPosY3 = 0;
        double dSearchPosZ = 0;

        double dAngleX = 0;//校准后的结果, X方向
        double dAngleY = 0;//校准后的结果, Y方向
    };
    struct VERTICAL_MEASURE
    {
        int nHeadId = 0;
        double dMeasurePosX = 0;
        double dMeasurePosY = 0;
        double dAngle1 = 0;//0
        double dAngle2 = 0;//90
        double dAngle3 = 0;//180
        double dFixtureAngle = 0;//治具角度
        double dFixtureLength = 0;//治具长度
        double dSearchPosZ = 0;

        double dZAxisAngleX = 0;//校准结果,Z轴X方向偏移角度
        double dZAxisAngleY = 0;//校准结果,Z轴Y方向偏移角度
    };

    struct NozzleCalibParam
    {
        int nNozzleId = 0;
        XY_DOUBLE_STRUCT stRotCenter = { 0,0 }; //吸嘴对应的旋转中心X
        XY_DOUBLE_STRUCT stBHHighCameraToNozzle = { 0,0 };
        XY_DOUBLE_STRUCT stBHLowCameraToNozzle = { 0,0 };
        XY_DOUBLE_STRUCT stWHCameraToNozzle = { 0,0 };
        bool bIsRotationCalib = false;	//已校准标记
        bool bIsHighCTDCalib = false;		//已校准标记
        bool bIsLowCTDCalib = false;         //已校准标记
        int nRTempID = 0;                   //旋转中心标定吸嘴模板ID
        //int nCTDBHLookUpTempID = 0;           //CTD标定上视模板ID
        //int nCTDHighBondTempID = 0;             //CTD标定固晶相机模板ID
        //int nCTDLowBondTempID = 0;             //CTD标定固晶相机模板ID
        int nCTDWHNozzleTempID = 0;             //华夫盒取晶头上视相机

    };

#pragma endregion

    class DLL_MACHINE_CALIBRATION_API CMachineCalibration : public CDataBaseOperate
    {
    public:
        CMachineCalibration();

    private:
        LONG SaveDB() override;
        LONG LoadDB() override;



    private:
        vector<CALIB_XY> m_vetCalibXY;
        vector<CALIB_R> m_vetCalibR;
        vector<CALIB_LOOKUP> m_vetCalibLookUp;
        vector<Step_RCalib_Result> m_vetStepRCalibResult;
        vector<FORCE_CONTROL> m_vetForceControl;
        vector<HORIZ_MEASURE> m_vetHorizMeasure;
        vector<VERTICAL_MEASURE> m_vetVerticalMeasure;
        vector<NozzleCalibParam> m_vetNozzleCalibParam;
    public:
        LONG GetCalibXYParam(int calibID, string name, CALIB_XY& calibXY);
        LONG GetCalibRParam(int calibID, string name, CALIB_R& calibR);
        LONG GetCalibLookUpParam(int calibID, string name, CALIB_LOOKUP& calibLookUp);
        LONG GetStepCalibResult(int calibID, string name, vector<Step_RCalib_Result>& m_stVecCalib_R);

        LONG GetNozzleCalibParam(int index, NozzleCalibParam& param);
        LONG SetNozzleCalibParam(int index, NozzleCalibParam param);

        LONG GetForceParam(int HeadID, FORCE_CONTROL& vetForceControl);
        LONG GetHorizMeasureParam(int HeadID, HORIZ_MEASURE& vetHorizMeasure);
        LONG GetVerticalMeasureParam(int HeadID, VERTICAL_MEASURE& vetVerticalMeasure);

        LONG SetCalibXYParam(int calibID, string name, CALIB_XY calibXY);
        LONG SetCalibRParam(int calibID, string name, CALIB_R calibXY);
        LONG SetCalibLookUpParam(int calibID, string name, CALIB_LOOKUP calibXY);
        LONG SetCalibRResult(int calibID, string name, vector<Step_RCalib_Result>& VecCalib_R);


        LONG SaveCalibXYParam();
        LONG SaveCalibRParam();
        LONG SaveCalibLookUpParam();
        LONG SaveCalibRResult();
        LONG SaveCalibForceParam();
        LONG SaveCalibTipParam();


        //bool SetCalibXYParam(int calibID, string name, CALIB_XY& calibXY);
        //bool SetCalibRParam(int calibID, string name, CALIB_R& calibR);
        //bool SetCalibLookUpParam(int calibID, string name, CALIB_LOOKUP& calibLookUp);
        //bool SetStepCalibResult(int calibID, string name, vector<Step_RCalib_Result>& m_stVecCalib_R);


      //读标定数据
        LONG LoadCalibXYParam(vector<CALIB_XY>& calibXY);
        LONG LoadCalibRParam(vector<CALIB_R>& calibR);
        LONG LoadCalibLookUpParam(vector<CALIB_LOOKUP>& calibLookUp);
        LONG LoadStepCalibResult(vector<Step_RCalib_Result>& m_stVecCalib_R);
        LONG LoadCalibForceParam(vector<FORCE_CONTROL>& vetForce);
        LONG LoadHorizMeasureParam(vector<HORIZ_MEASURE>& vetHorizMeasure);
        LONG LoadVerticalMeasureParam(vector<VERTICAL_MEASURE>& vetVerticalMeasure);
        LONG LoadNozzleCalibParam(vector<NozzleCalibParam>& nozzleParam);


    private:
        LONG SaveCalibXYParam(int calibID, string name, CALIB_XY calibXY);
        LONG SaveCalibRParam(int calibID, string name, CALIB_R calibXY);
        LONG SaveCalibLookUpParam(int calibID, string name, CALIB_LOOKUP calibXY);
        LONG SaveCalibRResult(int calibID, string name, vector<Step_RCalib_Result>& VecCalib_R);
        LONG SaveCalibForceParam(int headID, string name, FORCE_CONTROL VecCalib_R);
        LONG SaveCalibTipParam(int TipID, NozzleCalibParam NozzleCalibParam);

    };



}