#ifndef CAMERAHANDLE_H
#define CAMERAHANDLE_H
#include "RecognitionInfo.h"
#include "FaceReconitionHandle.h"
#include "HttpService.h"
#include "LicensePlateRecognition.h"
#include "Json_Header/AlarmInfo.h"
#include "Json_Header/NetWork_NetCommon.h"
#include "Json_Header/OPTimeSetting.h"
#include "Json_Header/Simplify_Encode.h"
#include "Json_Header/System_TimeZone.h"
#include "Json_Header/RecordCfg.h"
#include "Json_Header/NetWork_SPVMN.h"
#include "Json_Header/NetWork_Wifi.h"
#include "Json_Header/SystemInfo.h"
#include "Json_Header/OPMachine.h"
#include "mainwindow.h"
#include "ParkingSpaceInfo.h"
#include "hyper_lpr_sdk.h"
#include <QPolygon>
#include <QPainterPath>
#include <QProcess>
#include <QDateTime>
#include <QJsonDocument>
#include <memory>
#include <functional>
#include <QString>
#include <QTimer>
#include <QThreadPool>
#include <QQueue>
#include <opencv2/opencv.hpp>
#include <QSemaphore>
#include <atomic>

enum CAR_INFORMATION {
    Exit,   //出场
    Mobilization, //进场
    ExitAndMobilization //
};
class CameraHandle: public QObject
{
    Q_OBJECT

public:
    CameraHandle(QString &url,QString &httpUrl,QString &sSn, int &channel, int imageSave,
                 float &heightReference,vides_data::responseConfig &devConfig);
    CameraHandle();
    ~CameraHandle();
    int sdkDevLoginSyn(QString sDevId, int nDevPort, QString sUserName, QString sPassword, int nTimeout);
    //int SdkMediaGetFaceImage(int hDevice, int nSeq, int nTimeout);

    int sdkDevSetAlarmListener(XSDK_HANDLE hDevice, int bListener);
    
    int getHdevice();
    
    int getChannel();
    
    void clearCameraHandle();
    
    //    void rebindTimer(int hDevice);
    //相机参数更新
    void cameraParameterUpdate(vides_data::responseConfig &cloudConfig);
    
    void initSdkRealTimeDevSnapSyn(int hDevice,int syn_timer,uint64 face_frequency);

    void notificationUpdateImageMap(std::map<QString,QString>&maps,int numberFaces,float confidence);

    void featureRemove();
    
    void updateImage(const cv::Mat & frame,qint64 currentTime);
    
    void matToBase64(const cv::Mat &image, QByteArray &base64Data);

    //把原始图片转换成不同区域的掩码
    void matToAreaMask(const cv::Mat &source,std::map<int,cv::Mat> &maskFrame);

    int callbackFunction(XSDK_HANDLE hObject,QString &szString);


    void checkAndUpdateCurrentPlate(ParkingSpaceInfo*park,const cv::Mat & frame,RecognizedInfo& newInfo,int &result);
    
    void licensePlateRecognitionResults(vides_data::requestLicensePlate &location);
    
    void sdkDevSnapSyn(XSDK_HANDLE hDevice, int nChannel);

    void printWifi(XSDK_HANDLE hDevice,XSDK_CFG::NetWork_Wifi &cfg);

    void setCarConfidenceMaxAndMin(float carConfidenceMax,float carConfidenceMin);

    //设置相机连接的wifi
    void sdkWifi(QString &pwd,QString &ssid);
    //时间设置
    void sdkDevSystemTimeZoneSyn(QString &time);
    //录像设置
    void sdkRecordCfg(const char * recordJson);
    //配置编码设置
    void sdkEncodeCfg(const char *enCode);
    //28181更新
    void sdkDevSpvMn(const char* spvMn);
    //gb218开启
    int updateSdkDevStatus(bool status);

    void updateSdkDevSpvMn(vides_data::responseGb28181 *gb28181);
    //重启设备
    int deviceReboot();
    //设备关机
    int deviceShutdown();
    //获取固件版本
    void findFirmwareVersion(QString &firmwareVersion);
    
    //获取ip
    void findIp(QString &ip);
    
    void sdkDownloadFileByTime(XSDK_HANDLE hDevice,int id,
                               QString startTimer,QString endTime);
    void batchRegionalPushLicensePlate(QByteArray &imgs,qint64 currentTime,vides_data::requestLicensePlate &newPlate);

    void faceUniformOverlap(std::map<QString,vides_data::requestFaceReconition>&mapFaces,
                            std::vector<vides_data::ParkingArea> &uniforms,
                            std::list<QString>&outUniforms);
    
    bool isClockwise(const std::vector<cv::Point2f>& polygon);


    QString getSSn();
    int getMediaHandle();
    void setMediaHandle(int mediaHandle);

    void initAlgorithmPermissions(__uint8_t algorithm);
    void initParkingSpaceInfo(const std::list<vides_data::responseArea>&areas);
    
    bool compareLists(const std::list<vides_data::responseArea>& newAreas);
    
    void updateParkMapAndParkingSpaceInfos(const std::list<vides_data::responseArea>&newAreas);
    
    std::map<int, vides_data::responseRecognitionData>&getVideoCurrentData();
    
    std::map<QString, QString>&getCurrentData();
    
    vides_data::responseConfig &getDeviceConfig();
    
    bool isChanged(const QPoint& newInfo, const QPoint& current);
    // 检查点是否在多边形内
    bool polygonsOverlap(ParkingSpaceInfo &poly1, ParkingSpaceInfo &poly2);
    // 计算两个多边形的交集面积
    double calculateIntersectionArea(const QPolygonF &polygon1, const QPolygonF &polygon2);
    double ccw(const QPointF& a, const QPointF& b, const QPointF& c);

    void getCurrentFrame(std::vector<uchar> &buffer);
    bool isAnyOverlap(ParkingSpaceInfo *parkArea,std::vector<vides_data::ParkingArea> &currentPlates);
    
    int findPointRegion(ParkingSpaceInfo &prakArea);
    int determineArea(ParkingSpaceInfo &prakArea);

signals:
    void callbackFrameReady(const cv::Mat &frame, const QString &url);
    
    void afterDownloadFile( int id,int recognitionType,QString ossUrl);
    
private slots:
    void sdkRealTimeDevSnapSyn(int hDevice);
    void pushRecordToCloud(int id,int recognitionType,QString ossUrl);
    //void releaseSemaphore();
    
private :
    int hDevice;
    int channel;
    QString httpUrl;

    SXSDKLoginParam *loginParam;
    SXMediaFaceImageReq *sxMediaFaceImageReq;

    QString sSn;
    QString url;
    std::map<int, vides_data::responseRecognitionData> videoCurrentData;
    
    std::map<QString, QString> currentData;
    
    //每个区域编号对应一个区域信息
    std::map<int,ParkingSpaceInfo*>parkMap;
    //当前相机监视所以车位区域
    std::vector<ParkingSpaceInfo*>parkingSpaceInfos;
    //当前人脸数和工作人数
    QPoint faceMapWorker;
    
    
    int mediaHandle;
    //2秒钟抓一次图
    QTimer *dev_snap_syn_timer;
    
    int offlineCount=0;

    QSemaphore semaphore;
    
    int image_save;
    std::atomic<uint64> faceCount;
    
    uint64 face_frequency;
    
    __uint8_t algorithmPermissions;
    
    vides_data::responseConfig devConfig;
    
    float heightReference;

    float carConfidenceMax;

    float carConfidenceMin;


};
#endif // CAMERAHANDLE_H
