#pragma once
#include "CCalib.h"

/**
 * @class CRCalib
 * �̳��� CCalib �� R ��궨�࣬����ʵ�� R ��ı궨����
 *  1����Ҫ����ɾŵ�궨
 */
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_stCalibR.m_stRotateCenter.x == 0 && m_stCalibR.m_stRotateCenter.y == 0) {
            return FAIL;
        }
        // ����ת�������긳ֵ���������
        center = m_stCalibR.m_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_stCalibR.m_stRotateCenter = center; 
        SetParam();
    }

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

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

    //��ñ궨����
    CALIB_R GetCalibParam() { return m_stCalibR; }

    LONG MoveToCalibPos();

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

    vector<Point2D> m_vetRotatinPoints;  // ��ת���ս�����洢��ת��ĵ�����
    vector<double> m_vetRadius;          // ����뾶�����ڲ�ֵ����
    vector<double> m_vetAngle;           // ����Ƕȣ����ڲ�ֵ����
    CALIB_R m_stCalibR;                  // 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;
};