/*
 * @Author: turboLIU
 * @Date: 2022-11-02 15:04:08
 * @LastEditTime: 2024-10-25 09:17:48
 * @Description: Do not edit
 * @FilePath: /Algo_ACL_Common/API/AI_API.h
 */
#ifndef AI_API
#define AI_API
#include <string>
#include "detection_type_api.h"

using namespace AIGO;


#ifdef __cplusplus
extern "C"{
#endif
/**
 * @brief 算法启动前，最先年调用该函数，用于设置NPU硬件环境
 * 
 * @return int 非0表示环境异常
 */
int Init_ACL();
/**
 * @brief Set the deque size object
 * 
 * @param irdetin
 * @param visdetin 
 * @param irsegin
 * @param vissegin 
 * @param irdetout 
 * @param visdetout 
 * @param irsegout 
 * @param vissegout 
 * @param irdetres 
 * @param visdetres 
 * @param irsegres 
 * @param vissegres 
 * @return int 
 */
int set_deque_size(int irdetin=3, int visdetin=3, int irsegin=3, int vissegin=3, int irdetout=5, int visdetout = 5, int irsegout = 5, int vissegout = 5,
                    int irdetres = 10, int visdetres = 10, int irsegres = 10, int vissegres = 10);
int get_deque_size(int &irdetin, int &visdetin, int &irsegin, int &vissegin, int &irdetout, int &visdetout, int &irsegout, int &vissegout,
                    int &irdetres, int &visdetres, int &irsegres, int &vissegres);
int reset_dequeu_size(int irdetin=30, int visdetin=30, int irsegin=30, int vissegin=30, int irdetout=50, int visdetout = 50, int irsegout = 50, int vissegout = 50,
                    int irdetres = 100, int visdetres = 100, int irsegres = 100, int vissegres = 100);
/**
 * @brief Set the stream size object 
 *        init 函数调用之前，设置模型宽高；默认 1280， 1024
 * 
 * @param width 模型宽  默认1280
 * @param height 模型高 默认1024
 * @return int 
 */
int set_stream_size(int width, int height, MODE mode);
int get_stream_size(int &width, int &height, MODE mode);
int reset_stream_size(int width, int height, MODE mode);
/**
 * @brief 同时初始化检测和分割模型
 * 
 * @param irdetmodel 红外检测模型
 * @param visdetmodel 可见光检测模型
 * @param irsegmodel 红外分割模型
 * @param vissegmodel 可见光分割模型
 * @return int 
 */
int Init_AI(const char* irdetmodel, const char* visdetmodel, const char* irsegmodel, const char* vissegmodel);

int Det_VL(ImgMat frame, std::vector<objinfo> &outputs);

int Det_IR(ImgMat frame, std::vector<objinfo> &outputs);

int Seg_VL(ImgMat frame, TenMat* output);

int Seg_IR(ImgMat frame, TenMat* output);

/**
 * @brief 运行检测分割算法，异步接口，调用get_result函数获取结果
 * 
 * @param img 
 * @param GoDet 是否执行检测算法
 * @param GoSeg 是否执行分割算法
 * @param cropFlag 是否中心裁减，裁减大小通过 set_ROIArea 设置
 * @return int 
 */
int runAsync(ImgMat img, bool GoDet=true, bool GoSeg=true, bool cropFlag=false);
/**
 * @brief Get the result object，获取已异步结果
 * 
 * @param timestamp 
 * @param dets 
 * @param maskImg 
 * @param front: true: 先进先出， false: 后进先出
 * @param single true：仅获取当前光源的算法结果， false：获取双光结果
 * @return int -1:队列被释放； 1: 队列为空; 0: 成功从队列获取结果；
 */
int get_result(long long &timestamp, std::vector<objinfo> &dets, TenMat * maskImg, bool front=true, MODE mode=VIS); // async
/**
 * @brief 由可见光为主光源，切换至红外为主光源
 * 
 * @return int 
 */
int switch_vis_to_ir();
/**
 * @brief 由红外为主光源，切换至可见光为主光源
 * 
 * @return int 
 */
int switch_ir_to_vis();
/**
 * @brief Set the dropout param 
 * 
 * @param drop  true: drop deque front data, false: not drop data, 默认: false
 * @return int 
 */
int set_dropout_param(bool drop);
/**
 * @brief Get the dropout param
 * 
 * @param drop 
 * @return int 
 */
int get_dropout_param(bool &drop);
/**
 * @brief 设置分割类型，可时时生效
 * 
 * @param mode IR or VIS
 * @param road segment road or not
 * @param bridge segment bridge or not
 * @param water segment water or not
 * @param building segment building or not
 * @return int 
 */
int set_seg_classes(MODE mode, bool road, bool bridge, bool water, bool building);

/**
 * @brief Set the nms threshold object
 * 
 * @param nms 
 * @return int 
 */
int set_nms_threshold(float nms);
/**
 * @brief Get the nms threshold object
 * 
 * @param nms 
 * @return int 
 */
int get_nms_threshold(float& nms);
/**
 * @brief Set the det threshold object
 * 
 * @param threshold 置信度
 * @param idx 1～15，设置哪一个种类的置信度，种类编号参见CLASSTYPE
 * @return int 
 */
int set_det_threshold(float threshold, int idx);
/**
 * @brief Get the det threshold object
 * 
 * @param threshold 置信度
 * @param idx 1～15，设置哪一个种类的置信度，种类编号参见CLASSTYPE
 * @return int 
 */
int get_det_threshold(float &threshold, int idx);
/**
 * @brief Set the seg threshold object
 * 
 * @param thr 
 * @return int 
 */
int set_seg_threshold(float thr);
/**
 * @brief Get the seg threshold object
 * 
 * @return float 
 */
float get_seg_threshold();
/**
 * @brief 设置数据流模式，仅支持: BGR，RGB，NV12， NV21； 默认RGB
 * 
 * @param m 
 * @return int 
 */
int set_StreamMode(INPUT_LAYOUT m);
/**
 * @brief Get the StreamMode object
 * 
 * @return INPUT_LAYOUT 
 */
INPUT_LAYOUT get_StreamMode();

/**
 * @brief 算法关闭时调用，释放算法内部资源
 * 
 * @return int 
 */
int Uninit_AI();
/**
 * @brief only deinit hardware
 * 
 * @return int 
 */
int Uninit_ACL();
/**
 * @brief Set the ROIArea object
 * 
 * @param x1 lefttop
 * @param y1 lefttop
 * @param x2 botright
 * @param y2  botright
 * @return int 
 */
int set_ROIArea(int x1, int y1, int x2, int y2);

int setLabelMap(uint32_t A[], uint32_t B[], uint32_t len);


class DETECTION_API
{
private:
    /* data */
public:
    DETECTION_API(/* args */);
    ~DETECTION_API();
public:

    int netWidth=0;
    int netHeight = 0;
    int clsnum = 0;
    std::vector<std::vector<float>> anchors;// = {{7,11, 9,21, 21,15},{16,39, 31,24, 57,27},{43,59, 90,59, 131,116}};

    void* AIGOhandle=NULL;

    int AIGOinit(const char* modename, int deviceID=0);
    int AIGOpreprocess(ImgMat img, bool doCopy=true);
    int AIGOinfer();
    int AIGOpostprocess(std::vector<objinfo> &results);
    int AIGOdeinit();
};

class SEGMENTION_API
{
private:
    /* data */
public:
    SEGMENTION_API(/* args */);
    ~SEGMENTION_API();

    int netWidth = 0;
    int netHeight = 0;
    int clsnum = 0;

    void* AIGOhandle = NULL;

    int AIGOinit(const char* modename, int deviceID=0);
    int AIGOpreprocess(ImgMat img, bool doCopy=true);
    int AIGOinfer();
    int AIGOpostprocess();
    int AIGOdeinit();
};







#ifdef __cplusplus
}
#endif

#endif