/**
 * @file BF07.h
 * 
 * BF07
 * 
 * This file includes functions for communication with BF07.
 * 
 * BeFREE 07 (BF07) is a touchcomputer with integrated intercom, handset and programmable keys.
 * 
 * Tipro
 * 
 * support@tipro.si
 * 
 * Copyright 2021
 */
 
#ifndef _TIPRO_TIPROHIDAPI_BF07_H_
#define _TIPRO_TIPROHIDAPI_BF07_H_

#include "TiproHidDevice.h"

#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************************/
/*		BF07 DEFINES														*/
/****************************************************************************/

// Handsfree speaker levels
#define SBX_SPK_LEVEL_MIN						0x00 /**< Speaker level 0 - minimum */
#define SBX_SPK_LEVEL_MAX						0x14 /**< Speaker level 20 - maximum */

// PTT LED State
#define BF07_PTT_LED_OFF						0x00 /**< PTT LED is off. */
#define BF07_PTT_LED_ON							0x10 /**< PTT LED lights. */
#define BF07_PTT_LED_BLINK						0x20 /**< PTT LED blinks. */

// Handset speaker levels
#define BF07_HANDSET_SPEAKER_LEVEL_P4			0x00 /**< Handset speaker level +4 (maximum) */
#define BF07_HANDSET_SPEAKER_LEVEL_P3			0x01 /**< Handset speaker level +3 */
#define BF07_HANDSET_SPEAKER_LEVEL_P2			0x02 /**< Handset speaker level +2 */
#define BF07_HANDSET_SPEAKER_LEVEL_P1			0x03 /**< Handset speaker level +1 */
#define BF07_HANDSET_SPEAKER_LEVEL_0			0x03 /**< Handset speaker level 0 */
#define BF07_HANDSET_SPEAKER_LEVEL_M1			0x04 /**< Handset speaker level -1 */
#define BF07_HANDSET_SPEAKER_LEVEL_M2			0x05 /**< Handset speaker level -2 */
#define BF07_HANDSET_SPEAKER_LEVEL_M3			0x06 /**< Handset speaker level -3 */
#define BF07_HANDSET_SPEAKER_LEVEL_M4			0x07 /**< Handset speaker level -4 */
#define BF07_HANDSET_SPEAKER_LEVEL_M5			0x08 /**< Handset speaker level -5 */
#define BF07_HANDSET_SPEAKER_LEVEL_M6			0x09 /**< Handset speaker level -6 */
#define BF07_HANDSET_SPEAKER_LEVEL_M7			0x0A /**< Handset speaker level -7 (minimum) */
#define BF07_HANDSET_HEADSET_ILLEGAL			0xFF

#define BF07_HANDSET_HEADSET_MIN				BF07_HANDSET_SPEAKER_LEVEL_P4
#define BF07_HANDSET_HEADSET_MAX				BF07_HANDSET_SPEAKER_LEVEL_M7

// Alert line modes
#define BF07_ALERT_AS_ALERT						0x00 /**< Alert line mode - When handset is off-hook: Voice(Left) is switched to handset and Alert(Right) stays always on speakers */
#define BF07_ALERT_AS_VOICE						0x01 /**< Alert line mode - When handset is off-hook: Voice(Left) and Alert(Right) are switched to handset */
#define BF07_ALERT_NOT_USED						0x02 /**< Alert line mode - When handset is off-hook: Voice(Left) is switched to handset and Alert(Right) is muted */
// mode not defined
#define	BF07_ALERT_ILLEGAL						0xFF

// Devices 
#define BF07_DEVICE_HANDSFREE					0x00 /**< Handsfree device - Left and right speaker and gooseneck microphone */
#define BF07_DEVICE_HANDSET						0x01 /**< Handset device */
#define BF07_DEVICE_HANDSFREE_HANDSET			0x04 /**< Handsfree and handset device */
#define BF07_DEVICE_ILLEGAL						0xFF

// Microphone level (attenuation)
#define BF07_MIC_LEVEL_P3						0x10 /**< Microphone attenuation level +3 (maximum) */
#define BF07_MIC_LEVEL_P2						0x11 /**< Microphone attenuation level +2 */
#define BF07_MIC_LEVEL_P1						0x12 /**< Microphone attenuation level +1 */
#define BF07_MIC_LEVEL_0						0x13 /**< Microphone attenuation level 0 */
#define BF07_MIC_LEVEL_M1						0x14 /**< Microphone attenuation level -1 */
#define BF07_MIC_LEVEL_M2						0x15 /**< Microphone attenuation level -2 */
#define BF07_MIC_LEVEL_M3						0x16 /**< Microphone attenuation level -3 */
#define BF07_MIC_LEVEL_M4						0x17 /**< Microphone attenuation level -4 */
#define BF07_MIC_LEVEL_M5						0x18 /**< Microphone attenuation level -5 */
#define BF07_MIC_LEVEL_M6						0x19 /**< Microphone attenuation level -6 */
#define BF07_MIC_LEVEL_M7						0x1A /**< Microphone attenuation level -7 */
#define BF07_MIC_LEVEL_M8						0x1B /**< Microphone attenuation level -8 */
#define BF07_MIC_LEVEL_M9						0x1C /**< Microphone attenuation level -9 */
#define BF07_MIC_LEVEL_M10						0x1D /**< Microphone attenuation level -10 */
#define BF07_MIC_LEVEL_M11						0x1E /**< Microphone attenuation level -11 (minimum) */

#define BF07_MIC_LEVEL_MIN						BF07_MIC_LEVEL_P3
#define BF07_MIC_LEVEL_MAX						BF07_MIC_LEVEL_M11

// Microphone noise threshold
#define BF07_MIC_THRESHOLD_HIGH					0x10 /**< Microphone noise threshold high */
#define BF07_MIC_THRESHOLD_MID					0x11 /**< Microphone noise threshold mid */
#define BF07_MIC_THRESHOLD_LOW					0x12 /**< Microphone noise threshold low */
#define BF07_MIC_THRESHOLD_LOWER				0x13 /**< Microphone noise threshold lower */
#define BF07_MIC_THRESHOLD_VERY_LOW				0x14 /**< Microphone noise threshold very low */

#define BF07_MIC_THRESHOLD_MIN					BF07_MIC_THRESHOLD_HIGH
#define BF07_MIC_THRESHOLD_MAX					BF07_MIC_THRESHOLD_VERY_LOW

// Microphone compression
#define BF07_MIC_COMPRESSION_OFF				0x10 /**< Microphone compression off */
#define BF07_MIC_COMPRESSION_ON					0x11 /**< Microphone compression on */

#define BF07_MIC_COMPRESSION_MIN				BF07_MIC_COMPRESSION_OFF
#define BF07_MIC_COMPRESSION_MAX				BF07_MIC_COMPRESSION_ON

// Microphone optimal distance
#define BF07_MIC_DISTANCE_M2					0x0A /**< Microphone preamplifier level -2 (minimum) */
#define BF07_MIC_DISTANCE_M1					0x0B /**< Microphone preamplifier level -1 */
#define BF07_MIC_DISTANCE_0						0x0C /**< Microphone preamplifier level 0 */
#define BF07_MIC_DISTANCE_P1					0x0D /**< Microphone preamplifier level +1 */
#define BF07_MIC_DISTANCE_P2					0x0E /**< Microphone preamplifier level +2 */
#define BF07_MIC_DISTANCE_P3					0x0F /**< Microphone preamplifier level +3 */
#define BF07_MIC_DISTANCE_P4					0x10 /**< Microphone preamplifier level +4 */
#define BF07_MIC_DISTANCE_P5					0x11 /**< Microphone preamplifier level +5 */
#define BF07_MIC_DISTANCE_P6					0x12 /**< Microphone preamplifier level +6 */
#define BF07_MIC_DISTANCE_P7					0x13 /**< Microphone preamplifier level +7 */
#define BF07_MIC_DISTANCE_P8					0x14 /**< Microphone preamplifier level +8 (maximum) */

#define BF07_MIC_DISTANCE_VERY_SHORT			BF07_MIC_DISTANCE_0 /**< Very short distance */
#define BF07_MIC_DISTANCE_SHORT					BF07_MIC_DISTANCE_P2 /**< Short distance */
#define BF07_MIC_DISTANCE_MEDIUM				BF07_MIC_DISTANCE_P4 /**< Medium distance */
#define BF07_MIC_DISTANCE_LONG					BF07_MIC_DISTANCE_P6 /**< Long distance */

#define BF07_MIC_DISTANCE_MIN					BF07_MIC_DISTANCE_M2
#define BF07_MIC_DISTANCE_MAX					BF07_MIC_DISTANCE_P8

// Echo cancellation state
#define BF07_EC_OFF								0x0F /**< Echo canceller disabled. */
#define BF07_EC_ON								0x1F /**< Echo canceller enabled. */
#define BF07_EC_NOT_PRESENT						0xFF

// Showing microphone signal on VU meter
#define BF07_VU_MIC_OFF							0x3C /**< Signal from microphone not added to analogue line in. */
#define BF07_VU_MIC_ON							0x3D /**< Signal from microphone added to analogue line in. */

// Handset sidetone level
#define BF07_SIDETONE_LEVEL_M1					0x00 /**< Handset sidetone level -1 (maximum) */
#define BF07_SIDETONE_LEVEL_M2					0x01 /**< Handset sidetone level -2 */
#define BF07_SIDETONE_LEVEL_M3					0x02 /**< Handset sidetone level -3 */
#define BF07_SIDETONE_LEVEL_M4					0x03 /**< Handset sidetone level -4 */
#define BF07_SIDETONE_LEVEL_M5					0x04 /**< Handset sidetone level -5 */
#define BF07_SIDETONE_LEVEL_M6					0x05 /**< Handset sidetone level -6 */
#define BF07_SIDETONE_LEVEL_M7					0x06 /**< Handset sidetone level -7 */
#define BF07_SIDETONE_LEVEL_M8					0x07 /**< Handset sidetone level -8 */
#define BF07_SIDETONE_LEVEL_M9					0x08 /**< Handset sidetone level -9 (minimum) */
#define BF07_SIDETONE_OFF						0xFE /**< Handset sidetone disabled. */
#define BF07_SIDETONE_ILLEGAL					0xFF
// limits to check
#define BF07_SIDETONE_MIN						BF07_SIDETONE_LEVEL_M1
#define BF07_SIDETONE_MAX						BF07_SIDETONE_LEVEL_M9

// Emulate keys
#define BF07_KEY_PTT_HANDSFREE					0x01 /**< Handsfree PTT button */
#define BF07_KEY_PTT_HANDSET					0x02 /**< Handset PTT button */
#define BF07_KEY_HOOK							0x03 /**< Handset hook switch */

// VU meter scenario
#define BF07_VU_SPK_L							0x33 /**< Voice(Left) signal is shown on VU meter. */
#define BF07_VU_SPK_LR							0x37 /**< Voice(Left) and Alert(Right) signals are shown on VU meter. */

// Key status
#define BF07_HANDSET_ONHOOK						0x80 /**< Handset is onhook. */
#define BF07_HANDSET_OFFHOOK					0x00 /**< Handset is offhook. */

#define BF07_KEY_PRESSED						0x80 /**< Key is pressed. */
#define BF07_KEY_RELEASED						0x00 /**< Key is released. */



/****************************************************************************/
/*		BF07 FUNCTIONS														*/
/****************************************************************************/

/**
 * @brief Sets the level of the speakers
 * @param[in] device Device
 * @param[in] nLevel Speaker level
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetSpeakerLevel(TiproHidDevice *device, int nLevel);

/**
 * @brief Returns the level of the speakers
 * @param[in] device Device
 * @param[out] nLevel Speaker level
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetSpeakerLevel(TiproHidDevice *device, int *nLevel);

/**
 * @brief Sets the LED state of PTT key
 * @param[in] device Device
 * @param[in] nState State of the LED (LED_ON/LED_OFF/LED_BLINK)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetPTTLEDState(TiproHidDevice *device, int nState);

/**
 * @brief Returns the LED state of the PTT key
 * @param[in] device Device
 * @param[out] nState State of the LED (LED_ON/LED_OFF/LED_BLINK)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetPTTLEDState(TiproHidDevice *device, int *nState);

/**
 * @brief Sets the level of the handset spekaer
 * @param[in] device Device
 * @param[in] nLevel Handset speaker level
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetHandsetSpeakerLevel(TiproHidDevice *device, int nLevel);

/**
 * @brief Returns the current level of the handset speaker
 * @param[in] device Device
 * @param[out] nLevel Handset speaker level
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetHandsetSpeakerLevel(TiproHidDevice *device, int *nLevel);

/**
 * @brief Sets the function (mode) of the alert line
 * @param[in] device Device
 * @param[in] nMode Mode (ALERT, VOICE, NOT USED)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetAlertLine(TiproHidDevice *device, int nMode);

/**
 * @brief Returns the function (mode) of the alert line
 * @param[in] device Device
 * @param[out] nMode Mode (ALERT, VOICE, NOT USED)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetAlertLine(TiproHidDevice *device, int *nMode);

/**
 * @brief Sets the level of the microphone signal
 * @param[in] device Device
 * @param[in] nLevel Microphone level
 * @param[in] nDevice Device to set (handsfree, handset)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetMicrophoneLevel(TiproHidDevice *device, int nLevel, int nDevice);

/**
 * @brief Returns the level of microphone signal
 * @param[in] device Device
 * @param[out] nLevel Microphone level
 * @param[in] nDevice Device to get (handsfree, handset)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetMicrophoneLevel(TiproHidDevice *device, int *nLevel, int nDevice);

/**
 * @brief Sets the microphone threshold
 * @param[in] device Device
 * @param[in] nThreshold Microphone threshold
 * @param[in] nDevice Device to set (handsfree, handset)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetMicrophoneThreshold(TiproHidDevice *device, int nThreshold, int nDevice);

/**
 * @brief Returns microphone threshold
 * @param[in] device Device
 * @param[out] nThreshold Microphone threshold
 * @param[in] nDevice Device to get (handsfree, handset)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetMicrophoneThreshold(TiproHidDevice *device, int *nThreshold, int nDevice);

/**
 * @brief Sets the microphone compression
 * @param[in] device Device
 * @param[in] nCompression Microphone compression
 * @param[in] nDevice Device to set (handsfree, handset)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetMicrophoneCompression(TiproHidDevice *device, int nCompression, int nDevice);

/**
 * @brief Returns microphone compression
 * @param[in] device Device
 * @param[out] nCompression Microphone compression
 * @param[in] nDevice Device to set (handsfree, handset)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetMicrophoneCompression(TiproHidDevice *device, int *nCompression, int nDevice);

/**
 * @brief Sets the optimal distance for the microphone
 * @param[in] device Device
 * @param[in] nDistance Microphone optimal distance
 * @param[in] nDevice Device to set (handsfree, handset)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetMicrophoneOptimalDistance(TiproHidDevice *device, int nDistance, int nDevice);

/**
 * @brief Returns the optimal distance of the microphone
 * @param[in] device Device
 * @param[out] nDistance Microphone optimal distance
 * @param[in] nDevice Device to set (handsfree, handset)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetMicrophoneOptimalDistance(TiproHidDevice *device, int *nDistance, int nDevice);

/**
 * @brief Sets the LED blink timings
 * @param[in] device Device
 * @param[in] nTBlinkA ON time in ms (1..65000)
 * @param[in] nTBlinkB OFF time in ms (1..65000)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetLEDBlinkSpeed(TiproHidDevice *device, int nTBlinkA, int nTBlinkB);

/**
 * @brief Get LED blink timings
 * @param[in] device Device
 * @param[out] nTBlinkA ON time in ms (1..65000)
 * @param[out] nTBlinkB OFF time in ms (1..65000)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetLEDBlinkSpeed(TiproHidDevice *device, int *nTBlinkA, int *nTBlinkB);

/**
 * @brief Disables touchscreen
 * @param[in] device Device
 * @return Command status: 0-OK, else error code
 */
int TiproBF07TouchscreenDisable(TiproHidDevice *device);

/**
 * @brief Enables touchscreen
 * @param[in] device Device
 * @return Command status: 0-OK, else error code
 */
int TiproBF07TouchscreenEnable(TiproHidDevice *device);

/**
 * @brief Disables echo canceler
 * @param[in] device Device
 * @return Command status: 0-OK, else error code
 */
int TiproBF07DisableEcho(TiproHidDevice *device);

/**
 * @brief Enables echo canceler if present
 * @param[in] device Device
 * @return Command status: 0-OK, else error code
 */
int TiproBF07EnableEcho(TiproHidDevice *device);

/**
 * @brief Returns echo state
 * @param[in] device Device
 * @param[out] nState Echo state (ON/OFF/NOT_PRESENT)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetEchoState(TiproHidDevice *device, int *nState);

/**
 * @brief Sets if microphone level is shown on the VU-meter (ON/OFF)
 * @param[in] device Device
 * @param[in] nState Microphone on VU-meter state (ON/OFF)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetMicOnVUState(TiproHidDevice *device, int nState);

/**
 * @brief Returns if microphone level is shown on the VU-meter (ON/OFF)
 * @param[in] device Device
 * @param[out] nState Microphone on VU-meter state (ON/OFF)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetMicOnVUState(TiproHidDevice *device, int *nState);

/**
 * @brief Sets the level of the handset sidetone
 * @param[in] device Device
 * @param[in] nLevel Handset sidetone level
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetHandsetSidetoneLevel(TiproHidDevice *device, int nLevel);

/**
 * @brief Turn sidetone On or Off
 * @param[in] device Device
 * @param[in] bOn Handset On/Off
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SetHandsetSidetone(TiproHidDevice *device, bool bOn);

/**
 * @brief Returns the current level of the handset sidetone
 * @param[in] device Device
 * @param[out] nLevel Handset sidetone level
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetHandsetSidetoneLevel(TiproHidDevice *device, int *nLevel);

/**
 * @brief Emulates handset or handsfree PTT key press
 * @param[in] device Device
 * @param[in] nKey Which key to "press" (HS_PTT, HF_PTT)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07EmulateKeyPress(TiproHidDevice *device, int nKey);

/**
 * @brief Emulates handset or handsfree PTT key release
 * @param[in] device Device
 * @param[in] nKey Which key to "release" (HS_PTT, HF_PTT)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07EmulateKeyRelease(TiproHidDevice *device, int nKey);

/**
 * @brief Returns the state of the keys
 * @param[in] device Device
 * @param[out] nHandsetKeyState Handset PTT key state (BF07_KEY_PRESSED / BF07_KEY_RELEASED)
 * @param[out] nHookState Hook state (BF07_HANDSET_ONHOOK / BF07_HANDSET_OFFHOOK)
 * @param[out] nKey1State Key 1 state (BF07_KEY_PRESSED / BF07_KEY_RELEASED)
 * @param[out] nKey2State Key 2 state (BF07_KEY_PRESSED / BF07_KEY_RELEASED)
 * @param[out] nKey3State Key 3 state (BF07_KEY_PRESSED / BF07_KEY_RELEASED)
 * @param[out] nKey4State Key 4 state (BF07_KEY_PRESSED / BF07_KEY_RELEASED)
 * @param[out] nKey5State Key 5 state (BF07_KEY_PRESSED / BF07_KEY_RELEASED)
 * @param[out] nKey6State Key 6 state (BF07_KEY_PRESSED / BF07_KEY_RELEASED)
 * @param[out] nKeyPttState PTT key state (BF07_KEY_PRESSED / BF07_KEY_RELEASED)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07GetKeyState(TiproHidDevice *device, int *nHandsetKeyState, int *nHookState, int *nKey1State, int *nKey2State, int *nKey3State, int *nKey4State, int *nKey5State, int *nKey6State, int *nKeyPttState);

/**
 * @brief Resets the HID telephony events and sends hook and ptt button events
 * @param device Device
 * @param nTelephonyEvents Telephony events to be reset (1-hook, 2-mute)
 * @param nTelephonyKeys Should telephony keys be reset (0-false; else true)
 * @param nTelephonyButtons Should telephony program keys be reset (0-false, else true)
 * @return Command status: 0-OK, else error code
 */
int TiproBF07SendHookPttEvents(TiproHidDevice *device, int nTelephonyEvents, int nTelephonyKeys, int nTelephonyButtons);

#ifdef __cplusplus
}
#endif

#endif
