#pragma once
#include "CModule.h"
#include "CCameraBase.h"
#include "CRCalib.h"
#include "CXYCalib.h"
#include "HorizMeasure.h"


enum SOFTLIMITTYPE { SL_NONE = 0, SL_CIRCLE, SL_RECT }; //SL_NONE: ��ʹ��, SL_CIRCLE: Բ�η�Χ��λ, SL_RECT: ���η�Χ��λ
enum SEARCH_DIRECTION { WAF_LEFT = 0, WAF_DOWN, WAF_RIGHT, WAF_UP, WAF_MAX };
enum FIND_DIE { U_L = 0, U_C, U_R, C_L, C_C, C_R, D_L, D_C, D_R, MAX };
typedef struct
{
    X_Y_R_STRUCT stCurPickPosn;			//��Ƭ̨��ǰȡ��λ��
    DOUBLE dDistanceX;					//��Ƭ̨�Ͼ�Ƭ���X
    DOUBLE dDistanceY;                  //��Ƭ̨�Ͼ�Ƭ���Y
    SEARCH_DIRECTION enDirMain;			//��ѡ��������
    SEARCH_DIRECTION enDirMinor;		//��ѡ��������
}WAFER_SEARCHDIE;

typedef struct _SAVE_FIND_DIE
{
    bool bUse;
    X_Y_R_STRUCT stPosition;
    _SAVE_FIND_DIE()
    {
        bUse = false;
        stPosition = { 0.0,0.0,0.0 };
    }
}SAVE_FIND_DIE;



class __declspec(dllexport) CWaferTable :  public CModule
{

#define SAVE_DIE_POSITION_CONUT 3

    typedef struct
    {
        bool UseMatrix;				                //�������þ����ȡ����ʽ
        MATRIX_SEARCH_DIR SearchMatrixDir;          //�Ѿ���˳��
        UINT TemplateId;				            //�Ѿ�����ģ��
        UINT DelayTakePicture;			            //��ͼ��ʱ
        UINT LoseDieCount;                          //��Ƭ̨ʧ����������Ѱ��һ�ž�Ƭʱ�������Ҳ���LoseDieCount�ž�Ƭ���л򱨾�
        UINT PickDieAgainNum;			            //�ظ�ȡ������
        UINT ForecastCount;			                //��ǰ�澯����

        X_Y_Z_R_STRUCT SafePosition;                //��ȫλ��
        X_Y_Z_R_STRUCT DownRingPosition;            //�ϡ��¾���λ��

        XY_DOUBLE_STRUCT stWorkRangeCenter;         //��������
        DOUBLE dSoftLimitRadius;			        //3�㻭Բ����λ�뾶(Բ�ľ�����ת����)
        SOFTLIMITTYPE enSoftLimitType;              //�Ƿ�ʹ��3�㻭Բ������λ,һ�������ֻ��ʹ����Ĥ�ľ�Ƭ̨ʹ��
    } WAFERTABLE_CONFIG_STRUCT;     //��Ƭ̨��������

public:
    CWaferTable(MODULE_LIST eModuleType);
    ~CWaferTable(){}
    void SetCamera(CCameraBase* camera) { m_pCamera = camera; }

    virtual LONG AllocateAxis(vector<CAxis*> vecAxis) override;
    virtual LONG AllocateIo(vector<CIO*> vecIo) override;

    void SetCoord(CCoord* pCrd) { m_pCoord = pCrd; }

    CXYCalib* GetWaferXYCalib() { return m_pXYCalib; }
    CRCalib* GetWaferRCalib() { return m_pRCalib; }

    virtual LONG ToHome() override;
    virtual LONG Sync() override;
    virtual LONG ToSafePosition() override;
    virtual LONG InitResource() override;

    //����ʼ��Ƭλ��
    LONG ToFirstDie();
    //ȥ����һ�ž�Ƭλ��
    LONG ToPreDie();
    //ȥ����һ�ž�Ƭλ��
    LONG ToNextDie();
    //ȥ��ָ����ŵľ�Ƭλ��
    LONG ToIndexDie(UINT nIndex);
    //������ǰ��Ƭ����
    LONG ToDieCenter();
    //����оƬ
    LONG SearchDie();

    //�����¾���λ��
    LONG ToChangeRingPosition();
    //�����������
    LONG ChangeRingDone();

    //����3�㻭Բ����λ�İ뾶��Բ��(Բ�ľ�����ת����)
    LONG SetSoftLimitRadius(SOFTLIMITTYPE nSoftLimitType, XY_LONG_STRUCT stPosn1, XY_LONG_STRUCT stPosn2, XY_LONG_STRUCT stPosn3);

    LONG CreateTemplate(SEARCH_OUT eResultSelect, UINT& iTemplateId);
    LONG CreatePrStrategy(vector<UINT> vecTemplateId);
private:
    CAxis* m_pXAxis = nullptr;
    CAxis* m_pYAxis = nullptr;
    CAxis* m_pZAxis = nullptr;
    CAxis* m_pRAxis = nullptr;

    CIO* m_pRingDone = nullptr;

    CCameraBase* m_pCamera = nullptr;
    CCoord* m_pCoord = nullptr;
    CXYCalib* m_pXYCalib = nullptr;
    CRCalib* m_pRCalib = nullptr;
    CHorizMeasure* m_pHorizMeasure = nullptr;
    CPRStrategy* m_pPR = nullptr;

    CProduct* m_pCProduct = nullptr;
    CWaferMatrix* m_pWaferMatrix = nullptr;

    //��Ƭ̨����
    WAFERTABLE_CONFIG_STRUCT m_stConfig;
    WAFER_SEARCHDIE m_stSearchDie;

private:
    void DataChangNotice(string strDbName, string strTableName);

    virtual void SetDataChangFunction() override;
    virtual LONG SetParam() override;//��������
    virtual LONG GetParam() override;//��������

    //Z����
    LONG AxisZ_Up();
    //Z����
    LONG AxisZ_Down();
    //Z������������λλ�á�������ڣ����ֹ��Ƭ̨�ƶ�
    bool AxisZIsDown();

    LONG MoveTo(double x, double y, bool bSync = true);
    LONG MoveTo(double dX,double dY,double dR, bool bSync = true);
    LONG Move(double dX, double dY, double dR, bool bSync = true);

    bool bChangDirMain;		//�Ƿ��������������
    //��¼���ҵ���Ƭ�ľ���λ��
    SAVE_FIND_DIE m_SaveDiePosition[SAVE_DIE_POSITION_CONUT];//�������ŷ��򷽵ľ�Ƭλ��
    void ChangeCurrentPickPosition();
    void ChangeDirMain();			//�޸�����������
    //ѡ���¿ž�Ƭλ��
    FIND_DIE SelectNextDiePos(FIND_OUTPUT_STRUCT arrayDie[]);
    void CalcSearchDiePosition(X_Y_R_STRUCT stCurrentPosition, FIND_OUTPUT_STRUCT DiePosition, SAVE_FIND_DIE& OutPosition);
    void SaveSearchDiePosition(X_Y_R_STRUCT stCurrentPosition, FIND_OUTPUT_STRUCT ArrayDie[FIND_DIE::MAX]);
    //�ж�Ŀ��λ���Ƿ��ڷ�Χ��  true:�ڷ�Χ��   false:�ڷ�Χ��
    bool CheckPurPosnInRange(XY_DOUBLE_STRUCT stPurPosn);
};