#ifndef LIBDevice_H_
#define LIBDevice_H_

#include <LibHK/HKNET.h>
#include <LibHK/HKISAPI.h>
#include <YoseenSDK/YoseenAlg_Strech.h>

//
enum EPtzConnType {
    EPtzConnType_IR = 0,
    EPtzConnType_VIS,
};

struct DeviceConfig {
    char ir_ip[16];
    char vis_ip[16];
    char vis_username[32];
    char vis_password[32];
    s32 ptzconntype;
    s32 timeout;//ms
};

struct ImageConfig {
    s32 palette_type;
    strech_control sc;
};

//
#define PresetConfig_PresetCountMax    500
struct Preset {
    char name[64];
    s32 pan;
    s32 tilt;
    s32 zoom;

    s32 pad[5];
};

struct PresetConfig {
    Preset presetArray[PresetConfig_PresetCountMax];
};

//
struct DeviceFrame {
    u16 width;
    u16 height;
    s32 pad;
    void* tempHead;
    void* temp;
    void* bmp;
};
typedef void(__stdcall* callback_onDeviceFrame)(s32 errorCode, DeviceFrame* frame, void* custom);

enum EStreamType {
    EStreamType_None = 0,
    EStreamType_Temp,
    EStreamType_Video,
    EStreamType_Rtsp
};
struct DevicePreviewInfo {
    void* userData;

    s32 ir_streamType;
    s32 ir_pad;
    void* ir_hwnd;
    callback_onDeviceFrame ir_onFrame;

    s32 vis_streamType;
    s32 vis_pad;
    void* vis_hwnd;
    callback_onDeviceFrame vis_onFrame;

    //
    u16 ir_width;
    u16 ir_height;
    u16 vis_width;
    u16 vis_height;
};

enum EFileType {
    EFileType_mp4 = 0,
    EFileType_stream,
    EFileType_jpg
};

//
enum DeviceContextFlags {
    //
    DeviceContextFlags_IR_Login = 0x00000001,
    DeviceContextFlags_IR_Preview = 0x00000002,
    DeviceContextFlags_IR_Record = 0x00000004,

    DeviceContextFlags_VIS_Login = (DeviceContextFlags_IR_Login << 8),
    DeviceContextFlags_VIS_Preview = (DeviceContextFlags_IR_Preview << 8),
    DeviceContextFlags_VIS_Record = (DeviceContextFlags_IR_Record << 8),

    //combine
    DeviceContextFlags_IR_Login_Preview = DeviceContextFlags_IR_Login | DeviceContextFlags_IR_Preview,
    DeviceContextFlags_VIS_Login_Preview = DeviceContextFlags_VIS_Login | DeviceContextFlags_VIS_Preview,
    DeviceContextFlags_IR_Preview_Record = DeviceContextFlags_IR_Preview | DeviceContextFlags_IR_Record,
    DeviceContextFlags_VIS_Preview_Record = DeviceContextFlags_VIS_Preview | DeviceContextFlags_VIS_Record,
};

enum PTZFlags {
    PTZFlags_Pan = 0x01,
    PTZFlags_Tilt = 0x02,
    PTZFlags_Zoom = 0x04,

    //
    PTZFlags_All = PTZFlags_Pan | PTZFlags_Tilt | PTZFlags_Zoom
};

struct _DeviceContext;
typedef struct _DeviceContext DeviceContext;

extern "C" {
    /*
    * init sdk, yoseensdk libhk log
    */
    SDK_API s32 Device_InitSDK();

    /*
    * free sdk
    */
    SDK_API void Device_FreeSDK();

    /*
    * create device context
    *
    * @return device context
    */
    SDK_API DeviceContext* Device_Create();

    /*
    * free device context
    */
    SDK_API void Device_Free(DeviceContext** pp);

    /*
    * open preset config file
    *
    * @param context
    * @param fn
    * @param config
    * @return EError_XXX
    */
    SDK_API s32 Device_PresetOpenConfig(DeviceContext* context, const char* fn, PresetConfig** config);

    /*
    * close preset config file
    *
    * @param context
    * @return EError_XXX
    */
    SDK_API void Device_PresetCloseConfig(DeviceContext* context);

    /*
    * save preset to memory and file
    *
    * @param context
    * @param preset
    * @param presetId
    * @return EError_XXX
    */
    SDK_API s32 Device_PresetSave(DeviceContext* context, Preset* preset, s32 presetId);

    /*
    * get preset by presetId, then Device_SetPTZ
    *
    * @param context
    * @param presetId
    * @return EError_XXX
    */
    SDK_API s32 Device_PresetGoto(DeviceContext* context, s32 presetId);

    /*
    * set device config
    *
    * @param context
    * @param config
    * @return EError_XXX
    */
    SDK_API s32 Device_SetDeviceConfig(DeviceContext* context, DeviceConfig* config);

    /*
    * login
    *
    * @param context
    * @return <0 EError_XXX, >=0 DeviceContextFlags_XXX
    */
    SDK_API s32 Device_Login(DeviceContext* context);

    /*
    * logout
    *
    * @param context
    * @return <0 EError_XXX, >=0 DeviceContextFlags_XXX
    */
    SDK_API s32 Device_Logout(DeviceContext* context);

    /*
    * manual start move, zoom, switch
    *
    * @param context
    * @param act PtzAction_XXX
    * @param arg [0,255]
    * @return EError_XXX
    */
    SDK_API s32 Device_PTZControlStart(DeviceContext* context, s32 act, s32 arg);

    /*
    * manual stop move, zoom, switch
    *
    * @param context
    * @param act PtzAction_XXX
    * @param arg [0,255]
    * @return EError_XXX
    */
    SDK_API s32 Device_PTZControlStop(DeviceContext* context, s32 act, s32 arg);

    /*
    * only for B160 and B110
    *
    * @param context
    * @param w data for write
    * @param r data for read
    * @return EError_XXX
    */
    SDK_API s32 Device_PTZW4R4(DeviceContext* context, s32 w, s32& r);

    /*
    * set pan-tilt-zoom
    *
    * @param context
    * @param pan 0.01, [0-36000), <0 omit
    * @param tilt 0.01, <0 omit
    * @param zoom 0.1, <0 omit
    * @return PTZFlags_XXX
    */
    SDK_API s32 Device_SetPTZ(DeviceContext* context, s32 pan, s32 tilt, s32 zoom);

    /*
    * get pan-tilt-zoom
    *
    * @param context
    * @param pan 0.01, [0-36000)
    * @param tilt 0.01
    * @param zoom 0.1
    * @return PTZFlags_XXX
    */
    SDK_API s32 Device_GetPTZ(DeviceContext* context, s32& pan, s32& tilt, s32& zoom);

    /*
    * set image config, only for ir temp preview
    *
    * @param context
    * @param config
    * @return EError_XXX
    */
    SDK_API s32 Device_IRSetImageConfig(DeviceContext* context, ImageConfig* config);

    /*
    * save frame, not depend on preview
    *
    * @param context
    * @param fn
    * @return EError_XXX
    */
    SDK_API s32 Device_IRSaveFrame(DeviceContext* context, const char* fn);

    SDK_API s32 Device_IRSendControl(DeviceContext* context, Ctl* ctl);
    SDK_API s32 Device_IRSendControlX(DeviceContext* context, CtlX* ctlx);

    /*
    * save frame vis, not depend on preview
    *
    * @param context
    * @param fn
    * @return EError_XXX
    */
    SDK_API s32 Device_VISSaveFrame(DeviceContext* context, const char* fn);

    /*
    */
    SDK_API s32 Device_VISVoiceTalkStart(DeviceContext* context);
    SDK_API s32 Device_VISVoiceTalkSetVolumn(DeviceContext* context, s32 volumn);
    SDK_API s32 Device_VISVoiceTalkStop(DeviceContext* context);

    /*
    * start preview
    *
    * @param context
    * @param previewInfo
    * @return <0 EError_XXX, >=0 DeviceContextFlags_XXX
    */
    SDK_API s32 Device_StartPreview(DeviceContext* context, DevicePreviewInfo* previewInfo);

    /*
    * stop preview
    *
    * @param context
    * @return <0 EError_XXX, >=0 DeviceContextFlags_XXX
    */
    SDK_API s32 Device_StopPreview(DeviceContext* context);

    /*
    * begin save
    *
    * @param context
    * @param fn base filename, suffix (_ir.mp4\_vis.mp4\_ir.stream) will be added.
    * #param ft EFileType_XXX
    * @return <0 EError_XXX, >=0 DeviceContextFlags_XXX
    */
    SDK_API s32 Device_BeginSave(DeviceContext* context, const char* fn, s32 ft);

    /*
    * end save
    *
    * @param context
    * @return <0 EError_XXX, >=0 DeviceContextFlags_XXX
    */
    SDK_API s32 Device_EndSave(DeviceContext* context);
}

#endif
