#ifndef CLASERPATH_H
#define CLASERPATH_H

#include "export_laser_path_driver_diodes.h"
#include "CChannel.h"
#include "macro_def.h"
#include <QPair>
/*!
 * 指定宽度索引，关联的玻片参数
 *
 */
struct DIndexParam
{
    double dAngle1;
    double dAngle2;
    DIndexParam()
    {
        dAngle1 = 0;   //关联工艺轴1的功率角度
        dAngle2 = 0;   //关联工艺轴2的功率角度
    }
};

//! 记录测量的功率,每个频率下一个测量数据
struct PowerParamIndex
{
    double dIndex;
    double dPower;
    double dPower_RT;
    PowerParamIndex()
    {
        dIndex = 0;         //半玻片，衰减器，或Epulse参数，或挡板位置
        dPower = 0;         //测量的功率值
        dPower_RT = 0;      //???
    }
};

/**
 * @brief 功率测量的索引值.
 */
struct CPowerIndex
{
    int iFreq;      //! 频率KHz
    int iEpulse;    //! Epulse(Hz)
    int iWidth;     //! 光斑宽度(um)
    CPowerIndex()
    {
        iFreq = 0;
        iEpulse = 0;
        iWidth = 0;
    }
    CPowerIndex(const CPowerIndex& pt)
    {
        if (this == &pt)
        {
            return;
        }
        this->iFreq = pt.iFreq;
        this->iEpulse = pt.iEpulse;
        this->iWidth = pt.iWidth;
    }

    CPowerIndex(int iFreq, int iEpulse, int iWidth)
    {
        this->iFreq = iFreq;
        this->iEpulse = iEpulse;
        this->iWidth = iWidth;
    }

    bool operator ==(const CPowerIndex& pt)
    {
        return DEQUAL0(this->iFreq - pt.iFreq)
            && DEQUAL0(this->iEpulse - pt.iEpulse)
            && DEQUAL0(this->iWidth - pt.iWidth);
    }
    CPowerIndex& operator = (const CPowerIndex& pt)
    {
        if (this == &pt)
        {
            return*this;
        }
        this->iFreq = pt.iFreq;
        this->iEpulse = pt.iEpulse;
        this->iWidth = pt.iWidth;
        return *this;
    }
};

/**
 * @brief 光路控制的索引值.
 */
struct CMPathIndex
{
    CMPathIndex(int iFirst, int iSecond) :
        iFirstIndex(iFirst), iSecondIndx(iSecond)
    {

    }
    CMPathIndex() :
        iFirstIndex(0), iSecondIndx(0)
    {

    }
    CMPathIndex(const CMPathIndex& pt)
    {
        if (this == &pt)
        {
            return;
        }
        this->iFirstIndex = pt.iFirstIndex;
        this->iSecondIndx = pt.iSecondIndx;
    }
    int iFirstIndex;
    int iSecondIndx;
    bool operator ==(const CMPathIndex& pt)
    {
        return DEQUAL0(this->iFirstIndex - pt.iFirstIndex) && DEQUAL0(this->iSecondIndx - pt.iSecondIndx);
    }
    CMPathIndex& operator = (const CMPathIndex& pt)
    {
        if (this == &pt)
        {
            return*this;
        }
        this->iFirstIndex = pt.iFirstIndex;
        this->iSecondIndx = pt.iSecondIndx;
        return *this;
    }
};

/*!
* 指定宽度索引，关联的玻片参数
*
*/
struct DBeamWideScale
{
    double dWide;
    double dPower;
    double dScale;
    int iFreq;
    int iEpulse;
    DBeamWideScale()
    {
        dWide = 0;
        dPower = 0;
        dScale = 0;
        iFreq = 0;
        iEpulse = 0;
    }
};

/**
 * @brief 功率测量数据.
 */
using POWERPOSVECTOR = QMMutexVector<PowerParamIndex>;
using BEAMPOSVECTOR = QMMutexVector<DBeamWideScale>;
/**
 * @brief 功率测量数据.
 */
using CALIMAP = QMMutexVector<QPair<CPowerIndex, POWERPOSVECTOR>>;
using CALIBEAMMAP = QMMutexVector<QPair<CPowerIndex, BEAMPOSVECTOR>>;
/**
 * @brief 光班宽度，对应的两个玻片值，用于调整到光斑大小.
 */
using DINDEXVECTOR = QVector<QPair<int, DIndexParam> >;
/**
 * @brief 光斑偏移，固定光斑宽度下，对应的Offset值.
 */
using LPATHOFFSETVECTOR = QVector<QPair<CMPathIndex, double> >;
/**
 * @brief 光斑宽度，对应的挡板位置.
 */
using LPATHBEAMPOSMAP = QMap<int32_t, float64_t>;

//光路
class LASER_PATH_DRIVER_DIODES_EXPORT CLaserPath : public CChannel
{
public:
    CLaserPath(const QString& name, int32_t id);
    ~CLaserPath();

    DINDEXVECTOR        m_vDIndexParam; //!光路关联的宽度对应的角度
    LPATHOFFSETVECTOR	m_vOffset;	    //!光路偏移补偿
    LPATHBEAMPOSMAP     m_mBeamPos;     //!档板位置

    //功率点检数据
    CALIMAP             m_mPowerCali;
    //当前关联的功率数据
    POWERPOSVECTOR      m_vPowerPos;	//!半玻片角度对应的功率

#ifdef __USE_LASER_BAEM__POWER__
    CALIBEAMMAP         m_mBeamCali;
    //!光路关联的宽度对应的比例因子
    BEAMPOSVECTOR       m_vScaleParam;
#endif
public:
    QDomElement WriteConfig(QDomDocument& doc, QDomElement& root);
    int ReadConfig(QDomElement& root);

    /**
     * @brief 写入功率数据.序列化方式
     * @deprecated
     * @sa WriteBeamPosMapCsv
     */
    virtual void WritePowerPosMap();
    /**
     * @brief 读取功率数据.
     * @deprecated
     * @sa WriteBeamPosMapCsv
     */
    virtual void ReadPowerPosMap();

    virtual void WritePowerPosMapCsv();


    virtual bool ReadPowerPosCsv();
    virtual void WritePowerPosVectorCsv();

    //读取Index关联数据
    //virtual void ReadDIndexParamVector();
    //virtual void WriteDIndexParamVector();

    /**
     * \brief 读取Index关联数据.
     *
     * \return
     */
    virtual bool ReadDIndexParamVectorCsv();
    virtual void WriteDIndexParamVectorCsv();

    /**
     * @brief 读取Offset数据.
     *
     */
    virtual void ReadOffsetVector();
    virtual void WriteOffsetVector();

    /**
     * @brief 写入档板位置数据.
     *
     */
    virtual void WriteBeamPosMapCsv();
    /**
     * @brief 读取档板位置数据.
     *
     */
    virtual void ReadBeamPosMapCsv();
public:
    bool GetLineWidthParam(double dWidth, DIndexParam& param);
public:
    virtual int SetOffset(double dDIndex, double dSIndex, double dOffset);
    virtual int GetOffset(double dDIndex, double dSIndex, double& dOffset);
public:
    int SetOffset(double dOffset);
    int GetOffset(double& dOffset);
public:
    /**
     * \brief 根据索引获取档板位置.索引为小数，实际为【索引*1000】
     *
     * \param dSIndex
     * \return
     */
    virtual double GetBeamPos(double dBeamWidth);
    /**
     * \brief 添加档板位置.
     *
     * \param dBeamWidth
     * \param dPos
     */
    virtual void	AddToBeamPosMap(double dBeamWidth, double dPos);
    virtual void	DelFromBeamPosMap(double dBeamWidth);

public: //reserved
    //int AddDIndexParamToVector(double dDIndex, double dAngle);
    //double CalcuSIndexAngle(double dSIndex);
#ifdef __USE_LASER_BAEM__POWER__
    /**
    * \brief 读取Scale关联数据.
    *
    * \return
    */
    virtual bool ReadBeamWideScaleCsv();
    virtual void WriteBeamWideScaleCsv();
    /**
    * @brief 写入功率数据.序列化方式
    * @deprecated
    * @sa WriteBeamPosMapCsv
    */
    virtual void WriteBeamScaleMap();
    /**
    * @brief 读取功率数据.
    * @deprecated
    * @sa WriteBeamPosMapCsv
    */
    virtual void ReadBeamScaleMap();
    virtual bool FindBeamPosVector(int iFreq, int iEpulse, double dBeamWidth, BEAMPOSVECTOR& vector);
    virtual void	AddToBeamWidePower(int iFreq, int iEpulse, double dBeamWidth, double dPower);
    virtual bool AddBeamPosVector(int iFreq, int iEpulse, double dBeamWidth, BEAMPOSVECTOR& vector);
    double CalcuPowerToAngle(int iFreq, int iEpulse, double dBeamWidth, double dPower);
#endif
public:
    /*virtual bool FindPowerPosVector(const CPowerIndex& powerIndex, POWERPOSVECTOR& vector);
    virtual bool AddPowerPosVector(const CPowerIndex& powerIndex, POWERPOSVECTOR& vector);
    virtual double PowerToAngle(const CPowerIndex& powerIndex, double dPower);*/

    virtual bool FindPowerPosVector(int iFreq, int iEpulse, double dBeamWidth, POWERPOSVECTOR& vector);
    virtual bool AddPowerPosVector(int iFreq, int iEpulse, double dBeamWidth, POWERPOSVECTOR& vector);
    virtual double PowerToAngle(int iFreq, int iEpulse, double dBeamWidth, double dPower);
private:
    //单光路偏移
    double m_LaserOffsetY;

    QString GetFilePath(QString sFileName);

};

#endif // CLASERPATH_H
