/*********************************************************************************************************
* 2023-11-03
* add usb, add Binning 
*
* 2022-09-06
* remove callback in MVSConfig, add mvsSetCallback. add color convert.
* 
* 2022-08-31
* add PixelFormat to MVSParam, MVSOutput
*
*
*
*********************************************************************************************************/
#ifndef HKMVS_H
#define HKMVS_H

#include "HKMVS_Types.h"

//
enum MVSError {
    MVSError_NeedEnumDevices = -1000,
    MVSError_CreateHandle,
    MVSError_OpenDevice,
    MVSError_StartGrabbing,
    MVSError_RegisterCallBack,

    MVSError_GetValue,
    MVSError_SetValue,
    MVSError_StartRecord,
};

struct MVSConfig {
    //20231103
    s32 devicetype;//MV_GIGE_DEVICE=1, MV_USB_DEVICE=4
    s32 openMode;//MV_ACCESS_Exclusive, MV_ACCESS_Control, MV_ACCESS_Monitor
    union {
        char ip[16];
        char usb[16];//DeviceUserID
    };
    char username[16];
    char password[16];
};

struct MVSParam {
    s32 Width;//宽度
    s32 Height;//高度
    s32 OffsetX;//水平偏移
    s32 OffsetY;//垂直偏移
    s32 ReverseX;//水平镜像
    s32 ReverseY;//垂直镜像
    s32 PixelFormat;//像素格式

    s32 AcquisitionFrameRateEnable;//使能采集帧率控制
    float AcquisitionFrameRate;//采集帧率

    s32 ExposureAuto;//自动曝光 0 Off, 1 Once, 2 Continuous
    s32 ExposureMode;//曝光模式 0 Standard
    float  ExposureTime;//曝光时间 us

    s32 GainAuto;//自动增益 0 Off, 1 Once, 2 Continuous
    float Gain;//增益 0,14.9703

    s32 GammaEnable;//伽马矫正使能
    s32 GammaSelector;//伽马矫正选择器 1 User, 2 sRGB
    float Gamma;//伽马矫正值 0,4

    s32 SharpnessEnable;//锐度使能
    s32 Sharpness;//锐度值 0,100

    s32 HDREnable;//高动态范围使能
    s32 HDRSelector;//高动态范围选择器 0-3
    s32 HDRShutter;//高动态范围快门（us）, 38
    float HDRGain;//高动态范围增益 0, 14.9703

    s32 BalanceWhiteAuto;//自动白平衡 0 Off, 1 Continuous, 2 Once
    s32 BalanceRatioSelector;//白平衡选择器 0 Red, 1 Green, 2 Blue
    s32 BalanceRatio;//白平衡比 1，4095

    //20231103,binning
    s32 BinningHorizontal;//1,2,4
    s32 BinningVertical;//1,2,4
    s32 pad[8];
};

enum MVSRegType {
    MVSRegType_int = 0,		//s64
    MVSRegType_float,
    MVSRegType_bool,
    MVSRegType_string,
    MVSRegType_enum,		//u32
    MVSRegType_cmd,

    MVSRegType_none = 1024,
};

struct MVSOutput {
    u16 width;
    u16 height;
    u32 format;
    u32 fps;
};

struct MVSDeviceInfo {
    //20231103
    s32 devicetype;
    union {
        char ip[16];
        char usb[16];//DeviceUserID
    };
    char subnetmask[16];
    char gateway[16];
    u8 sn[16];
};

enum MVSWorkFunc {
    MVSWorkFunc_ConvertBGRA = 0x0001,
};

struct _MVSContext;
typedef struct _MVSContext MVSContext;
extern "C" {
    //
    SDK_API s32 mvsStaticInit(const char* libDir);
    SDK_API void mvsStaticFree();

    SDK_API s32 mvsStaticEnumDevices(s32 deviceType, MV_CC_DEVICE_INFO_LIST** pp);
    SDK_API void mvsStaticMakeInfo(MV_CC_DEVICE_INFO* src, MVSDeviceInfo* dst);

    //
    SDK_API MVSContext* mvsCreate();
    SDK_API void mvsFree(MVSContext** pp);

    //
    SDK_API s32 mvsSetConfig(MVSContext* context, MVSConfig* config);

    SDK_API s32 mvsOpenDevice(MVSContext* context);
    SDK_API void mvsCloseDevice(MVSContext* context);

    SDK_API void mvsSetCallback(MVSContext* context, void* userData, callback_onFrame2 onFrame, callback_onException cbExp);

    /**
    * bgraData valid in callback_onFrame2, when workFunc & MVSWorkFunc_ConvertBGRA.
    *
    */
    SDK_API s32 mvsStartWork(MVSContext* context, s32 workFunc, MVSOutput* output);
    SDK_API void mvsStopWork(MVSContext* context);

    //
    SDK_API s32 mvsStartRecord(MVSContext* context, const char* fn);
    SDK_API void mvsStopRecord(MVSContext* context);

    //
    SDK_API s32 mvsGetValue(MVSContext* context, const char* regName, s32 regType, void* regData);
    SDK_API s32 mvsSetValue(MVSContext* context, const char* regName, s32 regType, void* regData);
    SDK_API s32 mvsGetParam(MVSContext* context, MVSParam* param);
    SDK_API s32 mvsSetParam(MVSContext* context, MVSParam* param);
}

#endif