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

#include "CDataBaseOperate.h"

#ifdef PRODUCT_DLL
#define DLL_PRODUCT_API __declspec(dllexport)
#else
#define DLL_PRODUCT_API
#endif

#define PRODUCT_DATABASE_NAME			                "\\Product.db"
#define PROGRAM_BOND_MATRIX_TABLE_NAME                                "Program_BondMatrix"
#define PROGRAM_PONIT_MATRIX_TABLE_NAME                                "Program_PointMatrix"
#define PROGRAM_DIE_MATRIX_TABLE_NAME                                "Program_DieMatrix"
#define PROGRAM_WAFER_MATRIX_TABLE_NAME                                "Program_WaferMatrix"
#define PROGRAM_WAFFLE_MATRIX_TABLE_NAME                                "Program_WaffleMatrix"
#define PROGRAM_PARAM_TABLE_NAME                                "Program_Param"
#define PROGRAM_BOND_INFO_TABLE_NAME                                "Program_BondInfo"
#define PROGRAM_HEAD_TABLE_TABLE_NAME                                "Program_HeadTableMatrix"
#define ONE_DIM_MATRIX_TABLE_NAME									"OneDimMatrix"

#define STEP_LIST_DETAIL_TABLE_NAME                     "StepListDetail"
#define STEP_PUBLIC_DATA_TABLE_NAME                     "StepPublicData"
#define ALN_STRATEGY_TABLE_NAME                         "PR_Strategy"
#define PR_TEMPLATE_TABLE_NAME							"PR_Template"


namespace ns_db
{
	using namespace std;

	//一维矩阵ID
	enum OneDimMatrixID
	{
		NozzleMatrix = 0,
	};

	//模板类型枚举
	enum MCM_TEMPLATE_TYPE {
		COMMON_MIN = 0, COMMON_MAX = 50000,
		BONDINSP_MIN = 50001, BONDINSP_MAX = 60000,
		EXPOXY_MIN = 60001, EXPOXY_MAX = 70000,
		ALN_MIN = 70001, ALN_MAX = 80000
	};

	enum PICKBOND_PARAM_TYPE {
		WAFFLE_PICK = 1,						//华夫盒取晶
		WAFFLE_BOND,							//华夫盒固晶
		WAFFER_PICK,							//晶片台取晶
		WAFFER_BOND,							//晶片台固晶
		BONDHEAD_PICK,							//贴片头取晶
		BONDHEAD_BOND							//贴片头固晶
	};
	struct OneDimMatrixInfo
	{
		int nMatrixId = 0;   //矩阵ID
		std::string sMatrixName = "";	//名字
		int nMatrixRow = 0;		//矩阵行数
		int nMatrixCol = 0;		//矩阵列数
		XY_DOUBLE_STRUCT LeftTopPoint{ 0,0 };			//矩阵左上角点位置(相对位置)
		XY_DOUBLE_STRUCT RightTopPoint{ 0,0 };			//矩阵右上角点位置(相对位置)
		XY_DOUBLE_STRUCT RightBottomPoint{ 0,0 };		//矩阵右下角点位置(相对位置)
		vector<XY_LONG_STRUCT> vetNoUsedPt;				//不使用的点
	};
	//取(固)晶参数
	typedef struct _PICKBOND_PARAM_STRUCT : TABLE_INFO_BASE
	{
		UINT iId;								//参数ID
		PICKBOND_PARAM_TYPE eParamType;			//参数类型
		bool bCheckBlock;						//阻塞检测
		bool bCheckLose;						//漏晶检测
		bool bFindForce;						//是否寻压
		double dPreLev;							//预备高度
		union
		{
			double dForce;						//取(固)压力
			double dPickOrBondLev;				//取(固)高度
		};
		UINT iGrabDelay;						//拍图延时
		UINT iPickOrBondDelay;					//取(固)延时
		UINT iBlockOrLoseDelay;					//阻塞(漏晶)检测延时
		UINT iVacuumDelay;						//真空延时
		UINT iBlowDelay;						//吹气延时(0为不吹气)
	}PICKBOND_PARAM_STRUCT;

	//校准台校准类型枚举 NO_CALIB:不校准  UPLOOK_CALIB:下视校准  TABLE_CALIB:校准台校准
	enum CALIB_DIE_TYPE {
		NO_CALIB = 0x0,										//不校准
		UPLOOK_CALIB = 0x1,									//LookUp校准
		TABLE_CALIB = 0x2,									//中转台校准
		UPLOOK_TABLE_CALIB = UPLOOK_CALIB | TABLE_CALIB		//中转台和LookUp均校准
	};
	enum DIE_SOURCE {BY_NUL = 0 /*未指定*/, BY_WAFFLE = 1 /*华夫盒*/, BY_WAFER = 2/*晶片台*/ };

	//固晶信息
	typedef struct BOND_INFO_STRUCT : TABLE_INFO_BASE
	{
		UINT iInfoId;							//固晶信息Id
		//UINT iModuleId;							//模组Id
		DIE_SOURCE eDieSource;					//晶片来源
		UINT iDieMatrixId;						//使用的晶片台号或华夫盒矩阵号
		UINT iPickParamId;						//取晶参数Id
		UINT iPickPRStrategyId;					//取晶PR策略Id
		UINT iCalibBondParamId;					//校准台固晶参数Id
		UINT iPickHeadId;						//取晶吸嘴Id号
		UINT iBondHeadId;						//固晶吸嘴Id号
		UINT iCalibPickParamId;					//校准台取晶参数Id
		UINT iBondPRStrategyId;					//固晶PR策略Id
		UINT iBondParamId;						//固晶参数Id

		CALIB_DIE_TYPE eCalibType;				//校准方式
		UINT iCalibPRStrategyId;				//校准台PR策略Id
		UINT iLookUpPRStrategyId;				//下视PR策略Id

		UINT iBondFrontPRStrategyId;			//固前检测模板ID号 0为不检测
		UINT iBondBackPRStrategyId;				//固后检测模板ID号 0为不检测

		X_Y_ANGLE_STRUCT stOffset;				//固晶点补偿(从编程的固晶点位置偏移)

	}BOND_INFO_STRUCT;

	typedef struct _PROGRAM_DIE_MATRIX_STRUCT : TABLE_INFO_BASE
	{
		UINT iModuleId;							//模组Id
		string strModuleName;					//模组名称
		UINT MatrixId;							//矩阵ID
		INT MatrixRow;							//矩阵行数
		INT MatrixCol;							//矩阵列数
		XY_DOUBLE_STRUCT LeftTopPoint;			//矩阵左上角点位置(相对位置)
		XY_DOUBLE_STRUCT RightTopPoint;			//矩阵右上角点位置(相对位置)
		XY_DOUBLE_STRUCT RightBottomPoint;		//矩阵右下角点位置(相对位置)
		vector<XY_LONG_STRUCT> VecNoBondPt;		//矩阵上不固晶的Pt列表 (1,2)表示第一行第二列不固晶
	}PROGRAM_DIE_MATRIX_STRUCT;					//晶片矩阵包括华夫盒和晶圆台

	typedef struct _PROGRAM_WAFER_MATRIX_STRUCT : TABLE_INFO_BASE
	{
		UINT MatrixId;							//矩阵ID
		XY_DOUBLE_STRUCT LeftTopPoint;			//矩阵左上角点位置(绝对位置)
		UINT iDieMatrixId;						//包含的Pt矩阵Id
	}PROGRAM_WAFER_MATRIX_STRUCT;				//晶圆台矩阵

	typedef struct _PROGRAM_WAFFLE_MATRIX_STRUCT : TABLE_INFO_BASE
	{
		UINT MatrixId;								//矩阵ID
		INT PackRow;								//华夫盒行数
		INT PackCol;								//华夫盒列数
		XY_DOUBLE_STRUCT LeftTopPoint;				//矩阵左上角点位置(绝对位置)
		XY_DOUBLE_STRUCT RightTopPoint;				//矩阵右上角点位置(绝对位置)
		XY_DOUBLE_STRUCT RightBottomPoint;			//矩阵右下角点位置(绝对位置)
		vector<INT> VecDieMatrixId;					//包含的Pt矩阵Id
		vector<XY_LONG_STRUCT> VecNoBondDie;		//矩阵上不固晶的Pcb列表 (1,2)表示第一行第二列不固晶
	}PROGRAM_WAFFLE_MATRIX_STRUCT;	//华夫盒矩阵

	typedef struct _PROGRAM_POINT_MATRIX_STRUCT : TABLE_INFO_BASE
	{
		UINT MatrixId;							//矩阵ID
		UINT iModuleId;							//模组Id
		string strModuleName;					//模组名称
		INT MatrixRow;							//矩阵行数
		INT MatrixCol;							//矩阵列数
		XY_DOUBLE_STRUCT LeftTopPoint;			//矩阵左上角点位置
		XY_DOUBLE_STRUCT RightTopPoint;			//矩阵右上角点位置
		XY_DOUBLE_STRUCT RightBottomPoint;		//矩阵右下角点位置
		vector<XY_LONG_STRUCT> VecNoBondPt;		//矩阵上不固晶的Pt列表 (1,2)表示第一行第二列不固晶
	}PROGRAM_POINT_MATRIX_STRUCT;						//程序PT参数

	typedef struct _PROGRAM_BOND_MATRIX_STRUCT : TABLE_INFO_BASE
	{
		UINT BondMatrixId;						//矩阵ID
		UINT iModuleId;							//模组Id
		string strModuleName;					//模组名称
		INT BondMatrixRow;						//Pcb行数
		INT BondMatrixCol;						//Pcb列数
		XY_DOUBLE_STRUCT LeftTopPoint;			//矩阵左上角点位置
		XY_DOUBLE_STRUCT RightTopPoint;			//矩阵右上角点位置
		XY_DOUBLE_STRUCT RightBottomPoint;		//矩阵右下角点位置
		vector<INT> VecPointMatrixId;			//包含的Pt矩阵Id
		vector<XY_LONG_STRUCT> VecNoBondPt;		//矩阵上不固晶的列表 (1,2)表示第一行第二列不固晶
		INT BondInfoId;							//固晶参数Id
	}PROGRAM_BOND_MATRIX_STRUCT;				//固晶

	typedef struct _PROGRAM_HEAD_TABLE_MATRIX_STRUCT : TABLE_INFO_BASE
	{
		UINT MatrixId;							//矩阵ID
		INT MatrixRow;							//矩阵行数
		INT MatrixCol;							//矩阵列数
		XY_DOUBLE_STRUCT LeftTopPoint;			//矩阵左上角点位置
		XY_DOUBLE_STRUCT RightTopPoint;			//矩阵右上角点位置
		XY_DOUBLE_STRUCT RightBottomPoint;		//矩阵右下角点位置
		vector<XY_LONG_STRUCT> VecNoBondPt;		//矩阵上不固晶的Pt列表 (1,2)表示第一行第二列不固晶
	}PROGRAM_HEAD_TABLE_MATRIX_STRUCT;						//程序PT参数

	typedef struct _STEP_DETAIL : TABLE_INFO_BASE
	{
		UINT iIndex;							//在组中的执行顺序
		UINT iFunctionId;						//功能Id
		UINT iGroupId;							//组Id
		UINT iStepId;							//执行的StepId
		string strParam;						//执行Step时的参数(经过序列化后的参数)
	} STEP_DETAIL;

	typedef struct _STEP_PUBLIC_DATA : TABLE_INFO_BASE
	{
		UINT Id;								//参数Id
		string Key;								//参数Key
		string Value;							//值
	} STEP_PUBLIC_DATA;

	//enum TEMPLATE_TYPE {
	//	ALN_MIN = 0, ALN_MAX = 50000,				//对点策略
	//	BONDINSP_MIN = 50001, BONDINSP_MAX = 60000, //固后检测模板
	//	EXPOXY_MIN = 60001, EXPOXY_MAX = 70000,		//胶量检测模板		
	//};
	//模板图像类型枚举
	//enum TEMP_TYPE { FIND_PM = 0, FIND_GM = 1, FIND_LINE = 2, FIND_CIRCLE = 3, FIND_EPOXYINSP = 4 };

	//对点输出枚举
	enum SEARCH_OUT {
		OUT_NULL = 0X0,  //定位
		OUT_X = 0X1,
		OUT_Y = 0X2,
		OUT_Ax = 0X4/*相对于X轴角度*/,
		OUT_Ay = 0x8/*相对于Y轴角度*/,
		OUT_All = OUT_X | OUT_Y | OUT_Ax
	};

	typedef struct _PR_TEMPLATE : TABLE_INFO_BASE
	{
		UINT iTemplateId;						//模板Id
		UINT iModuleType;						//模组类型
		UINT iPrMethod;							//Pr模板方法
		UINT iCameraId;							//相机ID
		SEARCH_OUT eResultSelect;				//选取结果
		X_Y_Z_R_STRUCT stGrabPos;				//拍照位置

		UINT iRedLight;							//灯光参数1
		UINT iGreenLight;						//灯光参数2
		UINT iBlueLight;						//灯光参数3
		UINT iPointLight;						//灯光参数4
		double dExposureTime;						//相机曝光时间
		double dGain;								//相机对比度

		string Date;							//模板创建时间

	} PR_TEMPLATE;

	typedef struct _PR_STRATEGY : TABLE_INFO_BASE
	{
		UINT iStrategyId;						//PR策略ID
		vector<UINT> vecTemplateId;					//模板ID

		X_Y_ANGLE_STRUCT stRef;					//基准位置
		string Date;							//模板创建时间
	}PR_STRATEGY;

	typedef struct _TEMPERATURE_LIST_STRUCT
	{
		double dTemperature;	//共晶温度
		double dForce;			//共晶压力(为0时抬起吸嘴)
		LONG lDelay;			//共晶延时
		double dLimitUp;		//允许温度误差上限
		double dLimitDown;		//允许温度误差下限
		double dMoveRangeX;		//共晶台在共晶时移动范围X
		double dMoveRangeY;		//共晶台在共晶时移动范围Y
		BOOL bVacuumOff;		//关真空
	}TEMPERATURE_LIST_STRUCT;

	class DLL_PRODUCT_API CProduct : public CDataBaseOperate
	{
	public:
		CProduct(string strDbPath);
	private:
		LONG SaveDB() override;
		LONG LoadDB() override;

#pragma region Program_DieMatrix 表
	private:
		std::vector<PROGRAM_DIE_MATRIX_STRUCT> m_VecDieMatrix;
		//加载用户编程数据表
		LONG LoadDieMatrix();
	public:
		LONG GetDieMatrix(UINT nModuleId, std::vector<PROGRAM_DIE_MATRIX_STRUCT>& vecDieMatrix);
		LONG GetDieMatrix(UINT iMatrixId, PROGRAM_DIE_MATRIX_STRUCT& stDieMatrix);
		LONG SetDieMatrix(std::vector<PROGRAM_DIE_MATRIX_STRUCT> stDieMatrix, bool bAppend = false);
#pragma endregion

#pragma region Program_WaferMatrix 表
	private:
		std::vector<PROGRAM_WAFER_MATRIX_STRUCT> m_VecWaferMatrix;
		//加载用户编程数据表
		LONG LoadWaferMatrix();
	public:
		std::vector<PROGRAM_WAFER_MATRIX_STRUCT> GetWaferMatrix() {	return m_VecWaferMatrix	;};

#pragma endregion

#pragma region Program_WaffleMatrix 表
	private:
		std::vector<PROGRAM_WAFFLE_MATRIX_STRUCT> m_VecWaffleMatrix;
		//加载用户编程数据表
		LONG LoadWaffleMatrix();
	public:
		std::vector<PROGRAM_WAFFLE_MATRIX_STRUCT> GetWaffleMatrix() { return m_VecWaffleMatrix; };

#pragma endregion

#pragma region Program_BondMatrix 表
	private:
		std::vector<PROGRAM_BOND_MATRIX_STRUCT> m_VecBondMatrix;
		//加载用户编程数据表
		LONG LoadBondMatrix();
	public:
		std::vector<PROGRAM_BOND_MATRIX_STRUCT> GetBondMatrix() { return m_VecBondMatrix; };

#pragma endregion

#pragma region Program_PointMatrix 表
	private:
		std::vector<PROGRAM_POINT_MATRIX_STRUCT> m_VecPointMatrix;
		//加载用户编程数据表
		LONG LoadPointMatrix();
	public:
		LONG GetPointMatrix(UINT iMatrixId, PROGRAM_POINT_MATRIX_STRUCT& stPointMatrix);

#pragma endregion

#pragma region Program_BondInfo 表
	private:
		std::vector<BOND_INFO_STRUCT> m_VecBondInfoData;
		//加载用户编程数据表
		LONG LoadBondInfoData();
	public:
		LONG GetBondInfoData(UINT iInfoId, BOND_INFO_STRUCT& stBondInfoData);

#pragma endregion

#pragma region Program_Param 表
	private:
		std::vector<PICKBOND_PARAM_STRUCT> m_VecBondParam;
		//加载用户编程数据表
		LONG LoadBondParam();
	public:
		LONG GetBondParam(UINT iParamId, PICKBOND_PARAM_STRUCT& stBondParam) ;

#pragma endregion

#pragma region Program_HeadTableMatrix 表
	private:
		PROGRAM_HEAD_TABLE_MATRIX_STRUCT m_VecHeadTableMatrix;
		//加载用户编程数据表
		LONG LoadHeadTable();
	public:
		PROGRAM_HEAD_TABLE_MATRIX_STRUCT GetHeadTableMatrix() { return m_VecHeadTableMatrix; };

#pragma endregion

#pragma region
	private:
		std::vector<OneDimMatrixInfo>  m_vetOneDimMatrix;
		LONG LoadOneMatrixInfo();
	public:
		LONG GetOneDimMatrixInfo(int matrixID, OneDimMatrixInfo& matrix);

#pragma endregion

#pragma region StepListDetail 表

	private:
		std::vector<STEP_DETAIL>  m_vecStepDetail;
		//获取Step动作及参数表
		LONG LoadStepListDetail();

	public:
		std::vector<STEP_DETAIL> GetStepListDetail(UINT iFunctionId);
		std::vector<STEP_DETAIL> GetStepListDetail() {return m_vecStepDetail;};
		
#pragma endregion

#pragma region StepPublicData 表
	private:
		vector<STEP_PUBLIC_DATA>  m_mapStepPublicData;

		LONG LoadStepPublicData();
		LONG SaveStepPublicData();
	public:
		vector<STEP_PUBLIC_DATA> GetStepPublicData() { return m_mapStepPublicData; };
		LONG SetStepPublicData(vector<STEP_PUBLIC_DATA> vecStepPublicData, bool bAppend = false);
		
#pragma endregion

	
#pragma region PR_Strategy 表
	private:
		std::vector<PR_STRATEGY>  m_vecPrStrategy;

		LONG LoadPrStrategy();
		LONG SavePrStrategy();
	public:
		std::vector<PR_STRATEGY>  GetPrStrategy() { return m_vecPrStrategy; };
		LONG AddPrStrategy(vector<UINT> vecTemplateId);
#pragma endregion
	

#pragma region PR_Template 表
	private:
		std::vector<PR_TEMPLATE>  m_vecPrTemplate;

		LONG LoadPrTemplate();
		LONG SavePrTemplate();
	public:
		std::vector<PR_TEMPLATE>  GetPrTemplate() { return m_vecPrTemplate; };
		LONG AddPrTemplate(PR_TEMPLATE stTemplate);
#pragma endregion
		

	};



}