#ifndef YOSEENSDK_H_
#define YOSEENSDK_H_

#include "YoseenDeviceTypes.h"
#include "YoseenFileTypes.h"
#include "YoseenAlg_Strech.h"
#include "YoseenAlg_Filter.h"

struct _YoseenPlaybackContext;
typedef struct _YoseenPlaybackContext YoseenPlaybackContext;

extern "C" {
    /*******************************************************************************************************
    *
    * 接口
    *
    *
    ********************************************************************************************************/

    /*
    建立SDK
    @return 错误码
    */
    SDK_API s32 Yoseen_InitSDK();

    /*
    释放SDK
    */
    SDK_API void Yoseen_FreeSDK();

    /*
    设定全局Socket超时, 单位ms, 默认2000ms, 取值范围[2000, 8000]

    @param connectTimeout 连接超时
    @param sendTimeout 发送超时
    @param recvTimeout 接收超时
    */
    SDK_API void Yoseen_SetTimeout(s32 connectTimeout, s32 sendTimeout, s32 recvTimeout);

    /**
    分配调色板数据

    @param count 调色板数量
    @return 调色板数据, 内存布局
    ======================================
    调色板0名称, 调色板0数据; 调色板1名称, 调色板1数据; ...
    ======================================
    */
    SDK_API xxxpalettedata* Yoseen_AllocPaletteData(s32& count);

    /**
    释放调色板数据
    @param paletteData 调色板数据
    */
    SDK_API void Yoseen_FreePaletteData(xxxpalettedata** paletteData);

    /**
    导出温度数据的csv文本
    */
    SDK_API s32 Yoseen_ExportText(DataFrameHeader* dfh, s16* dfd, const char* fn);

    /*******************************************************************************************************
    *
    * 发现接口
    *
    *
    ********************************************************************************************************/

    /**
    发现热像仪
    @param discoverFlags 0x01广播, 0x02组播, 0x04 广播2
    @return 响应链表
    */
    SDK_API DiscoverCameraResp2* Yoseen_DiscoverCameras(s32 discoverFlags);

    /*
    释放响应链表
    @param pp 响应链表
    */
    SDK_API void Yoseen_DiscoverCamerasFree(DiscoverCameraResp2** pp);

    SDK_API s32 Yoseen_DiscoverConfigIP(ConfigIPReq* configIPReq);

    /*******************************************************************************************************
    *
    * 用户接口
    *
    *
    ********************************************************************************************************/

    /*
    登入热像仪, 成功登入会填充热像仪基本信息.
    目前只验证热像仪地址, 不验证用户名和密码; 热像仪不限制登入的用户.

    @param loginInfo 登录信息
    @param [out] cameraBasicInfo 热像仪基本信息
    @return >=0用户句柄, <0 错误码
    */
    SDK_API s32 Yoseen_Login(const YoseenLoginInfo* loginInfo, CameraBasicInfo* cameraBasicInfo);

    /*
    登入热像仪V2, 成功登入会填充热像仪基本信息.
    热像仪的端口是固化不可更改, 可以做端口映射, 让SDK使用映射后IP和端口,访问设备

    @param loginInfo 登录信息
    @param [out] cameraBasicInfo 热像仪基本信息
    @return >=0用户句柄, <0 错误码
    */
    SDK_API s32 Yoseen_LoginV2(const YoseenLoginInfoV2* loginInfo, CameraBasicInfo* cameraBasicInfo);

    /*
    退出热像仪
    @param userHandle 用户句柄
    @return 错误码
    */
    SDK_API s32 Yoseen_Logout(s32 userHandle);

    /*
    保存单帧温度到文件(jpg扩展格式), 不需要预览的支持. 热像仪支持同一时刻处理16个保存请求,
    降低了在同一时刻请求过多时, 后面请求失败的几率.
    @param userHandle 用户句柄
    @param fileName 文件名
    @param withTemp 是否带温度扩展
    @return 错误码
    */
    SDK_API s32 Yoseen_SaveFrame(s32 userHandle, const char* fileName, s32 withTemp);

    /*
    保存单帧温度到内存, 用户提供frameFile, SDK填充frameFile的各个数据指针.
    frameFile的各个数据指针指向的都是内部数据缓冲区, 对同一userHandle的保存请求会更新此内部数据缓冲区的内容.
    @param userHandle 用户句柄
    @param frameFile 文件数据指针结构体
    @return 错误码
    */
    SDK_API s32 Yoseen_SaveFrameToMem(s32 userHandle, TempFrameFile* frameFile);

    /**
    获取热像仪基本信息
    @param userHandle 用户句柄
    @param [out] cameraBasicInfo 基本信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetCameraBasicInfo(s32 userHandle, CameraBasicInfo* cameraBasicInfo);

    /**
    设置热像仪基本信息
    @param userHandle 用户句柄
    @param cameraBasicInfo 基本信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetCameraBasicInfo(s32 userHandle, const CameraBasicInfo* cameraBasicInfo);

    /**
    获取热像仪网络信息

    @param userHandle 用户句柄
    @param [out] cameraNetworkInfo 网络信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetCameraNetworkInfo(s32 userHandle, CameraNetworkInfo* cameraNetworkInfo);

    /**
    设置热像仪网络信息, 成功设置后, 热像仪IP可能发生变化, 请重新发现热像仪.
    若配置成使用静态IP, 但是忘记IP, 请使用热像仪的GPIO复位热像仪.

    @param userHandle 用户句柄
    @param cameraNetworkInfo 网络信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetCameraNetworkInfo(s32 userHandle, const CameraNetworkInfo* cameraNetworkInfo);

    /**
    获取探测器配置信息
    @param userHandle 用户句柄
    @param [out] fpaInfo 探测器配置信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetFPAInfo(s32 userHandle, FPAInfo* fpaInfo, s32 index);

    /**
    设置探测器配置信息
    @param userHandle 用户句柄
    @param fpaInfo 探测器配置信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetFPAInfo(s32 userHandle, const FPAInfo* fpaInfo, s32 index);

    SDK_API s32 Yoseen_GetFPAInfoAK(s32 userHandle, FPAInfoAK* info, s32 index);
    SDK_API s32 Yoseen_SetFPAInfoAK(s32 userHandle, const FPAInfoAK* info, s32 index);
    SDK_API s32 Yoseen_GetFPAInfoGD(s32 userHandle, FPAInfoGD* info, s32 index);
    SDK_API s32 Yoseen_SetFPAInfoGD(s32 userHandle, const FPAInfoGD* info, s32 index);
    SDK_API s32 Yoseen_GetFPAInfoCLW(s32 userHandle, FPAInfoCLW* info, s32 index);
    SDK_API s32 Yoseen_SetFPAInfoCLW(s32 userHandle, const FPAInfoCLW* info, s32 index);

    SDK_API s32 Yoseen_GetFPAInfoUL(s32 userHandle, FPAInfoUL* info);
    SDK_API s32 Yoseen_SetFPAInfoUL(s32 userHandle, const FPAInfoUL* info);
    /**
    获取挡板校零信息
    @param userHandle 用户句柄
    @param [out] ffcInfo 挡板校零信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetFFCInfo(s32 userHandle, FFCInfo* ffcInfo);

    /**
    设置挡板校零信息, 设置成功后, 会触发一次挡板校零.
    @param userHandle 用户句柄
    @param ffcInfo 挡板校零信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetFFCInfo(s32 userHandle, const FFCInfo* ffcInfo);

    /**
    获取模拟视频信息, 模拟视频信息也包含图像算法参数\流媒体参数.
    @param userHandle 用户句柄
    @param [out] tvoutInfo 模拟视频信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetTvoutInfo(s32 userHandle, TvoutInfo* tvoutInfo);

    /**
    设置模拟视频信息.
    @param userHandle 用户句柄
    @param tvoutInfo 模拟视频信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetTvoutInfo(s32 userHandle, const TvoutInfo* tvoutInfo);

    /**
    获取测温修正信息
    @param userHandle 用户句柄
    @param [out] fixInfo 测温修正信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetFixInfo(s32 userHandle, FixInfo* fixInfo);

    /**
    设置测温修正信息
    @param userHandle 用户句柄
    @param fixInfo 测温修正信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetFixInfo(s32 userHandle, const FixInfo* fixInfo);

    /**
    获取热像仪时间信息
    @param userHandle 用户句柄
    @param [out] cameraTimeInfo 时间信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetCameraTimeInfo(s32 userHandle, CameraTimeInfo* cameraTimeInfo);

    /**
    设置热像仪时间信息
    @param userHandle 用户句柄
    @param cameraTimeInfo 时间信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetCameraTimeInfo(s32 userHandle, const CameraTimeInfo* cameraTimeInfo);

    /**
    获取GPIO信息
    @param userHandle 用户句柄
    @param [out] gpioInfo GPIO信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetGpioInfo(s32 userHandle, GpioInfo* gpioInfo);

    /**
    设置GPIO信息
    @param userHandle 用户句柄
    @param gpioInfo GPIO信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetGpioInfo(s32 userHandle, const GpioInfo* gpioInfo);

    /**
    获取串口信息
    @param userHandle 用户句柄
    @param [out] serialPortInfo 串口信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetSerialPortInfo(s32 userHandle, SerialPortInfo* serialPortInfo);

    /**
    设置串口信息
    @param userHandle 用户句柄
    @param serialPortInfo 串口信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetSerialPortInfo(s32 userHandle, const SerialPortInfo* serialPortInfo);

    /**
    获取混合输出信息
    @param userHandle 用户句柄
    @param [out] cameraOutputInfo 串口信息
    @return 错误码
    */
    SDK_API s32 Yoseen_GetCameraOutputInfo(s32 userHandle, CameraOutputInfo* cameraOutputInfo);

    /**
    设置混合输出信息
    @param userHandle 用户句柄
    @param cameraOutputInfo 串口信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SetCameraOutputInfo(s32 userHandle, const CameraOutputInfo* cameraOutputInfo);

    SDK_API s32 Yoseen_GetCameraOSDInfo(s32 userHandle, CameraOSDInfo* osdInfo);
    SDK_API s32 Yoseen_SetCameraOSDInfo(s32 userHandle, const CameraOSDInfo* osdInfo);

    SDK_API s32 Yoseen_GetFPAInfoHK160(s32 userHandle, FPAInfoHK160* hk160);
    SDK_API s32 Yoseen_SetFPAInfoHK160(s32 userHandle, const FPAInfoHK160* hk160);

    SDK_API s32 Yoseen_GetCameraPluginInfo(s32 userHandle, CameraPluginInfo* info);
    SDK_API s32 Yoseen_SetCameraPluginInfo(s32 userHandle, const CameraPluginInfo* info);

    /**
    发送控制信息
    @param userHandle 用户句柄
    @param ctl 控制信息
    @return 错误码
    */
    SDK_API s32 Yoseen_SendControl(s32 userHandle, Ctl* ctl);

    /**
    发送控制信息X
    @param userHandle 用户句柄
    @param ctlx 控制信息x
    @return 错误码
    */
    SDK_API s32 Yoseen_SendControlX(s32 userHandle, CtlX* ctlx);

    /*
    发送串口数据到热像仪, 热像仪接收到数据, 直接写到串口
    @param userHandle 用户句柄
    @param spd 串口数据
    @return 错误码
    */
    SDK_API s32 Yoseen_WriteSerialPortData(s32 userHandle, const xxxserialportdata* spd);

    /*
    上传本地文件到热像仪, 用于热像仪程序更新、坏点补偿等
    @param userHandle 用户句柄
    @param fn 文件名称
    @param fileType 文件类型
    @return 错误码
    */
    SDK_API s32 Yoseen_UploadFile(s32 userHandle, const char* fn, s32 fileType);

    /*
    下载热像仪文件到本地, 用于热像仪日志分析等
    @param userHandle 用户句柄
    @param fn 文件名称
    @param fileType 文件类型
    @return 错误码
    */
    SDK_API s32 Yoseen_DownloadFile(s32 userHandle, const char* fn, s32 fileType);

    /*
    上传本地内存数据到热像仪, 用于设置测温模板
    @param userHandle 用户句柄
    @param memType 内存数据类型
    @param memData 内存数据指针
    @param memSize 内存数据大小
    @return 错误码
    */
    SDK_API s32 Yoseen_UploadMem(s32 userHandle, s32 memType, void* memData, s32 memSize);

    /*
    下载热像仪内存数据到本地, 用于获取测温模板
    @param userHandle 用户句柄
    @param memType 内存数据类型
    @param memData 内存数据指针
    @param memSize 内存数据大小
    @return 错误码
    */
    SDK_API s32 Yoseen_DownloadMem(s32 userHandle, s32 memType, void* memData, s32& memSize);

    //
    enum DeviceConfigType {
        //IR
        DeviceConfigType_CameraBasicInfo = 0,
        DeviceConfigType_CameraNetworkInfo,
        DeviceConfigType_FixInfo,
        DeviceConfigType_FFCInfo,
        DeviceConfigType_TvoutInfo,
        DeviceConfigType_CameraOutputInfo,//mix
        DeviceConfigType_CameraTimeInfo,
        DeviceConfigType_CameraOSDInfo,
        DeviceConfigType_GpioInfo,
        DeviceConfigType_SerialPortInfo,
        DeviceConfigType_CameraPluginInfo,//AuthCtl
        DeviceConfigType_DestripInfo,
        DeviceConfigType_DenoiseInfo,

        //
        DeviceConfigType_FPAInfo0   =   100,
        DeviceConfigType_FPAInfo1,
        DeviceConfigType_FPAInfo2,
        DeviceConfigType_FPAInfoAK0,
        DeviceConfigType_FPAInfoAK1,
        DeviceConfigType_FPAInfoAK2,
        DeviceConfigType_FPAInfoGD0,
        DeviceConfigType_FPAInfoGD1,
        DeviceConfigType_FPAInfoGD2,
        DeviceConfigType_FPAInfoCLW0,
        DeviceConfigType_FPAInfoCLW1,
        DeviceConfigType_FPAInfoCLW2,
        DeviceConfigType_FPAInfoUL,
        DeviceConfigType_FPAInfoHK160,

        //Box
        BoxConfigType_BoxInputInfo = 1000,
        BoxConfigType_BoxOutputInfo,
        BoxConfigType_BoxAlgInfo,
    };
    SDK_API s32 Yoseen_GetInfo(s32 userHandle, s32 configType, void* data, s32 dataSize);
    SDK_API s32 Yoseen_SetInfo(s32 userHandle, s32 configType, void* data, s32 dataSize);

    /*******************************************************************************************************
    *
    * 预览接口
    *
    *
    ********************************************************************************************************/

    /*
    开始预览, 一台热像仪能同时支持 "1对16的视频流预览" 和 "1对1的温度流" 预览.

    视频流预览, 后端接收到的是H264编码的图像数据和特征温度数据, 带宽要求低.

    温度流预览, 后端接收到的是全帧温度数据, 带宽要求高.

    @param userHandle 用户句柄
    @param previewInfo 预览信息
    @return >=0 预览句柄, <0 错误码
    */
    SDK_API s32 Yoseen_StartPreview(s32 userHandle, YoseenPreviewInfo* previewInfo);

    /*
    开始预览, 预览低分辨率的温度数据(小于160x120)时, 放大温度数据.
    只支持取数据，不支持显示.

    @param userHandle 用户句柄
    @param previewInfo 预览信息
    @param tempScale 温度数据放大, 支持2,3,4倍放大
    @return >=0 预览句柄, <0 错误码
    */
    SDK_API s32 Yoseen_StartPreviewTempScale(s32 userHandle, YoseenPreviewInfo* previewInfo, s32 tempScale);

    /*
    开始预览, 支持翻转90, 翻转180, 翻转270, X镜像, Y镜像
    只支持取数据，不支持显示.

    @param userHandle 用户句柄
    @param previewInfo 预览信息
    @param tempTransform 温度数据翻转
    @return >=0 预览句柄, <0 错误码
    */
    SDK_API s32 Yoseen_StartPreviewTempTransform(s32 userHandle, YoseenPreviewInfo* previewInfo, s32 tempTransform);

    /*
    开始预览,  按标准rtsp协议, 预览视频数据. 只需要可见光设备或红外设备支持rtsp协议.

    @param rtspInfo rtsp流信息
    @param previewInfo 预览信息
    @return >=0 预览句柄, <0 错误码
    */
    SDK_API s32 Yoseen_StartPreviewRtsp(YoseenRtspInfo* rtspInfo, YoseenPreviewInfo* previewInfo);

    /*
    停止预览
    @param previewHandle 预览句柄
    @return 错误码
    */
    SDK_API s32 Yoseen_StopPreview(s32 previewHandle);

    /*
    暂停预览
    @param previewHandle 预览句柄
    @param pause 0-非暂停, 1-暂停
    @return 错误码
    */
    SDK_API s32 Yoseen_PausePreview(s32 previewHandle, s32 pause);

    /*
    开始保存, 温度流预览支持保存.stream和.mp4文件, 视频流预览支持保存.mp4文件.
    @param previewHandle 预览句柄
    @param fileName 文件名
    @param fileType 文件类型
    @return 错误码
    */
    SDK_API s32 Yoseen_BeginSave(s32 previewHandle, const char* fileName, s32 fileType);

    SDK_API s32 Yoseen_BeginSaveStream(s32 previewHandle, const char* fileName, s32 timeDelta);

    /*
    停止保存
    @param previewHandle 预览句柄
    @param fileType 文件类型
    @return 错误码
    */
    SDK_API s32 Yoseen_EndSave(s32 previewHandle, s32 fileType);

    /*
    设置温度流预览, 温度转位图算法参数; 视频流预览使用Yoseen_SetTvoutInfo.
    @param previewHandle 预览句柄
    @param strechControl 温度转位图算法参数
    @param paletteType 调色板
    @return 错误码
    */
    SDK_API s32 Yoseen_PreviewSetImage(s32 previewHandle, const strech_control* strechControl, s32 paletteType);

    SDK_API s32 Yoseen_PreviewEnableMask(s32 previewHandle, s32 enable);

    SDK_API s32 Yoseen_PreviewSetDelay(s32 previewHandle, s32 manualDelay);

    /*******************************************************************************************************
    *
    * 回放接口
    *
    *
    ********************************************************************************************************/

    /*
    建立回放上下文
    @return 回放上下文
    */
    SDK_API YoseenPlaybackContext* YoseenPlayback_Create();

    /*
    释放回放上下文
    @param pp 回放上下文
    */
    SDK_API void YoseenPlayback_Free(YoseenPlaybackContext** pp);

    /*
    设置回放图像算法参数
    @param ctx 回放上下文
    @param sc 算法参数
    @param paletteType 调色板类型
    */
    SDK_API void YoseenPlayback_GetImage(YoseenPlaybackContext* ctx, strech_control* sc, s32* paletteType);

    /*
    获取回放图像算法参数
    @param ctx 回放上下文
    @param sc 算法参数
    @param paletteType 调色板类型
    */
    SDK_API void YoseenPlayback_SetImage(YoseenPlaybackContext* ctx, const strech_control* sc, const s32* paletteType);

    /*
    打开文件
    @param ctx 回放上下文
    @param fileName 文件名
    @param fileType 文件类型
    @return 错误码
    */
    SDK_API s32 YoseenPlayback_OpenFile(YoseenPlaybackContext* ctx, const char* fileName, s32 fileType);

    /*
    打开内存
    @param ctx 回放上下文
    @param dfh 温度数据帧头
    @param dfd 温度数据
    @return 错误码
    */
    SDK_API s32 YoseenPlayback_OpenMem(YoseenPlaybackContext* ctx, DataFrameHeader* dfh, s16* dfd);

    /*
    关闭文件
    @param ctx 回放上下文
    */
    SDK_API void YoseenPlayback_CloseFile(YoseenPlaybackContext* ctx);

    /*
    保存文件, 只支持单帧文件jpg
    @param ctx 回放上下文
    @param tff 封面数据
    @param fileName 文件名
    @return 错误码
    */
    SDK_API s32 YoseenPlayback_SaveFile(YoseenPlaybackContext* ctx, TempFrameFile* tff, const char* fileName);

    /*
    读取封面数据,
    @param ctx 回放上下文
    @param tff 封面数据
    @return 错误码
    */
    SDK_API s32 YoseenPlayback_ReadCover(YoseenPlaybackContext* ctx, TempFrameFile* tff);

    /*
    读取温度数据, 每次读取一帧, 位图数据重新生成.
    @param ctx 回放上下文
    @param frameIndex 帧序号
    @param dataFrame 数据帧
    @return 错误码
    */
    SDK_API s32 YoseenPlayback_ReadFrame(YoseenPlaybackContext* ctx, s32 frameIndex, DataFrame* dataFrame);

    //
    SDK_API s32 YoseenPlayback_ConfigDestrip(YoseenPlaybackContext* ctx, IRDestripConfig* config, s32 get_set);
    SDK_API s32 YoseenPlayback_ConfigDenoise(YoseenPlaybackContext* ctx, IRDenoiseConfig* config, s32 get_set);
    SDK_API int Util_SaveBGRA(void* bgra, s32 width, s32 height, const char* fn);
    SDK_API int Util_SaveGRAY(u8* gray, s32 width, s32 height, const char* fn, void* palette);
}

#endif


