// globals.h
#ifndef GLOBALS_H
#define GLOBALS_H

#include <MIL.h>
#include <QMutex>
#include <opencv2/opencv.hpp>
#include <QSemaphore>
#include <QDir>
#include <QCoreApplication>
#include <queue>
#include <mutex>
#include <condition_variable>
#include <optional>
#include <thread>
#include <atomic>
#include "onnxrunner.h"

extern long long g_valveActionCount;

// 图片显示0
extern QMutex gDispPicMutex0;
extern MIL_ID gDispCurrentPicId0;

// 图片显示1
extern QMutex gDispPicMutex1;
extern MIL_ID gDispCurrentPicId1;

// 掩膜互斥锁和ID
extern QMutex gMaskMutex0;
extern MIL_ID gMask0;

extern QMutex gMaskMutex1;
extern MIL_ID gMask1;

// 检测准备信号量
extern QSemaphore detection_ready;

extern bool g_dl_enable[2];
extern bool g_traditional_enable[2];

// 获取保存目录和配置目录函数
QString getSaveDirectory();
QString getConfigDirectory();

// 定义一个结构体来存储图像数据及其来源相机ID
struct ImageData
{
    int camera_id;
    cv::Mat image;
};

// 添加 DetectionResult 结构体
struct DetectionResult {
    QMutex mutex;                                          // 保护数据的互斥锁
    std::vector<std::vector<uint8_t>> dl_mask;             // 深度学习掩膜
    std::vector<std::vector<uint8_t>> traditional_mask;    // 传统算法掩膜
};

extern DetectionResult g_detection_result[2];

// 线程安全队列模板类
// 线程安全队列模板类，最大长度为1避免队列数据或者结果的积压
template <typename T>
class ThreadSafeQueue {
public:
    // 添加元素到队列，如果队列已满（长度为1），则移除旧元素
    void enqueue(const T& item)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        if (queue_.size() >= 1)
        {
            queue_.pop(); // 移除旧的元素
        }
        queue_.push(item);
        cond_var_.notify_one();
    }

    // 从队列中移除并获取元素
    bool dequeue(T& item)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while (queue_.empty() && !stop_)
        {
            cond_var_.wait(lock);
        }
        if (queue_.empty())
            return false;
        item = std::move(queue_.front());
        queue_.pop();
        return true;
    }

    // 查看队列中的第一个元素而不移除
    bool front(T& item)
    {
        std::unique_lock<std::mutex> lock(mutex_);
        while (queue_.empty() && !stop_)
        {
            cond_var_.wait(lock);
        }
        if (queue_.empty())
            return false;
        item = queue_.front(); // 直接复制，不移除
        return true;
    }

    // 停止队列，唤醒所有等待的线程
    void stop()
    {
        std::unique_lock<std::mutex> lock(mutex_);
        stop_ = true;
        cond_var_.notify_all();
    }

    // 检查队列是否为空
    bool empty()
    {
        std::lock_guard<std::mutex> lock(mutex_);
        return queue_.empty();
    }

private:
    std::queue<T> queue_;
    std::mutex mutex_;
    std::condition_variable cond_var_;
    bool stop_ = false;
};

// 定义全局存储队列
extern ThreadSafeQueue<ImageData> g_storageQueue;

// 定义全局图像队列和结果队列
extern ThreadSafeQueue<ImageData>* g_img_Queue[2];
extern ThreadSafeQueue<ImageData>* g_result_Queue[2];

// 定义全局识别线程
extern std::thread* g_recognitionThread[2];

// 定义线程控制变量
extern std::atomic<bool>* g_recognitionRunning[2];

// 定义全局ONNXRunner实例数组
extern ONNXRunner* g_runner_array[2];

extern std::map<std::string, int> params;
extern std::vector<std::string> colors;



#define MIN_AREA 30

#endif // GLOBALS_H
