#pragma once
#include "CCalib.h"

/**
 * @class CRCalib
 * �̳��� CCalib �� R ��궨�࣬����ʵ�� R ��ı궨����
 *  1����Ҫ����ɾŵ�궨
 */



struct CALIB_R_PARAM {
    double dCalibPosX = 0;
    double dCalibPosY = 0;
    double dGrabPosZ = 0;                                     //����λ
    int nTempId = 0;
    double dStartAngle = -40;                                 //�궨ʱ�Ƕ�����
    double dEndAngle = 40;                                  //�궨ʱ�Ƕ�����
    int nRotationNum = 10;                                     //��ת����

    XY_DOUBLE_STRUCT stRotateCenter = { 0,0 };                //��ת����
    double dRad = 0;                                              //��ת�뾶
};


//����ģʽ
class __declspec(dllexport) CRCalib : public CCalib {
public:
    /**
     * @enum RCalibType 
     * @brief ���� R ��궨������
     */
    enum RCalibType {
        StepCalib,             // �����궨
        RotationCenterCalib    // ��ת���ı궨
    };

    /**
     * @brief ���캯��
     * @param GetModuleType ģ�����ͣ����ڱ�ʶ��ͬ��ģ��
     * @param GetModuleName ģ�����ƣ��������ֲ�ͬ��ģ��
     */
    CRCalib(int GetModuleType, string GetModuleName);

    /**
     * @brief ��������
     */
    ~CRCalib() {}

    /**
     * @brief ��ʼ�궨����
     * @return �궨�����ķ���ֵ��ͨ�� 0 ��ʾ�ɹ����� 0 ��ʾʧ��
     * @override ��д����Ĵ��麯��
     */
    virtual int StartCalib() override;

    /**
     * @brief ���ñ궨����
     * @override ��д����Ĵ��麯��
     */
    virtual void SetParam() override;

    /**
     * @brief �����ݿ�������м��ر궨����
     * @override ��д����Ĵ��麯��
     */
    virtual LONG GetParam() override;

    /**
     * @brief ��ȡ��ת����
     * @param center �������ת�������꣬ͨ�����ô���
     * @return ���������OK ��ʾ�ɹ���FAIL ��ʾʧ��
     */
    LONG GetCenter(XY_DOUBLE_STRUCT& center) {
        // �����ת���������Ƿ�Ϊ (0, 0)��������򷵻� FAIL
        if (m_stCalibParam_R.stRotateCenter.x == 0 && m_stCalibParam_R.stRotateCenter.y == 0) {
            return FAIL;
        }
        // ����ת�������긳ֵ���������
        center = m_stCalibParam_R.stRotateCenter;
        return OK;
    }

    /**
     * @brief ���ݽǶȻ�ȡƫ����
     * @param dAngle ����ĽǶ�
     * @param stCoefficient_R �����ƫ���������ͨ�����ô���
     * @return ���������LONG ���ͣ�ͨ�� 0 ��ʾ�ɹ����� 0 ��ʾʧ��
     */
    LONG GetOffsetByAngle(double dAngle, Step_RCalib_Result& stCoefficient_R);

    /**
     * @brief ����궨���
     * @return ���������LONG ���ͣ�ͨ�� 0 ��ʾ�ɹ����� 0 ��ʾʧ��
     */
    LONG CalResult();

    /**
     * @brief ������תƫ����
     * @param angle �������ת�Ƕ�
     * @param dx ����� X ����ƫ������ͨ�����ô���
     * @param dy ����� Y ����ƫ������ͨ�����ô���
     * @return ���������LONG ���ͣ�ͨ�� 0 ��ʾ�ɹ����� 0 ��ʾʧ��
     */
    LONG CalRotationOffset(double angle, double& dx, double& dy);

    /**
     * @brief ��������תλ��
     * @param point �����ԭʼ������
     * @param rotationRad �������ת����
     * @param rotatedPoint �������ת��ĵ����꣬ͨ�����ô���
     * @return ����������������ͣ�true ��ʾ�ɹ���false ��ʾʧ��
     */
    bool rotationPos(const XY_DOUBLE_STRUCT& point, const double& rotationRad, XY_DOUBLE_STRUCT& rotatedPoint);
	
    //������ת����
    void SetCenter(XY_DOUBLE_STRUCT center) { 
        m_stCalibParam_R.stRotateCenter = center;
        SetParam();
    }

    //���þŵ�궨����
    void SetXYCalib(CXYCalib* calib) {
        m_pXYCalib = calib;
    }

    //���浱ǰ�궨��ʹ�õ�����
    void SetTempID(int tempID) { 
        m_stCalibParam_R.nTempId = tempID;
        SetParam();
    }

    //��ñ궨����
    CALIB_R_PARAM GetCalibParam() { return m_stCalibParam_R; }

    LONG MoveToCalibPos();

    LONG CalibTest();


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

private:
    const int ROT_NUM = 8;  // ��ת���յĴ���

    vector<MODULE_CONFIG_STRUCT> m_vecConfigStruct;

    vector<Point2D> m_vetRotatinPoints;  // ��ת���ս�����洢��ת��ĵ�����
    vector<double> m_vetRadius;          // ����뾶�����ڲ�ֵ����
    vector<double> m_vetAngle;           // ����Ƕȣ����ڲ�ֵ����
    //CALIB_R m_stCalibR;                  // R ��궨����ز����ṹ��
    CALIB_R_PARAM m_stCalibParam_R;

    RCalibType m_calibType = RotationCenterCalib;  // �궨��ʽ��Ĭ��Ϊ��ת���ı궨
    //DOUBLE m_dAngleStep = 1;                        // �궨ʱ��ת�Ƕȣ��Ƕȵ�λ
    //DOUBLE m_dAngleLower = -90;                     // �궨ʱ�Ƕ�����
    //DOUBLE m_dAngleUpper = 90;                      // �궨ʱ�Ƕ�����
    vector<Step_RCalib_Result> m_stVetCalib_R;      // R ��궨������洢ÿ�α궨�Ľ��
    CXYCalib* m_pXYCalib = nullptr;
};