#ifndef __FIGURE_H__
#define __FIGURE_H__

// *****************************************************************************
// 版权所有(C)2023~2099 上海骄成超声波技术有限公司
// 保留所有权利
// *****************************************************************************
// 作者 : 严寒
// 版本 : 1.0
// 代码创建日期:2025/01/10
// 版本更新日期:2025/01/10
// 功能说明:视觉窗口中可拖动的几何类型实现。
// *****************************************************************************

#include "TypeDef.h"
//#include "qlist.h"

class BaseItem;
class QPointF;
template <typename T>
class QList;

namespace JVision
{
	/** @brief 图形类型的枚举体 */
	enum class JVision_API E_FIGURE_TYPE : int
	{
		E_AUTO_FIGURE = 0,				/**< 自定义类型 */

		E_CIRCLE,					    /**< 圆 */
		E_CONCENTRIC_CIRCLE,		    /**< 同心圆 */
		E_RECTANGLE,			        /**< 矩形  */
		E_RECTANGLE_R,				    /**< 旋转矩形 */
		E_CONCENTRIC_RECTANGLE,         /**< 同心矩形 */
		E_LINE_OBJ,					    /**< 直线 */
		E_CALIPERS,						/**< 卡尺 */
		E_POLYGEN,                      /**< 多边形 */
	};

	/** @brief 图形的枚举体 */
	struct JVision_API BaseFigure
	{
		// 这个后面需要删除
		BaseItem* ConvertBaseItem() { return nullptr; }

		/**
		* @brief 获取图形名
		* @param[in] type 图形类型
		* @return std::string 图形名的中文名称
		*/
		static std::string GetFigureNameCN(E_FIGURE_TYPE type);

		/**
		* @brief 创建图形
		* @param[in] type 图形类型
		* @return BaseFigure* 图形指针
		*/
		static BaseFigure* Create(E_FIGURE_TYPE type);

		/**
		* @brief 销毁图形
		* @param[in] *data 图形指针
		*/
		static void Destroy(BaseFigure* data);

		/**
		* @brief 两图形间是否相等
		* @param[in] *figure_1 图形指针1
		* @param[in] *figure_2 图形指针2
		* @return bool 两图形间相同则返回true
		*/
		static bool FigureIsEqual(const BaseFigure* figure_1, const BaseFigure* figure_2);

		/**
		* @brief 拷贝图形
		* @param[in] *figure_1 拷贝的图形指针
		* @param[in] *figure_2 待拷贝的图形指针
		* @return bool 是否拷贝成功,成功返回true
		*/
		static bool CopyData(BaseFigure* figure_1, BaseFigure* figure_2);

		/**
		* @brief 序列化图形参数
		* @return std::string 图形序列化的参数字符串
		*/
		virtual std::string serializeJSON() = 0;

		/**
		* @brief 反序列化图形参数
		* @param[in] *figure_1 图形序列化的参数字符串
		* @return bool 是否反序列化成功,成功返回true
		*/
		virtual bool DeserializeJSON(const std::string jsonStr) = 0;

		/**
		* @brief 构造函数
		* @param[in] _type 图形类型
		*/
		BaseFigure(E_FIGURE_TYPE _type);

		E_FIGURE_TYPE type;		        /** @brief 图形类型的枚举体 */
		static const double epsilon;    /** @brief 精度, 用于比较浮点数的误差 */ // 
	};

	/** @brief 圆参数 */
	struct JVision_API Circle : public BaseFigure
	{
		/**
		* @brief 圆构造函数
		*/
		Circle();

		/**
		* @brief 圆构造函数
		* @param[in] _x 圆心列坐标
		* @param[in] _y 圆心行坐标
		* @param[in] _radius 圆半径
		*/
		Circle(double _x, double _y, double _radius);

		/**
		* @brief 序列化圆参数接口
		* @return std::string 序列化的圆参数字符串
		*/
		std::string serializeJSON();

		/**
		* @brief 反序列化圆参数接口
		* @param[in] jsonStr 序列化的圆参数字符串
		* @return bool 是否反序列化成功,成功为true
		*/
		bool DeserializeJSON(const std::string jsonStr);

		/**
		* @brief 重载比较符号,比较传入的圆与本地的圆参数是否一致
		* @param[in] other 图形FIGURE
		* @return bool 是否一致,一致则为true
		*/
		bool operator==(const Circle& other) const;

		/**
		* @brief 拷贝一份圆图形
		* @param[in] * dst 待拷贝的圆图形
		* @return bool 是否拷贝成功,成功则为true
		*/
		bool Copy(Circle* dst);

		double x;		/** @brief 圆图形的列坐标 */
		double y;		/** @brief 圆图形的行坐标 */
		double radius;  /** @brief 圆图形的半径 */
	};

	/** @brief 同心圆参数 */
	struct JVision_API CCircle : public BaseFigure
	{
		/**
		* @brief 同心圆构造函数
		*/
		CCircle();

		/**
		* @brief 圆构造函数
		* @param[in] _x 圆心列坐标
		* @param[in] _y 圆心行坐标
		* @param[in] _small_radius 小圆半径
		* @param[in] _big_radius 大圆半径
		*/
		CCircle(double _x, double _y, double _small_radius, double _big_radius);

		/**
		* @brief 序列化同心圆参数接口
		* @return std::string 序列化的同心圆参数字符串
		*/
		std::string serializeJSON();

		/**
		* @brief 反序列化同心圆参数接口
		* @param[in] jsonStr 序列化的同心圆参数字符串
		* @return bool 是否反序列化成功,成功为true
		*/
		bool DeserializeJSON(const std::string jsonStr);

		/**
		* @brief 重载比较符号,比较传入的同心圆与本地的同心圆参数是否一致
		* @param[in] other 图形FIGURE
		* @return bool 是否一致,一致则为true
		*/
		bool operator==(const CCircle& other) const;

		/**
		* @brief 拷贝一份同心圆图形
		* @param[in] * dst 待拷贝的同心圆图形
		* @return bool 是否拷贝成功,成功则为true
		*/
		bool Copy(CCircle* dst);

		double x;				 /** @brief 同心圆图形的列坐标 */
		double y;				 /** @brief 同心圆图形的行坐标 */
		double small_radius;     /** @brief 同心圆图形的小圆半径 */
		double radius;			 /** @brief 同心圆图形的圆半径 */
		double big_radius;       /** @brief 同心圆图形的大圆半径 */
	};

	/** @brief 矩形参数 */
	struct JVision_API Rectangle : public BaseFigure
	{
		/**
		* @brief 矩形构造函数
		*/
		Rectangle();

		/**
		* @brief 矩形构造函数
		* @param[in] _x 矩形左上角顶点列坐标
		* @param[in] _y 矩形左上角顶点行坐标
		* @param[in] _width 矩形宽度
		* @param[in] _height 矩形高度
		*/
		Rectangle(double _x, double _y, double _width, double _height);

		/**
		* @brief 序列化矩形参数接口
		* @return std::string 序列化的矩形参数字符串
		*/
		std::string serializeJSON();

		/**
		* @brief 反序列化矩形参数接口
		* @param[in] jsonStr 序列化的矩形参数字符串
		* @return bool 是否反序列化成功,成功为true
		*/
		bool DeserializeJSON(const std::string jsonStr);

		/**
		* @brief 重载比较符号,比较传入的矩形与本地的矩形参数是否一致
		* @param[in] other 图形FIGURE
		* @return bool 是否一致,一致则为true
		*/
		bool operator==(const Rectangle& other) const;

		/**
		* @brief 拷贝一份矩形图形
		* @param[in] * dst 待拷贝的矩形图形
		* @return bool 是否拷贝成功,成功则为true
		*/
		bool Copy(Rectangle* dst);

		double x;			   /** @brief 矩形图形左上角顶点的列坐标 */
		double y;			   /** @brief 矩形图形左上角顶点的行坐标 */
		double width;		   /** @brief 矩形图形的宽度 */
		double height;		   /** @brief 矩形图形的高度 */
	};

	/** @brief 旋转矩形参数 */
	struct JVision_API RotatedRect : public BaseFigure
	{
		/**
		* @brief 旋转矩形构造函数
		*/
		RotatedRect();

		/**
		* @brief 矩形构造函数
		* @param[in] _x 旋转矩形中心列坐标
		* @param[in] _y 旋转矩形中心行坐标
		* @param[in] _phi 旋转矩形的旋转角度 单位:degree°
		* @param[in] _lenth1 旋转矩形的一半宽度
		* @param[in] _lenth2 旋转矩形的一半高度
		*/
		RotatedRect(double _x, double _y, double _phi, double _lenth1, double _lenth2);

		/**
		* @brief 序列化旋转矩形参数接口
		* @return std::string 序列化的旋转矩形参数字符串
		*/
		std::string serializeJSON();

		/**
		* @brief 反序列化旋转矩形参数接口
		* @param[in] jsonStr 序列化的旋转矩形参数字符串
		* @return bool 是否反序列化成功,成功为true
		*/
		bool DeserializeJSON(const std::string jsonStr);

		/**
		* @brief 重载比较符号,比较传入的旋转矩形与本地的旋转矩形参数是否一致
		* @param[in] other 图形FIGURE
		* @return bool 是否一致,一致则为true
		*/
		bool operator==(const RotatedRect& other) const;

		/**
		* @brief 拷贝一份旋转矩形图形
		* @param[in] * dst 待拷贝的旋转矩形图形
		* @return bool 是否拷贝成功,成功则为true
		*/
		bool Copy(RotatedRect* dst);

		double x;			/** @brief 旋转矩形图形中心点的列坐标 */
		double y;			/** @brief 旋转矩形图形中心点的行坐标 */
		double phi;         /** @brief 旋转矩形图形的旋转角度degree */
		double lenth1;		/** @brief 旋转矩形图形的一半高度 */
		double lenth2;		/** @brief 旋转矩形图形的一半高度 */
	};

	/** @brief 同心矩形参数 */
	struct JVision_API CRectangle :public BaseFigure
	{
		/**
		* @brief 旋转矩形构造函数
		*/
		CRectangle();

		/**
		* @brief 矩形构造函数
		* @param[in] _x 旋转矩形中心列坐标
		* @param[in] _y 旋转矩形中心行坐标
		* @param[in] _phi 旋转矩形的旋转角度 单位:degree°
		* @param[in] _lenth1 旋转矩形的一半宽度
		* @param[in] _lenth2 旋转矩形的一半高度
		*/
		CRectangle(double _x, double _y, double _phi, double _lenth1, double _lenth2, double _Diff);

		/**
		* @brief 序列化旋转矩形参数接口
		* @return std::string 序列化的旋转矩形参数字符串
		*/
		std::string serializeJSON();

		/**
		* @brief 反序列化旋转矩形参数接口
		* @param[in] jsonStr 序列化的旋转矩形参数字符串
		* @return bool 是否反序列化成功,成功为true
		*/
		bool DeserializeJSON(const std::string jsonStr);

		/**
		* @brief 重载比较符号,比较传入的旋转矩形与本地的旋转矩形参数是否一致
		* @param[in] other 图形FIGURE
		* @return bool 是否一致,一致则为true
		*/
		bool operator==(const CRectangle& other) const;

		/**
		* @brief 拷贝一份同心矩形图形
		* @param[in] * dst 待拷贝的同心矩形图形
		* @return bool 是否拷贝成功,成功则为true
		*/
		bool Copy(CRectangle* dst);

		double x;			/** @brief 同心矩形图形中心点的列坐标 */
		double y;			/** @brief 同心矩形图形中心点的行坐标 */
		double phi;         /** @brief 同心矩形图形的旋转角度degree */
		double lenth1;		/** @brief 同心矩形图形的一半高度 */
		double lenth2;		/** @brief 同心矩形图形的一半高度 */
		double Diff;	    /** @brief 同心矩形图像中矩形差*/
	};

	/** @brief 直线参数 */
	struct JVision_API Line : public BaseFigure
	{
		/**
		* @brief 直线构造函数
		*/
		Line();

		/**
		* @brief 直线构造函数
		* @param[in] _StartX 直线的起始点列坐标
		* @param[in] _StartY 直线的起始点行坐标
		* @param[in] _EndX 直线的终止点点列坐标
		* @param[in] _EndY 直线的终止点点行坐标
		*/
		Line(double _StartX, double _StartY, double _EndX, double _EndY);

		/**
		* @brief 序列化直线参数接口
		* @return std::string 序列化的直线参数字符串
		*/
		std::string serializeJSON();

		/**
		* @brief 反序列化直线参数接口
		* @param[in] jsonStr 序列化的直线参数字符串
		* @return bool 是否反序列化成功,成功为true
		*/
		bool DeserializeJSON(const std::string jsonStr);

		/**
		* @brief 重载比较符号,比较传入的直线与本地的直线参数是否一致
		* @param[in] other 图形FIGURE
		* @return bool 是否一致,一致则为true
		*/
		bool operator==(const Line& other) const;

		/**
		* @brief 拷贝一份直线图形
		* @param[in] * dst 待拷贝的直线图形
		* @return bool 是否拷贝成功,成功则为true
		*/
		bool Copy(Line* dst);

		double StartX;		 /** @brief 直线图形起始点的列坐标 */
		double StartY;		 /** @brief 直线图形起始点的行坐标 */
		double EndX;		 /** @brief 直线图形终止点的列坐标 */
		double EndY;		 /** @brief 直线图形终止点的行坐标 */
	};

	/** @brief 卡尺参数 */
	struct JVision_API Caliper : public BaseFigure
	{
		/**
		* @brief 卡尺构造函数
		*/
		Caliper();

		/**
		* @brief 卡尺构造函数
		* @param[in] _x1 卡尺的起始点列坐标
		* @param[in] _y1 卡尺的起始点行坐标
		* @param[in] _x2 卡尺的终止点点列坐标
		* @param[in] _y2 卡尺的终止点点行坐标
		* @param[in] _height 卡尺的高度
		* @param[in] _segment_line_num 卡尺的分割数量
		*/
		Caliper(double _x1, double _y1, double _x2, double _y2, double _height, int _segment_line_num);

		/**
		* @brief 序列化卡尺参数接口
		* @return std::string 序列化的卡尺参数字符串
		*/
		std::string serializeJSON();

		/**
		* @brief 反序列化卡尺参数接口
		* @param[in] jsonStr 序列化的卡尺参数字符串
		* @return bool 是否反序列化成功,成功为true
		*/
		bool DeserializeJSON(const std::string jsonStr);

		/**
		* @brief 重载比较符号,比较传入的卡尺与本地的卡尺参数是否一致
		* @param[in] other 图形FIGURE
		* @return bool 是否一致,一致则为true
		*/
		bool operator==(const Caliper& other) const;

		/**
		* @brief 拷贝一份卡尺图形
		* @param[in] * dst 待拷贝的卡尺图形
		* @return bool 是否拷贝成功,成功则为true
		*/
		bool Copy(Caliper* dst);

		double lineStartX;				/** @brief 卡尺图形起始点的列坐标 */
		double lineEndX;				/** @brief 卡尺图形起始点的行坐标 */
		double lineStartY;				/** @brief 卡尺图形终止点的列坐标 */
		double lineEndY;				/** @brief 卡尺图形终止点的行坐标 */
		double height;					/** @brief 卡尺高度 */
		std::string caliperCase;		/** @brief 卡尺的放置情况, case1代表垂直,case2代表水平 */
		int segment_line_num;			/** @brief 卡尺的分割数量 */

		// 下面是通过计算得出的数据
		double x1;				/** @brief 卡尺中心线的起始点横坐标 */
		double y1;				/** @brief 卡尺中心线的起始点列坐标 */
		double x2;				/** @brief 卡尺中心线的终止点横坐标 */
		double y2;				/** @brief 卡尺中心线的终止点列坐标 */
		double row;			    /** @brief 卡尺最小包围框旋转矩形的中心横坐标 */
		double col;				/** @brief 卡尺最小包围框旋转矩形的中心列坐标 */
		double len1;			/** @brief 卡尺最小包围框旋转矩形的边1 */
		double len2;			/** @brief 卡尺最小包围框旋转矩形的边2 */
		double angle;			/** @brief 卡尺最小包围框旋转矩形的旋转角度 */
	};

	/** @brief 多边形(在窗口中通过鼠标点击多次构成的图形) */
	struct JVision_API MPolygon : public BaseFigure
	{
		/**
		* @brief 卡尺构造函数
		*/
		MPolygon();

		/**
		* @brief 多边形构造函数
		* @param[in] Points	后期优化
		* @param[in] List_P	后期优化
		* @param[in] List_Ps	后期优化
		*/
		MPolygon(QList<QPointF> Points, QList<QPointF> List_P, QList<QList<QPointF>> List_Ps);

		/**
		* @brief 序列化多边形参数接口
		* @return std::string 序列化的多边形参数字符串
		*/
		std::string serializeJSON();

		/**
		* @brief 反序列化多边形参数接口
		* @param[in] jsonStr 序列化的多边形参数字符串
		* @return bool 是否反序列化成功,成功为true
		*/
		bool DeserializeJSON(const std::string jsonStr);

		/**
		* @brief 重载比较符号,比较传入的多边形与本地的多边形参数是否一致
		* @param[in] other 图形FIGURE
		* @return bool 是否一致,一致则为true
		*/
		bool operator==(const MPolygon& other) const;

		/**
		* @brief 拷贝一份多边形图形
		* @param[in] * dst 待拷贝的多边形图形
		* @return bool 是否拷贝成功,成功则为true
		*/
		bool Copy(MPolygon* dst);

		QList<QPointF>* points;				/** @brief 后期优化 */
		QList<QPointF>* list_p;				/** @brief 后期优化 */
		QList<QList<QPointF>>* list_ps;		/** @brief 后期优化 */
	};
}

#endif