#pragma once

#include <iostream>
#include <vector>
#include <mutex>
#include "basecamera.h"
#include "QtCore\qdatetime.h"

//#define __DEBUG          //debug信息输出功能
#define __UDPSend          //网络发送功能
#define USB_BASLER_NEW_FW  //使用basler定制固件
//#define IMM_PROCESS        //拍照后立马处理，不等校验信号
#define IMM_FEED_BACK      //处理完后立马反馈，不等校验信号
//#define ONE_TIME_SHIFT     //错开一拍发送反馈(默认错开两次)
#define AI_WARM_UP         //AI识别开始前的热身动作
#define LICENSE_VERIFY     //开启license文件校验
//CAP_FEED_BACK和DOUBLE_FEED_BACK不要一起开
#if defined (ONE_TIME_SHIFT)    
	//#define CAP_FEED_BACK   //拍照时也检测有没有测试结果，有的话就反馈
	//#define DOUBLE_FEED_BACK   //一次ng，两次反馈ng信号
#endif
//#define identify_Hik_YSXID//识别海康相机YSXID
//#define __ExportData  // 输出检测数据到XML文档
#define DRAW_RECT // 鼠标画框功能

#define Queue_Size         15
#define Unit_Queue_Size    Queue_Size*3
#define StrobeLineTime     10000

#ifdef __DEBUG
#define DEBUG(format, ...) printf (format, ##__VA_ARGS__)
#else
#define DEBUG(format, ...)
#endif

// 主界面基本参数配置文件
#define CONFIGURE_FILE    "D:/conf/conf.txt"
// 相机旋转角度配置文件
#define ROTATE_FILE    "D:/conf/rotate.txt"
#define MODBUS_CONFIGURE_FILE "D:/conf/modbus.txt"
#define PLC_CONFIG_FILE    "D:/conf/plc.txt"
#define SELECT_RECTS_FILE    "D:/conf/SelectRects%d%d.txt"
#define STATISTIC_FILE    "D:/conf/camera%d_statistic.txt"
#define ALARM_RECORD_FILE    "alarm.txt"

#define OUTPUT_HIGH_WIDTH	20000			//输出信号的脉冲宽度，微秒

#define OP_TIME 300	//OP权限时长（默认300秒）

#define ADMIN_TIME 600	//ADMIN权限时长（默认300秒）

#define STOP_SECONDS	3	//检查多少次不变触发自动换班

int string_split(std::string str, std::string pattern,std::vector<std::string> &out);
std::string format(const char *pszFmt, ...);
void getFiles(std::string path, std::vector<std::string>& files);
std::string SelectDirBRI();
std::string SelectFileOFN();
std::string SelectDirIFD();
class SysConf
{
public:
	std::mutex lock;
	int save;						//图片是否保存，0不保存，1保存NG, 2全部保存
	int MisMatchAct;				//错位行为，1：NG,0：ok
	int save_days;					///照片保存天数
	int freesize;					/// 设定清理图片最小空间
	std::string ComPort;			///COM口
	int ConfThreshold;			//识别率
	int auto_open;					//是否自动打开相机，0否，1是
	int auto_work;					//是否自动开始工作，0否，1是
	int auto_shift;					//是否自动换班，0否，1是
	int shift_byhand;				// 是否手动换班，0否，1是
	QTime shiftA;					//A换班时间
	QTime shiftB;					//B换班时间
	QTime shiftC;					//C换班时间
	QString location;				// 所在地
	QString model_path;				// 模型文件夹路径
	QString model_name;				// 模型名
	QString jpg_path;				// 图片路径
	int timing_shift;					//是否定时换班，0否，1是
	int expo[NumberOfSupportedCameras];	//相机曝光时间，单位微秒
	int gain[NumberOfSupportedCameras];	//相机模拟增益，范围0~64
	int filter[NumberOfSupportedCameras];//相机滤波时间
	int UserID[NumberOfSupportedCameras];
	int no[NumberOfSupportedCameras][3];//拍摄图片最少合格胶点数
	int shoot[NumberOfSupportedCameras];//拍摄次数
	std::string MonitorIP;				//远程监控端的IP
	int MonitorPort;
	int FeedbackPort;
	int FilePort;
	//MonitorPort为数据端口
	//MonitorPort+NumberOfSupportedCameras为图像端口
	//MonitorPort+NumberOfSupportedCameras*2为发送命令端口,也就是FeedbackPort
	//MonitorPort+NumberOfSupportedCameras*2+1为接受命令端口
	
	SysConf()
	{
		save=0;						//图片是否保存，0不保存，1保存NG, 2全部保存
		MisMatchAct=1;				//错位行为，1：NG,0：ok
		save_days = 1;				///照片保存天数
		freesize = 10;				/// 设定清理图片最小空间
		ComPort = "COM1";			///COM口
		ConfThreshold = 1;			///百分比识别率
		auto_open=1;				//是否自动打开相机，0否，1是
		auto_work=1;				//是否自动开始工作，0否，1是
		auto_shift=0;				//是否自动换班，0否，1是
		shift_byhand = 1;			//是否手动换班，0否，1是
		timing_shift = 0;			//是否定时换班，0否，1是
		location = "";
		model_path = "";
		model_name = "";
		jpg_path = "";
		shiftA.setHMS(0, 0, 0);
		shiftB.setHMS(0, 0, 0);
		shiftC.setHMS(0, 0, 0);
		for(int i=0;i<NumberOfSupportedCameras;i++)
		{
			expo[i]=2000;
			gain[i]=0;
			filter[i]=500;
			UserID[i]=0xff;
			no[i][0]=0;
			no[i][1]=0;
			no[i][2]=0;
			shoot[i]=3;
		}
		MonitorIP = "192.168.10.1";
		FeedbackPort = MonitorPort + NumberOfSupportedCameras*2;
		
	}
};

//Modbus地址设置
class ModbusConf
{
public:
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>0)
	int kick1;			//1#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>1)
	int kick2;			//2#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>2)
	int kick3;			//3#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>3)
	int kick4;			//4#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>4)
	int kick5;			//5#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>5)
	int kick6;			//6#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>6)
	int kick7;			//7#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>7)
	int kick8;			//8#通道剔除个数地址
#endif
	int quantity;		//当班产量地址
	int shift;			//换班地址
	int	work;			//开始/停止
	int no_kick;		//只拍照不剔除模式
	int debug;			//调试模式，PLC产生模拟的line4信号
	int reset;			//复位
	int alarm;			//报警

	ModbusConf()
	{
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>0)
		kick1=0;			//1#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>1)
		kick2=0;			//2#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>2)
		kick3=0;			//3#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>3)
		kick4=0;			//4#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>4)
		kick5=0;			//5#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>5)
		kick6=0;			//6#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>6)
		kick7=0;			//7#通道剔除个数地址
#endif
#if defined(NumberOfSupportedCameras) && (NumberOfSupportedCameras>7)
		kick8=0;			//8#通道剔除个数地址
#endif
		quantity=0;		//当班产量地址
		shift=0;			//换班地址
		work=0;			//开始/停止
		no_kick=0;		//只拍照不剔除模式
		debug=0;			//调试模式，PLC产生模拟的line4信号
		reset=0;			//复位
		alarm=0;			//报警
	}
};

#define  DisplayLabel_Type_Bit 0x01  //1:打开范围识别功能，0:关闭范围识别功能
#define  DisplayLabel_Conf_Bit 0x02  //1:可以绘制矩形框，0:不能绘制矩形框
class RectRatio
{
public:
	RectRatio(cv::Point2f tl, cv::Point2f br) :TL(tl), BR(br) {};
	cv::Point2f TL;
	cv::Point2f BR;
};

class DisplayLabelConf
{
public:
	std::mutex lock;
	bool leftButtonDownFlag = false; //左键单击后视频暂停播放的标志位
	cv::Point2f originalPoint; //矩形框起点
	cv::Point2f processPoint;  //矩形框终点

	cv::Mat g_last_mat[2];
	bool g_max[2] = {false};   //视图是否最大化
	uint8_t Flag[2] = {0};
	std::vector<RectRatio> RectVet[2];
};
void DrawSelectRects(cv::Mat input, DisplayLabelConf& t_DisplayLabelConf, int Cnt);
bool CheckSelectRects(cv::Mat input, std::vector<std::vector<std::pair<int, cv::Rect> > >& VecRects, int VecCnt, DisplayLabelConf& t_DisplayLabelConf, int LabelCnt);
