#pragma once
#include "CManageDB.h"
#include <map>
#include <mutex>

#ifdef BOND_MATRIX_EXPORTS
#define BOND_CMATRIX_DLL_API __declspec(dllexport)
#else
#define BOND_CMATRIX_DLL_API //__declspec(dllimport)
#endif

using namespace ns_db;

namespace ns_mat
{
	typedef struct
	{
		PICKBOND_PARAM_STRUCT stWaferParam;		//��Ƭ̨\�����ȡ������
		PICKBOND_PARAM_STRUCT stCalibBondParam;	//У׼̨�ž�����
		UINT nTemplate_Pick;					//ȡ��ģ���
		UINT nPickHeadIdByTable;				//ȡ��������������ϵ�Id��
		UINT nMatrixId;						//ʹ�õľ�Ƭ̨\����кţ�����ţ�
	}PICK_PARAM;

	typedef struct
	{
		//�̾��������õ������ݣ������û����ã��豣�浽���ݿ�IJ���
		PICKBOND_PARAM_STRUCT stCalibPickParam;		//У׼̨ȡ������
		PICKBOND_PARAM_STRUCT stBondParam;			//�̾�̨�̾�����

		UINT nTemplate_BondFront;					//��ǰ���ģ��ID�� 0Ϊ�����
		UINT nTemplate_BondBack;					//�̺���ģ��ID�� 0Ϊ�����
		//UINT nTemplate_SearchModel;					//��ģ��λ�ú��Ƿ����� 0Ϊ������
		UINT nTemplate_Bond;						//�̾���Ե�ģ��ID�� 
		UINT nTemplate_Calib;						//��ת̨У׼ģ���  0Ϊ������
		UINT nTemplate_LookUp;						//���ӶԵ�ģ���    0Ϊ������

		UINT nBondHeadIdByTable;					//�̾�������������ϵ�Id��

		X_Y_ANGLE_STRUCT stOffset;					//�̾��㲹��(�ӱ�̵Ĺ̾���λ��ƫ��)
	}BOND_PARAM;

	//�̾����������������õõ�
	typedef struct
	{
		//ȫ�ְ��յIJ���
		UINT iPcbMatId;						//��Ӧ��pcb��
		CALIB_DIE_TYPE nCalibType;			//У׼��ʽ 0:��У׼  1:����У׼  2:У׼̨У׼
		DIE_SOURCE nWaffleOrWaffer;			//0������У�1����Բ̨
		PICK_PARAM nPickParam;
		BOND_PARAM nBondParam;
	}PROCESS_INFO_STRUCT;

	//�̾�˳��
	enum BOND_DIR {
		//order˳�򣬰��ձ���������һ������С�����ٱ����ڶ���
		//Alternate˳�򣬰��ձ�������ͬ��С�����ٱ����ڶ���С����
		OrderAndS = 0,/*������*/
		AlternateAndZ = 1,
		OrderAndZ = 2,/*֮����*/
		AlternateAndS = 3,
	};

	typedef struct _BOND_INDEX_STRUCT
	{
		//UINT iProductId = 1;			//�̾������ڲ�ƷId
		UINT iPcbMatId = 1;				//�̾�������PCB Id
		UINT iPcbRow = 1;				//�̾�����PCB��������
		UINT iPcbCol = 1;				//�̾�����PCB��������
		UINT iPtMatId = 1;				//�̾�������Pt����Id
		UINT iPtRow = 1;				//�̾����ھ�����������
		UINT iPtCol = 1;				//�̾����ھ�����������
		UINT iIndex = 1;				//��ǰPoint������Bond�����е����
	} BOND_MATRIX_POINT_INFO_STRUCT; //�̾���

	enum DIE_STATUS {
		//NO_PICK = 0,			/*δȡ��*/
		//WAF_PICK_DONE,				/*�ѴӾ�Ƭ̨ȡ��*/
		//TRANSFER_BOND_DONE,			/*�ѽ���Ƭ�ŵ���ת̨*/
		NO_BOND,					//δ����̾�״̬
		TRANSFER_PICK_DONE,			/*�Ѵ���ת̨ȡ��*/
		LOOKUP_CALIB_DONE,			/*������У׼*/
		BOND_DONE,				/*�ѹ̾�*/
		BOND_DEL				/*���̾���*/
	};
	enum PICK_STATUS
	{
		NO_PICK = 0, /*δȡ��*/
		WAF_PICK_DONE,	/*�ѴӾ�Ƭ̨ȡ��*/
		TRANSFER_BOND_DONE,			/*�ѽ���Ƭ�ŵ���ת̨*/
	};

	//���̲����Ĺ�������
	typedef struct _BONDED_STATUS_STRUCT
	{
		//���̹����е�״̬���ݣ������浽���ݿ���
		DIE_STATUS bDieStatus;				//�̾�״̬
		PICK_STATUS bPickStatus;			//ȡ��״̬
		bool bAlnStatus;					//�Ե�״̬,�Ƿ��ѶԵ�
		bool bIsCheck;						//�Ƿ�̺������

		X_Y_ANGLE_STRUCT stLookUpOffset;	//��������ƫ����
		XY_DOUBLE_STRUCT stSetBondPosition;	//�������õĹ̾�λ��
		XY_DOUBLE_STRUCT stAlnBondPosition;	//�Ե��Ĺ̾�λ��
		XY_DOUBLE_STRUCT stAlnOffset;		//�̾���Ե�ƫ��
		double dAlnAngle;					//�Ե�Ƕ�
		XY_DOUBLE_STRUCT stCheckOffset;		//�̺�����
		double dCheckAngle;					//�̺���Ƕ� 

		_BONDED_STATUS_STRUCT()
		{
			bDieStatus = NO_BOND;
			bPickStatus = NO_PICK;
			bAlnStatus = false;
			bIsCheck = false;
			stSetBondPosition = 0;
			stAlnBondPosition = 0;
			dAlnAngle = 0;
			dCheckAngle = 0;
			stCheckOffset = 0.0;
		}
	} BOND_STATUS_STRUCT;

	typedef struct _POINT_INFO_STRUCT
	{
		BOND_MATRIX_POINT_INFO_STRUCT stIndex;
		BOND_STATUS_STRUCT stBondStatus;
		PROCESS_INFO_STRUCT stBondInfo;
	} POINT_INFO_STRUCT;


	/// <summary>
	/// �̾���ȡ�����λ����Ϣ
	/// </summary>
	class BOND_CMATRIX_DLL_API  CBondMatrix
	{
		//enum type { pick, bond };
	private:
		static std::mutex m_MatrixMutex;
		bool bIsInitSuccess = false;

		//��ǰ��
		//UINT m_iCurrentBondIndex = 0;
		//��������
		UINT m_iBondAmount = 0;
		int m_iWaferDieNum = 0;
		int m_iWaffleDieNum = 0;

		BOND_DIR m_eBondDir = BOND_DIR::OrderAndS;

		CProduct* m_pCProduct = nullptr;

		vector<PROGRAM_BOND_MATRIX_STRUCT> m_vetBondMatrix;				//Pcb����,�����ݿ������δ������������
		map<int, POINT_INFO_STRUCT> m_mapBondMatrixInfo;

		void Sort_OrderAndZ();
		void Sort_AlternateAndZ();
		void Sort_OrderAndS();
		void Sort_AlternateAndS();

		POINT_INFO_STRUCT CalPointInfo(UINT iPtId, PROGRAM_BOND_MATRIX_STRUCT pcbMatrix, PROGRAM_POINT_MATRIX_STRUCT ptMatrix, 
			int pcbRow, int pcbCol, int pointRow, int pointCol);
		LONG BondInfoConvertPorcessInfo(UINT iPcbId, BOND_INFO_STRUCT stBondInfo, PROCESS_INFO_STRUCT& stProcessInfo);

		void ProcessPointMatrix(const PROGRAM_BOND_MATRIX_STRUCT& pcbMatrix, const PROGRAM_POINT_MATRIX_STRUCT& pointMatrix, int i, int j);
		//void RecvTableChangNoticeFunction(string dbname, string tabname);
	public:
		CBondMatrix();
		LONG LoadMatrix(BOND_DIR dir);

	public:
		//����0��ʾû�ҵ�
		//UINT GetCurrentIndex();							//��ȡ��ǰ�̾���
		//LONG SetCurrentIndex(UINT nIndex);				//���õ�ǰ�̾���

		//��ȡ������ǰ�̾��㿪ʼ���¸��̾���
		UINT GetNextBondIndex(UINT nIndex);							//��ȡ�ӵ�ǰ�̾��㿪ʼ���¸��̾���
		UINT GetPrevBondIndex(UINT nIndex);

		UINT GetNextPickIndex(UINT nIndex,DIE_SOURCE eSource = DIE_SOURCE::BY_NUL);							//��ȡ�ӵ�ǰ�̾��㿪ʼ���¸��̾���
		UINT GetPrevPickIndex(UINT nIndex, DIE_SOURCE eSource = DIE_SOURCE::BY_NUL);							//��ȡ�ӵ�ǰ�̾��㿪ʼ���ϸ��̾���

		UINT GetAmount();									//��ȡ����
		int GetWaferPickAmount();
		int GetWafflePickAmount();

		//��ȡָ����Բ��λ����Ϣ
		LONG GetPintInfoByIndex(UINT nPtIndex, POINT_INFO_STRUCT& stPointInfo);
		LONG SetPintInfoByIndex(UINT nPtIndex, POINT_INFO_STRUCT stPointInfo);

		LONG GetAllBondParam(UINT nPtIndex,BOND_PARAM& bondParam);
		LONG GetAllPickParam(UINT nPtIndex, PICK_PARAM& pickParam);

		LONG SetBondParam(int nPtIndex, BOND_PARAM bondParam);
		LONG SetPickParam(int nPtIndex, PICK_PARAM pickParam);

		/// <summary>
		/// ���ù̾���Ե���Ϣ������ʱ���̾�������Ӧ�͵�PCBһ�����ò�����Ե��λ��
		/// </summary>
		/// <param name="nPtIndex">�̾�����</param>
		/// <param name="stBasePosn">��׼λ��</param>
		/// <param name="dBaseAngle">��׼�Ƕ�</param>
		/// <param name="stAlnPosn">�Ե�λ��</param>
		/// <param name="dAlnAngle">�Ե�Ƕ�</param>
		/// <returns></returns>
		LONG SetBondAlnInfo(UINT nPtIndex, XY_DOUBLE_STRUCT stBasePosn, DOUBLE dBaseAngle, XY_DOUBLE_STRUCT stAlnPosn, DOUBLE dAlnAngle);
		
		LONG SetBondAlnOffset(int index, X_Y_ANGLE_STRUCT offset);
		LONG SetLookupOffset(int index, X_Y_ANGLE_STRUCT offset);
		LONG ResetAlnStatus(UINT nPtIndex);										//����Ե�״̬���̾���������Ӧ��PCBһ�����

		LONG SetDieStatus(UINT nPtIndex, DIE_STATUS eStatus);					//���ù̾�״̬
		LONG SetPickStatus(UINT nPtIndex, PICK_STATUS eStatus);					//����ȡ��״̬

		LONG ClearWaferPickStatus();

		LONG ClearWafflePickStatus();

		LONG ClearAllBondInfo();												//������й̾����״̬����Ϣ

	};

}