/*
 * @Author: Alfred Xiang Wu
 * @Date: 2022-11-20 22:18:49
 * @Breif: 
 * @Last Modified by: Alfred Xiang Wu
 * @Last Modified time: 2023-09-19 22:32:56
 */


#ifndef _DS_PEDESTRIAN_MOT_HISI_H_
#define _DS_PEDESTRIAN_MOT_HISI_H_

#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <stdint.h>  // int64_t

#define RW_LICENSE_CHECK

#if defined _WINDOWS && !(defined _LIB)
    #ifdef DS_PEDESTRIAN_MOT_HISI_EXPORTS
        #define DS_PEDESTRIAN_MOT_HISI_API __declspec(dllexport)
    #else
        #define DS_PEDESTRIAN_MOT_HISI_API __declspec(dllimport)
    #endif
#else
    #define DS_PEDESTRIAN_MOT_HISI_API
#endif

typedef void* DS_PEDESTRIAN_MOT_HANDLE;

// for detection
typedef struct PedestrianRect {
    float xmin;
    float ymin;
    float xmax;
    float ymax;
    float score;
    int label;
} PedestrianRect;

// for tracking
typedef struct io_MEASURE {
    std::vector<float> state;       // bbox: xmin, ymin, xmax, ymax
    int frame;                      // frame id
    float conf;                     // confidence for bbox
} io_MEASURE;

typedef struct io_person {
    io_MEASURE head;                // head bbox (don't use head bbox for any analysis.)
    io_MEASURE body;                // body bbox
    int tracked = 0;                // track state

    float quality_score = 0.0;      // quality scores
} io_person;

typedef struct io_TrackData {
    int track_id;                   // track id
    int track_state;                // track state: 0 pre-track; +1 confirmed; -1 hibernate; -2 remove;
    
    io_person prediction;           // bbox at the current frame (If track_state != 1, prediction is empty.)
} io_TrackData;


#if defined(__cplusplus)
extern "C"
{
#endif

#ifdef RW_LICENSE_CHECK
    DS_PEDESTRIAN_MOT_HISI_API void ds_pedestrian_hisi_set_lic_path(const char *path);
#endif // RW_LICENSE_CHECK

    
    /**
     * The function is used to initialize the pedestrian detection and tracking handle.
     * 
     * @param handle the handle
     * @param det_model_path The path to the pedestrian detection model.
     * @param reid_model_path the path of the pedestrian tracking reid model
     * @param width width of the input image
     * @param height the height of the input image
     * @param channels the number of channels of the input image, It must be 3 channels.
     * 
     * @return A handle for the pedestrian detection and tracking.
     */
    DS_PEDESTRIAN_MOT_HISI_API int ds_pedestrian_hisi_init(
            DS_PEDESTRIAN_MOT_HANDLE* handle, 
            char* det_model_path,
            char* reid_model_path,
            const int width,
            const int height,
            const int channels);

    /**
     * The function is the interface function for pedestrian detection.
     * 
     * @param handle The handle.
     * @param bboxes the output of the pedestrian detection model, which is a vector of PedestrianRect.
     * 
     * @return the bounding boxes of the detected pedestrians.
     */
    DS_PEDESTRIAN_MOT_HISI_API int ds_pedestrian_det_hisi(
        DS_PEDESTRIAN_MOT_HANDLE handle, 
        unsigned char* img,
        std::vector<PedestrianRect> &bboxes);

    /**
     * The function is the interface function for pedestrian tracking.
     * 
     * @param handle The handle.
     * @param nframe the frame number of the current frame
     * @param det_bboxes the detection results of the current frame, which is a vector of PedestrianRect.
     * @param tracks the output of the tracking results, which is a vector of io_TrackData.
     * 
     * @return the number of tracks.
     */
    DS_PEDESTRIAN_MOT_HISI_API int ds_pedestrian_track_hisi(
        DS_PEDESTRIAN_MOT_HANDLE handle, 
        unsigned char* img,
        const int nframe, 
        std::vector<PedestrianRect> det_bboxes, 
        std::vector<io_TrackData> &tracks);

    /**
     * It releases the resources allocated in the initialization function.
     * 
     * @param handle The handle.
     * 
     * @return The handle.
     */
    DS_PEDESTRIAN_MOT_HISI_API int ds_pedestrian_hisi_release(
        DS_PEDESTRIAN_MOT_HANDLE *handle);

#if defined(__cplusplus)
}
#endif

#endif // _DS_PEDESTRIAN_MOT_HISI_H_