#ifndef YEALINK_SDK_COMMON_H
#define YEALINK_SDK_COMMON_H
#include <stdlib.h>
#include <string.h>

typedef enum Yealink_HidInput
{
    Undefined,
    OffHook,
    Mute,
    Flash,
    Hold,
    Redial,
    Line,
    SpeakerPhone,
    Send,
    Reject,
    SpeedDial,
    VoiceMail,
    LedRinger,
    LineBusyTone,
    Key0,
    Key1,
    Key2,
    Key3,
    Key4,
    Key5,
    Key6,
    Key7,
    Key8,
    Key9,
    KeyStar,
    KeyPound,
    KeyDelete,
    KeyVolumeUp,
    KeyVolumeDown,
    KeyFastForward,
    KeyRewind,
    KeyScanNextTrack,
    KeyScanPreviousTrack,
    KeyStop,
    KeyPlayPause
} Yealink_HidInput;


/** For use with ConfigParams.cloudConfig_params */
typedef struct _ConfigParams_cloud
{
    /** if true, all network access is blocked. */
    bool blockAllNetworkAccess;

    const char* baseUrl_capabilities;


    const char* baseUrl_fw;


    const char* proxy;
} ConfigParams_cloud;

/** Parameters for configuring the SDK at initialization. */
typedef struct _Config_params
{
    /** Optional configuration of cloud access.Not support in this version ，Please set null. */
    ConfigParams_cloud* cloudConfig_params;
    /** For internal Yealink use. */
    void* reserved2;
} Config_params;





typedef enum _ReturnCode
{
    Return_Ok,// "Success")
    Device_Unknown, //"The device is not known")
    Device_Invalid,// "The device is invalid")
    Not_Supported, //"The device is not supported")
    Return_ParameterFail,// "One or more parameters are wrong")
    ProtectedSetting_Write,// "The setting you are attempting to write is protected")
    No_Information,// "No info available")
    NetworkRequest_Fail,// "Network failure")
    Device_WriteFail, //"Failed writing to the device")
    Device_ReadFails,// "Failed reading from the device")
    No_FactorySupported, //"Factory reset is not supported or allowed")
    System_Error,// "System error")
    Device_BadState,// "The device is in a bad state")
    FileWrite_Fail, //"Failed writing to file")
    File_AlreadyExists,// "The file already exists")
    File_Not_Accessible, //"The file is not accessible")
    Firmware_UpToDate, //"Firmware is up-to-date")
    Firmware_Available,// "Firmware is available")
    Return_Async, //"Asynch operation has started in the background")
    Invalid_Authorization,// "Authorization failure")
    Device_AlreadyConnected,// "The device is already connected")
    Device_NotConnected,// "The device is not connected")
    CannotClear_DeviceConnected,// "Unable to clear, the device has an active connection")
    Device_Rebooted,// "The device rebooted")
    Upload_AlreadyInProgress,// "Upload is already in progress")
    Download_AlreadyInProgress,// "Download is already in progress")
    Sdk_TooOldForFwUpdate, //"The Yealink SDK is too old to update the selected firmware")
    No_OtaUpdateSupport,// "Firmware update through OTA is not supported for this device")
    Non_Device_Detection_disabled,// "Non Yealink device detection is disabled")
    Preset_Count_Limit, // "The number of preset reaches limit"
    Preset_Not_Exist, // "The preset index not exist"
    Preset_Apply_Time_Out, // "The camera cannot rotate to the specified position, check position timeout timeout"
    Operation_Fail_SmartTracking_Enabled, // "Operation failed because smart tracking is enabled"
    Camera_Not_Ready, // "Camera not ready, operation not supported"
    Rcc_Disable_By_YUC,
    Other_Error,
    NUMBER_OF_RETURNCODES
} Yealink_ReturnCode;






typedef enum _ErrorStatus
{
    NoError,// "No Error")
    SSLError,// "SSL Handshake failed. Please contact your administrator")
    CertError,// "Failed to Authenticate Server Certificate. Please contact your administrator")
    NetworkError,// "Unable to download the files. Please check Internet connection and reconnect the device")
    DownloadError,// "Setting files download failed. Please contact your administrator")
    ParseError, //"Unable to retrieve device settings. Please reconnect device")
    OtherError, //"Unknown error. Please contact your administrator")
    DeviceInfoError, //"Unable to retrieve device information. Please reconnect device")
    FileNotAccessible,// "File is not accessible")
    FileNotCompatible, //"File is not compatible for the device")
    Device_NotFound,// "The specified device is not found")
    Parameter_fail,// "Incorrect parameters")
    Authorization_failed,// "Authorization failed")
    FileNotAvailable,// "Files are not available for the device. Please check internet connection and reconnect the device")
    ConfigParseError,// "Config XML parse error")
    SetSettings_Fail, //"Error in applying settings")
    Device_Reboot, //"Device will reboot due to change in the settings")
    Device_ReadFail,// "Unable to read settings from the device")
    Device_NotReady, //"The device is not ready")
    FilePartiallyCompatible,// "Partial Settings loaded")
    SdkTooOldForFwUpdateError, //"The Yealink SDK is too old to update the selected firmware")
    NUMBER_OF_YEALINK_ERRORCODES
} Yealink_ErrorStatus;


typedef enum _DeviceConnectionType
{
    USB = 0,
    BT
} DeviceConnectionType;

/** @brief Device description structure, identifies attached devices. */
typedef struct _DeviceInfo
{
    /** @brief Device identifier, used for most API calls to identify the device
    * to operate on. */
    unsigned short deviceID;
    /** @brief Product identifier, used for identifying the type of product. */
    unsigned short productID;
    /** @brief Vendor identifier, used for identifying the vendor. Yealink vendor
    * ID is 0x6993. */
    unsigned short vendorID;
    char* deviceName;
    char* usbDevicePath;
    char* parentInstanceId;
    Yealink_ErrorStatus errStatus;
    bool isDongle;
    char* dongleName;
    char* variant;
    char* serialNumber;
    /** @brief if in FireWareUpdateMode the sdk interface does not work,please not invoke*/
    bool isInFirmwareUpdateMode;
    DeviceConnectionType deviceconnection;
    unsigned long connectionId;
    unsigned short parentDeviceId;
} Yealink_DeviceInfo;

typedef struct _FirmwareInfo
{
    /** Version of firmware. */
    char *version;
    /** Size of firmware file in KB/MB. */
    char * fileSize;
    /** Release date of firmware. it is timestamp*/
    char *releaseDate;
    /** Firmware stage. */
    char *stage;
    /** Release notes of firmware. */
    wchar_t *releaseNotes;
} Yealink_FirmwareInfo;

typedef struct _FirmwareInfoList
{
    unsigned short count;
    Yealink_FirmwareInfo* items;
} Yealink_FirmwareInfoList;

/** This enum represents event type for callback. */
typedef enum  _FirmwareEventType
{
    Firmware_Download = 0,
    Firmware_Update
} Yealink_FirmwareEventType;

/** @todo needs to be consolidated with other result codes. */
typedef enum _FirmwareEventStatus
{
    Initiating = 0,
    InProgress,
    Completed,
    Cancelled,
    File_NotAvailable,
    File_NotAccessible,
    File_AlreadyPresent,
    Network_Error,
    SSL_Error,
    Download_Error,
    Update_Error,
    Invalid_Authentication,
    File_UnderDownload,
    Not_Allowed,
    Sdk_TooOldForUpdate
} Yealink_FirmwareEventStatus;

typedef enum  _LogEventType
{
    Log_Upload = 0,
    Log_Export
} Yealink_LogEventType;

typedef struct _timedate_t
{
    /** Seconds, range is [0-59]. */
    int sec;
    /** Minutes, range is [0-59]. */
    int min;
    /** Hours, range is [0-23]. */
    int hour;
    /** Day of month, range is [1-31]. */
    int mday;
    /** Month, range is [0-11]. */
    int mon;
    /** Year, range is [0-n], where 0 is 1900CE. */
    int year;
    /** Day of week, range is [0-6] where 0 is Sunday. */
    int wday;
} timedate_t;

typedef enum _Yealink_HidState
{
    /** Setting Standard HID or YL HID is not supported */
    NOT_SUPPORTED = 0,
    /** Use standard HID as specified in the HID specification from usb.org. */
    STD_HID = 1,
    /** Use YL HID as specified by YL. */
    YL_HID = 2
} Yealink_HidState;

/** @brief This enum represents each setting data type */
typedef enum _DataType
{
    settingShort = 0,
    settingString
} DataType;

/** @brief This enum represents each setting control type. */
typedef enum _ControlType
{
    cntrlRadio = 0,
    cntrlToggle,
    cntrlComboBox,
    cntrlDrpDown,
    cntrlLabel,
    cntrlTextBox,
    cntrlButton,
    cntrlUnknown
} ControlType;

typedef enum _DeviceFeature
{
    FeaFactoryReset = 1000,
    FeaReboot,
    FeaLogging,
    FeaSetDateTime,
    FeaBluetooth,
    FeaRemoteMMI,
    FeaBattery,
    FeaContact,
    FeaUploadRingtone,
    FeaPlayRingtone,
    FeaBusyLight,
    FeaExportAudio,
    FeaSettings,
    FeaCameraPTZ,
    FeaCameraPreset,
    FeaCameraFaceDetection,
    FeaCameraSmartTracking,
    FeaSetCurrentContact,
    FeaCallExtend,
    FeaMultiCameraMng,
    FeaRccMultiCall,
} DeviceFeature;

/** @brief This structure represents validation rules. */
typedef struct _ValidationRule
{
    int minLength;
    int maxLength;
    char* regExp;

    _ValidationRule()
    {
        minLength = 0;
        maxLength = 0;
        regExp = NULL;
    }
} ValidationRule;

typedef struct _DependencySetting
{
    char* GUID;
    bool enableFlag;

    _DependencySetting()
    {
        GUID = NULL;
        enableFlag = false;
    }
} DependencySetting;

/** @brief This structure contains setting values in key value pair. */
typedef struct _ListKeyValue
{
    unsigned short key;
    void* value;
    int dependentcount;
    DependencySetting* dependents;

    _ListKeyValue()
    {
        key = 0;
        value = NULL;
        dependentcount = 0;
        dependents = NULL;
    }
} ListKeyValue;

/** @brief This structure represents each setting info. */
typedef struct _SettingInfo
{
    /* Setting GUID */
    char* guid;


    /* Setting Name */
    char* name;

    /* Setting Help Text */
    char* helpText;

    /* Current Device value for this setting */
    void* currValue;

    /* Number of values for this setting */
    int listSize;

    /* Structure for all key-value pairs for this setting */
    ListKeyValue* listKeyValue;

    /* If validation rule is supported or not */
    bool isValidationSupport;

    /* This structure contains the validation rule */
    ValidationRule* validationRule;

    /* If device restart is required for this setting */
    bool isDeviceRestart;

    /* Is setting protected */
    bool isSettingProtected;

    /* Is setting protection enabled */
    bool isSettingProtectionEnabled;


    /* This represents what type of control for setting */
    ControlType cntrlType;

    /* This represents datatype of setting value */
    DataType settingDataType;


    /* This represents group name of the setting */
    char* groupName;

    /* This represents group help text of the setting */
    char* groupHelpText;

    /* Whether dependency setting is present or not */
    bool isDepedentsetting;

    /* Default dependent value when setting is disabled */
    void* dependentDefaultValue;

    _SettingInfo()
    {
        guid = NULL;
        name = NULL;
        helpText = NULL;
        currValue = NULL;
        listSize = 0;
        listKeyValue = NULL;
        isValidationSupport = false;
        validationRule = NULL;
        isDeviceRestart = false;
        isSettingProtected = false;
        isSettingProtectionEnabled = false;
        cntrlType = cntrlUnknown;
        settingDataType = settingShort;
        groupName = NULL;
        groupHelpText = NULL;
        isDepedentsetting = false;
        dependentDefaultValue = NULL;
    }

} SettingInfo;

/** @brief This structure represents all settings available for the device. */
typedef struct _DeviceSettings
{
    /* number of settings for the device */
    unsigned int settingCount;
    /* Setting information of all settings of the device */
    SettingInfo* settingInfo;

    _DeviceSettings()
    {
        settingCount = 0;
        settingInfo = NULL;
    }
} DeviceSettings;

typedef enum _DeviceListType
{
    SearchResult,
    PairedDevices,
    SearchComplete
} Yealink_DeviceListType;

/**
* Callback. Used with Yealink_SetSettingsChangeListener.
* @param deviceID the affected device
* @param settings the affected settings. Must be freed by Yealink_FreeDeviceSettings
*/
typedef void(*SettingsListener)(unsigned short deviceID, DeviceSettings* settings);

/** @brief Paired devices list structure. */
typedef struct _PairedDevice
{
    /** @brief Name of device, this is end-user editable i.e. it is not
     * necessarily the name of the product. */
    char* deviceName;
    /** @brief Bluetooth MAC address. */
    unsigned char deviceBTAddr[6];
    /** Current connection status. */
    bool isConnected;

    _PairedDevice()
    {
        deviceName = NULL;
        memset(deviceBTAddr, 0, sizeof(deviceBTAddr));
        isConnected = false;
    }
} Yealink_PairedDevice;

/** @brief List of paired devices list structure. */
typedef struct _PairingList
{
    /** Number of #Yealink_PairedDevice elements in the list. */
    unsigned short count;
    /** List type identifier. */
    Yealink_DeviceListType listType;
    /** Paired device information. */
    Yealink_PairedDevice* pairedDevice;
    _PairingList()
    {
        count = 0;
        listType = SearchResult;
        pairedDevice = NULL;
    }
} Yealink_PairingList;


/**
* Types of remote MMIs, use #Yealink_GetRemoteMmiTypes to determine the types
* supported for the device in question.
*/
typedef enum _RemoteMmiType
{
    MMI_TYPE_PC = 0,
    MMI_TYPE_PHONE = 1,
    MMI_TYPE_VOLUP = 2,
    MMI_TYPE_VOLDOWN = 3,
    MMI_TYPE_MUTE = 4,
    MMI_TYPE_HOOK = 5,
    MMI_TYPE_HOOK_OFF = 6,
    MMI_TYPE_HOOK_ON = 7,
    MMI_TYPE_BLUETOOTH = 8,
    MMI_TYPE_TEAMS = 9,
} RemoteMmiType;

/**
* Remote MMI sequences, used to identify supported output LEDs (as a bitmask)
* and for setting the output LEDs (single bit).
*/
typedef enum _RemoteMmiSequence
{
    MMI_LED_SEQUENCE_OFF = 0x01,
    MMI_LED_SEQUENCE_ON = 0x02,
    MMI_LED_SEQUENCE_SLOW = 0x04,
    MMI_LED_SEQUENCE_FAST = 0x08
} RemoteMmiSequence;

/**
* Remote MMI priorities.
*/
typedef enum _RemoteMmiPriority
{
    /**
    * Used for remote MMIs that does not support priority.
    */
    MMI_PRIORITY_NONE = 0x00,
    /**
    * Get remote MMI focus if device doesn't use it or no function is assigned
    * to the button.
    */
    MMI_PRIORITY_LOW = 0x01,
    /**
    * Get remote MMI focus unconditionally, this can remove important
    * functionality from the device.
    */
    MMI_PRIORITY_HIGH = 0x02
} RemoteMmiPriority;

/**
* Remote MMI action to use in #Yealink_SetRemoteMmiAction for setting the MMI
* output LED(s). Only single bit value of RemoteMmiSequence can be specified
* as parameter RemoteMmiActionOutput to #Yealink_SetRemoteMmiAction.
*/
typedef struct _RemoteMmiActionOutput
{
    /** Red LED output component to set. */
    unsigned char red;
    /** Green LED output component to set. */
    unsigned char green;
    /** Blue LED output component to set. */
    unsigned char blue;
    /** Output sequence to set. */
    RemoteMmiSequence sequence;
} RemoteMmiActionOutput;

/**
* Supported remote MMI output LED colours.
*/
typedef struct _RemoteMmiOutput
{
    /** Red LED supported. */
    bool red;
    /** Green LED supported. */
    bool green;
    /** Blue LED supported. */
    bool blue;
} RemoteMmiOutput;

/**
* Remote MMI input actions.
* Remote MMI input, used to identify supported input actions (as a bitmask)
* and for reporting input events via the RemoteMmiCallback callback
* (as single bit).
*/
typedef enum _RemoteMmiInput
{
    MMI_ACTION_NONE = 0x00,
    MMI_ACTION_CLICK = 0x01,
    MMI_ACTION_DBCLICK = 0x02,
    MMI_ACTION_BOUNCE = 0x04,
    MMI_ACTION_LONGPRE = 0x08,
    MMI_ACTION_LONGBOUNCE = 0x10,
} RemoteMmiInput;

/**
* Remote MMI definitions for the supported MMIs.
*/
typedef struct _RemoteMmiDefinition
{
    /** Supported type. */
    RemoteMmiType type;
    /** Mask of supported priorities. */
    RemoteMmiPriority priorityMask;
    /** Mask of supported output LED sequences. */
    RemoteMmiSequence sequenceMask;
    /** Mask of supported inputs. */
    RemoteMmiInput inputMask;
    /** Supported output LED colours. */
    RemoteMmiOutput output;
} RemoteMmiDefinition;

typedef struct _ContactInfoInfo
{
    char *name;
    char *number;

    _ContactInfoInfo()
    {
        name = NULL;
        number = NULL;
    }
} Yealink_ContactInfo;

typedef struct _ContactInfoList
{
    unsigned short count;
    Yealink_ContactInfo* items;

    _ContactInfoList()
    {
        count = 0;
        items = NULL;
    }
} Yealink_ContactInfoList;

/**
* @brief Type definition of function pointer to use for
* #Yealink_RegisterRemoteMmiCallBack.
*/
typedef void(*RemoteMmiCallback)(unsigned short deviceID, RemoteMmiType type, RemoteMmiInput action);

typedef enum _EqualizerMode
{
    Equalizer_Normal,
    Equalizer_Bass,
    Equalizer_Treble
} EqualizerMode;

typedef enum _WizardModes
{
    No_Wizard,
    Normal_Wizard,
} WizardModes;

typedef enum _BusylightStatus
{
    BUSYLIGHT_UNKNOWN = 0,
    BUSYLIGHT_RING,
    BUSYLIGHT_TALKING,
    BUSYLIGHT_HOLD,
    BUSYLIGHT_MUTE,
    BUSYLIGHT_DIALINNG,
    BUSYLIGHT_ONLINE,
    BUSYLIGHT_OFFLINE,
    BUSYLIGHT_LEFT,
    BUSYLIGHT_BUSY,
    BUSYLIGHT_NOT_DISTURB,
    BUSYLIGHT_OFFWORK,
} UsbBusylight;

typedef enum _AudioModes
{
    AM_HANDFREE,
    AM_HEADSET,
} AudioMode;

typedef struct _CameraPresetInfo
{
    unsigned short presetIndex;
    char* picPath;

    _CameraPresetInfo()
    {
        presetIndex = 0;
        picPath = NULL;
    }
} CameraPresetInfo;

typedef struct _DeviceCameraPresets
{
    unsigned int presetCount;
    CameraPresetInfo* presetInfo;

    _DeviceCameraPresets()
    {
        presetCount = 0;
        presetInfo = NULL;
    }
} Yealink_CameraPresetList;

typedef enum _CameraDirectionCmd
{
    CAMERA_DIR_STOP,
    CAMERA_DIR_UP,
    CAMERA_DIR_DOWN,
    CAMERA_DIR_LEFT,
    CAMERA_DIR_RIGHT
} CameraDirectionCmd;

typedef enum _CameraZoomCmd
{
    CAMERA_ZOOM_STOP,
    CAMERA_ZOOM_IN,
    CAMERA_ZOON_OUT
} CameraZoomCmd;

typedef enum _CameraSmartTrackingOpt
{
    CAMERA_SMART_TRACKING_DISABLE,
    CAMERA_AUTOFRAMING_TRACKING,
    CAMERA_VOICE_TRACKING,
    CAMERA_PRESENTER_TRACKING
} CameraSmartTrackingOpt;

typedef struct _CameraSmartTracking
{
    unsigned int optCount;
    CameraSmartTrackingOpt* optSmartTracking;

    _CameraSmartTracking()
    {
        optCount = 0;
        optSmartTracking = NULL;
    }
} Yealink_CameraSmartTrackingOptList;

typedef struct _CameraLayout
{
    unsigned int devId;
    unsigned int left;
    unsigned int top;
    unsigned int width;
    unsigned int height;

    _CameraLayout()
    {
        devId = 0;
        left = 0;
        top = 0;
        width = 0;
        height = 0;
    }
} Yealink_CameraLayout;

typedef struct _CameraLayoutList
{
    unsigned int count;
    Yealink_CameraLayout* layoutInfo;

    _CameraLayoutList()
    {
        count = 0;
        layoutInfo = NULL;
    }
} Yealink_CameraLayoutList;

typedef struct _Contact
{
    char* szUserName;
    char* szCompany;
    char* szOfficeNumber;
    char* szMobileNumber;
    char* szOthers;

    _Contact()
    {
        szUserName = NULL;
        szCompany = NULL;
        szOfficeNumber = NULL;
        szMobileNumber = NULL;
        szOthers = NULL;
    }
} Yealink_ContactData;

typedef struct _ContactList
{
    unsigned short nSum;
    Yealink_ContactData* pItem;

    _ContactList()
    {
        nSum = 0;
        pItem = NULL;
    }
} Yealink_ContactDataList;
#endif // YEALINK_SDK_COMMON_H
