/*******************************************************************************************************
* 2024-12-04
*
*
*
********************************************************************************************************/
#ifndef YOSEENALG_CALIBRATE_H_
#define YOSEENALG_CALIBRATE_H_

#include "YoseenDeviceTypes.h"

/*******************************************************************************************************
*
* cali
*
*
********************************************************************************************************/
struct _cali_cfg;
typedef struct _cali_cfg cali_cfg;

struct _fpa_env_context;
typedef struct _fpa_env_context fpa_env_context;

struct _cali2multi_context;
typedef struct _cali2multi_context cali2multi_context;

struct _nst_context;
typedef struct _nst_context nst_context;

struct _vvv_context;
typedef struct _vvv_context vvv_context;

struct _gaowen_context;
typedef struct _gaowen_context gaowen_context;

struct _WeiJu2Context;
typedef struct _WeiJu2Context WeiJu2Context;

struct _FixTransContext;
typedef struct _FixTransContext FixTransContext;

//
struct _cali_file_header;
typedef struct _cali_file_header cali_file_header;

struct _com_file_header;
typedef struct _com_file_header com_file_header;

/*******************************************************************************************************
*
* com
*
*
********************************************************************************************************/
enum {
    ComError_None = 0,

    ComError_InvalidInput,
    ComError_InvalidInputForCali,
    ComError_InitCom,
    ComError_MakeCom,
    ComError_SortCom,
    ComError_SaveCom,
};

typedef struct _bad_file_header {
    char camera_id[32];
    s32 width;
    s32 height;

    //
    s32 count;
}bad_file_header;

typedef struct _camera_point {
    u16 x;
    u16 y;
}camera_point;

struct com_input_bad {
    char camera_id[32];
    s32 width;
    s32 height;

    //
    s32 count;
    camera_point points[0];
};

/*******************************************************************************************************
*
*
*
*
********************************************************************************************************/
extern "C" {
    /*
    calibrate
    */
    SDK_API cali_cfg* caliCreate(const char* fn_cali, const char* fn_com, const FixInfo& fixInfo);
    SDK_API cali_cfg* caliCreate2(const char* fn_cali, const char* fn_com, const FixInfo& fixInfo, s32 fpaTemp);
    SDK_API void caliFree(cali_cfg* cfg);
    SDK_API s32 caliSetFixInfo(cali_cfg* cfg, const FixInfo& fixInfo);
    SDK_API void caliCompensate(cali_cfg* cfg, s16* temp);

    SDK_API void cali201601(const cali_cfg* cfg, s32 fpaTemp, s16* vd, s16* temp);
    SDK_API void cali201704(const cali_cfg* cfg, s32 fpaTemp, s16* vd);
    SDK_API void caliExecute(cali_cfg* cfg, s16* vd);
    SDK_API void caliExecutePart(cali_cfg* cfg, s16* vd, s32 begin, s32 end);
    SDK_API void caliInitEnv(cali_cfg* cfg, s32 fpaTemp, s32 shellTemp);
    SDK_API void caliInitEnvSync(cali_cfg* cfg, s32 fpaTemp, s32 shellTemp);
    SDK_API void caliSetHack1Flags(cali_cfg* cfg);
    SDK_API int caliVerify(const char* filename, const char* camera_id);

    /*
    * old device may use c2m. new device don't.
    *
    * use c2m fpa1-bbt-bbsi init cfg->hack2_bb_lut.
    *
    */
    SDK_API s32 caliLoadC2m(cali_cfg* cfg, const char* fn_c2m);

    /*
    fec
    */
    SDK_API fpa_env_context* fecCreate(cali_cfg* cfg_array[]);
    SDK_API void fecFree(fpa_env_context* fec);
    SDK_API s32 fecGetEnv(fpa_env_context* fec, s32 fpa);
    SDK_API void fecGet(fpa_env_context* fec, DataFrameHeader* dfh);

    /*
    com
    */
    SDK_API s32 comProcess(cali_cfg* caliCfg, const char* fnBad, const char* fnCom);
    SDK_API s32 comProcessVVV(vvv_context* vvv, const char* fnBad, const char* fnCom);
    SDK_API int caliVerifyBad(const char* filename, const bad_file_header* bfh);

    /*
    nst
    */
    SDK_API s32 nstFFC(cali_cfg* caliCfg, s32 fpaTemp, s16* vol, s16* temp, s32 nstDelta);
    SDK_API void nstSetFlags(cali_cfg* caliCfg);

    /*
    c2m
    */
    SDK_API cali2multi_context* c2mCreate(const char* fn_c2m, cali_cfg* caliCfg);
    SDK_API void c2mFree(cali2multi_context* context);
    SDK_API void c2mExecute(cali2multi_context* context, s16* vd);
    SDK_API void c2mInitEnv(cali2multi_context* context, s32 fpaTemp, s32 shellTemp);
    SDK_API void c2mSetHack1Flags(cali2multi_context* context);
    SDK_API int caliVerifyC2m(const char* filename, const char* camera_id);

    /*
    gaowen
    */
    SDK_API gaowen_context* gaowenCreate(const char* fn_c2m, cali_cfg* caliCfg);
    SDK_API void gaowenFree(gaowen_context** pp);
    SDK_API void gaowenExecute(gaowen_context* context, s16* vd, DataFrameHeader* dfh);
    SDK_API void gaowenInitEnv(gaowen_context* context, s32 fpaTemp, s32 shellTemp);
    SDK_API void gaowenSetHack1Flags(gaowen_context* context);
    SDK_API void gaowenChangeGear(gaowen_context* context, s32 gearLevel, s32 fpaTemp, s32 shellTemp);
    SDK_API int caliVerifyGaoWen(const char* filename, const char* camera_id);

    /*
    weiju
    */
    SDK_API WeiJu2Context* WeiJu2_Create(cali_cfg* caliCfg);
    SDK_API void WeiJu2_Free(WeiJu2Context** pp);
    SDK_API void WeiJu2_Execute(WeiJu2Context* context, s16* vd);
    SDK_API void WeiJu2_ExecutePart(WeiJu2Context* context, s16* vd, s32 begin, s32 end);
    SDK_API void WeiJu2_InitEnv(WeiJu2Context* context, s32 fpaTemp, s32 shellTemp);
    SDK_API s32 WeiJu2_LoadFile(WeiJu2Context* context, const char* fn_weiju);
    SDK_API s32 WeiJu2_Convert(const char* fnv1, const char* fnv2);

    /*
    vvv
    */
    SDK_API vvv_context* vvvCreate(const char* fn, const char* fn_com);
    SDK_API void vvvFree(vvv_context** pp);
    SDK_API void vvvNST(vvv_context* context, s32 fpaTemp, s16* vol, s16* temp);
    SDK_API void vvvCOM(vvv_context* context, s16* temp);
    SDK_API void vvvFIX(vvv_context* context, s16* temp);
    SDK_API s32 vvvGetEnv(vvv_context* context, s32 fpaTemp);
    SDK_API s32 vvvVerify(const char* fn, const char* camera_id);

    /*
    cust
    */
    SDK_API s32 Cust2_Load(cali_cfg* cfg, const char* fn_cust);
    SDK_API s32 Cust2_LoadGaoWen(gaowen_context* context, const char* fn_cust2);
    SDK_API s32 Cust2_LoadWeiJu(WeiJu2Context* context, const char* fn_cust1, const char* fn_cust2);
    SDK_API s32 Cust2_Convert(const char* fnv1, const char* fnv2);

    /*
    fixtrans
    */
    SDK_API FixTransContext* FixTrans_Create();
    SDK_API void FixTrans_Free(FixTransContext** pp);
    SDK_API void FixTrans_UpdateLut(FixTransContext* context, s32 envTemp, double trans, s16* lut, s32 slope, s32 offset);

    /*
    * cali2+FixInfo.InfraredWindowTrans=1.0, use 200C to test.
    * t1: no trans
    * t2: trans
    * envTemp: 25
    */
    SDK_API double FixTrans_CalcTrans(double t1, double t2, double envTemp);
}

#endif