//
// Created by zx on 2019/12/9.
//

#ifndef REGION_WORKER_H
#define REGION_WORKER_H

#include "region_detect.h"
#include "../tool/StdCondition.h"
#include <thread>
#include <mutex>
#include <iostream>
#include <atomic>
#include <chrono>
#include "../error_code/error_code.h"
#include "../verify/Verify_result.h"

/**
 * 区域功能类，负责自动检测区域状态并更新到plc
 * */
class Region_worker
{
public:
#define REGION_WORKER_RESULT_DEFAULT 0x0000
//#define REGION_WORKER_VERIFY_OK 0x0001
//#define REGION_WORKER_EMPTY_SPACE 0x0020
//#define REGION_WORKER_CLUSTER_SIZE_ERROR 0x0040
//#define REGION_WORKER_OTHER_ERROR 0x0080
//#define REGION_WORKER_NULL_POINTER 0x0100
#define REGION_WORKER_EMPTY_SPACE 1
#define REGION_WORKER_HAS_CAR 2
#define REGION_WORKER_DETECT_ERROR 3
public:
    // 有参构造
    Region_worker(int id, wj::Region region, Verify_result* verify_handle);
    // 析构函数
    ~Region_worker();
    // 外部调用传入新点云
    void update_cloud(pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_in);
    // 实时检测线程函数
    static void detect_loop(Region_worker *worker);
    // 获取区域id
    int get_id();
    // 获得中心点、角度等测量数据
    Error_manager get_wheel_result(pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_in, double &x, double &y, double &c, double &wheelbase, double &width);

    // 获得中心点、角度等测量数据,前轮旋转
    Error_manager get_wheel_result(pcl::PointCloud<pcl::PointXYZ>::Ptr &cloud_in, double &x, double &y, double &c,
            double &wheelbase, double &width,double& front_theta);

private:
    static cv::RotatedRect create_rotate_rect(float length,float width,float angle,float x,float y);
private:
    Region_detector *m_detector;                             // 区域检测算法实例
    pcl::PointCloud<pcl::PointXYZ>::Ptr m_cloud;             // 自动区域检测用点云
    std::atomic<bool> mb_cloud_updated;                      // 点云更新指标
    std::chrono::steady_clock::time_point m_update_plc_time; // 更新plc状态时刻
    int m_last_sent_code;                              // 上次写入plc的状态值
    int m_last_read_code;                              // 上次检查获得的状态值
    int m_last_border_status;				// 上次超界提示
    std::atomic<int> m_read_code_count;                      // 检查后重复获取相同状态值次数

    StdCondition m_cond_exit;     // 系统退出标志
    std::thread *m_detect_thread; // 实时检测线程
    std::mutex m_mutex;           // 点云互斥锁

    Verify_result* mp_verify_handle; // 边缘检测
};

#endif //REGION_WORKER_H
