/**
 * @file BF20.h
 * 
 * BF20
 * 
 * This file includes functions for communication with BF20.
 * 
 * BeFREE 20 (BF20) is a touchcomputer with integrated intercom.
 * 
 * Tipro
 * 
 * support@tipro.si
 * 
 * Copyright 2021
 */

#ifndef _TIPRO_TIPROHIDAPI_BF20_H_
#define _TIPRO_TIPROHIDAPI_BF20_H_

#include "TiproHidDevice.h"

#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************************/
/*		BF20 DEFINES														*/
/****************************************************************************/

// PCM scenario
#define BF20_PCM_SCENARIO_AB			0x3C /**< PMC scenario - Both channels of codec A to left speaker and both channels of codec B to right speaker. */
#define BF20_PCM_SCENARIO_LR			0x3D /**< PMC scenario - Left channels of codec A and B to left speaker and right channels of codec A and B to right speaker. */
#define BF20_PCM_SCENARIO_VOID			0x3F
#define BF20_PCM_SCENARIO_MASK			0x03

// microphone amplifier mode
#define BF20_MICAMP_MODE_LOG			0x33 /**< Microphone amplifier mode - Logaritmic. When the microphone amplifier is set to logaritmic mode, you can set additional settings: optimal distance, noise threshold and compression. */
#define BF20_MICAMP_MODE_LIN			0x37 /**< Microphone amplifier mode - Linear */
#define BF20_MICAMP_MODE_VOID			0x3F
#define BF20_MICAMP_MODE_MASK			0x0C

// central (low frequency) speaker 
#define BF20_LF_SPK_OFF					0x3C /**< Central speaker disabled. */
#define BF20_LF_SPK_ON					0x3D /**< Central speaker activated. */
#define BF20_LF_SPK_VOID				0x3F
#define BF20_LF_SPK_MASK				0x03

// showing microphone signal on VU meter
#define BF20_VU_AB_MIC_OFF				0x33 /**< Microphone signal is not shown. */ 
#define BF20_VU_AB_MIC_ON				0x37 /**< Microphone signal is shown on VU meter. */ 
#define BF20_VU_AB_MIC_VOID				0x3F
#define BF20_VU_AB_MIC_MASK				0x0C

// analog line out to speakers
#define BF20_LINE_OUT_OFF_SPK			0x10 /**< Soundcard is not connected to the speakers. */
#define BF20_LINE_OUT_ON_L_SPK			0x11 /**< Left channel of soundcard to left speaker. */
#define BF20_LINE_OUT_ON_R_SPK			0x12 /**< Right channel of soundcard to right speaker. */
#define BF20_LINE_OUT_ON_LR_SPK			0x13 /**< Left channel of soundcard to left speaker and right channel to right speaker. */
#define BF20_LINE_OUT_VOID				0x14
#define BF20_LINE_OUT_MASK				0x03

// microphone to analog line in
#define BF20_MIC_OFF_LINE_IN			0x04 /**< Signal from microphone not added to analogue line in. */
#define BF20_MIC_ON_LINE_IN				0x0C /**< Signal from microphone added to analogue line in. */
#define BF20_MIC_LINE_IN_VOID			0x14
#define BF20_MIC_LINE_IN_MASK			0x08

// echo canceller
#define BF20_EC_OFF						0x00 /**< Echo canceller disabled. */
#define BF20_EC_ON_L					0x01 /**< Echo canceller enabled. Left speaker signal as reference. */
#define BF20_EC_ON_R					0x02 /**< Echo canceller enabled. Right speaker signal as reference. */
#define BF20_EC_ON_LR					0x03 /**< Echo canceller enabled. Left and right speaker signal as reference. */
#define BF20_EC_VOID					0x07
#define BF20_EC_MASK					0x03

// PTT LED controll
#define BF20_PTT_LED_OFF				0x00 /**< PTT LED is off. */
#define BF20_PTT_LED_ON					0x10 /**< PTT LED lights. */
#define BF20_PTT_LED_BLINK				0x20 /**< PTT LED blinks. */

// microphone
#define BF20_MIC_ACTIVE					0x00 /**< Microphone is active. */
#define BF20_MIC_MUTE					0x01 /**< Microphone is muted. */

// microphone level (attenuation)
#define BF20_MIC_LEVEL_P3				0x10 /**< Microphone attenuation level +3 (maximum) */
#define BF20_MIC_LEVEL_P2				0x11 /**< Microphone attenuation level +2 */
#define BF20_MIC_LEVEL_P1				0x12 /**< Microphone attenuation level +1 */
#define BF20_MIC_LEVEL_0				0x13 /**< Microphone attenuation level 0 */
#define BF20_MIC_LEVEL_M1				0x14 /**< Microphone attenuation level -1 */
#define BF20_MIC_LEVEL_M2				0x15 /**< Microphone attenuation level -2 */
#define BF20_MIC_LEVEL_M3				0x16 /**< Microphone attenuation level -3 */
#define BF20_MIC_LEVEL_M4				0x17 /**< Microphone attenuation level -4 */
#define BF20_MIC_LEVEL_M5				0x18 /**< Microphone attenuation level -5 */
#define BF20_MIC_LEVEL_M6				0x19 /**< Microphone attenuation level -6 */
#define BF20_MIC_LEVEL_M7				0x1A /**< Microphone attenuation level -7 */
#define BF20_MIC_LEVEL_M8				0x1B /**< Microphone attenuation level -8 */
#define BF20_MIC_LEVEL_M9				0x1C /**< Microphone attenuation level -9 */
#define BF20_MIC_LEVEL_M10				0x1D /**< Microphone attenuation level -10 */
#define BF20_MIC_LEVEL_M11				0x1E /**< Microphone attenuation level -11 (minimum) */

#define BF20_MIC_LEVEL_MIN				BF20_MIC_LEVEL_P3
#define BF20_MIC_LEVEL_MAX				BF20_MIC_LEVEL_M11

// microphone optimal distance
#define BF20_MIC_DISTANCE_M2			0x0A /**< Microphone preamplifier level -2 (minimum) */
#define BF20_MIC_DISTANCE_M1			0x0B /**< Microphone preamplifier level -1 */
#define BF20_MIC_DISTANCE_0				0x0C /**< Microphone preamplifier level 0 */
#define BF20_MIC_DISTANCE_P1			0x0D /**< Microphone preamplifier level +1 */
#define BF20_MIC_DISTANCE_P2			0x0E /**< Microphone preamplifier level +2 */
#define BF20_MIC_DISTANCE_P3			0x0F /**< Microphone preamplifier level +3 */
#define BF20_MIC_DISTANCE_P4			0x10 /**< Microphone preamplifier level +4 */
#define BF20_MIC_DISTANCE_P5			0x11 /**< Microphone preamplifier level +5 */
#define BF20_MIC_DISTANCE_P6			0x12 /**< Microphone preamplifier level +6 */
#define BF20_MIC_DISTANCE_P7			0x13 /**< Microphone preamplifier level +7 */
#define BF20_MIC_DISTANCE_P8			0x14 /**< Microphone preamplifier level +8 (maximum) */

#define BF20_MIC_DISTANCE_VERY_SHORT	BF20_MIC_DISTANCE_0 /**< Very short distance (~10 cm) */
#define BF20_MIC_DISTANCE_SHORT			BF20_MIC_DISTANCE_P2 /**< Short distance (~30 cm) */
#define BF20_MIC_DISTANCE_MEDIUM		BF20_MIC_DISTANCE_P4 /**< Medium distance (~100 cm) */
#define BF20_MIC_DISTANCE_LONG			BF20_MIC_DISTANCE_P6 /**< Long distance (~200 cm) */

#define BF20_MIC_DISTANCE_MIN			BF20_MIC_DISTANCE_M2
#define BF20_MIC_DISTANCE_MAX			BF20_MIC_DISTANCE_P8

// microphone compression
#define BF20_MIC_COMPRESSION_OFF		0x10 /**< Microphone compression off */
#define BF20_MIC_COMPRESSION_ON			0x11 /**< Microphone compression on */

#define BF20_MIC_COMPRESSION_MIN		BF20_MIC_COMPRESSION_OFF
#define BF20_MIC_COMPRESSION_MAX		BF20_MIC_COMPRESSION_ON

// microphone noise threshold
#define BF20_MIC_THRESHOLD_HIGH			0x10 /**< Microphone noise compression high */
#define BF20_MIC_THRESHOLD_MID			0x11 /**< Microphone noise compression medium */
#define BF20_MIC_THRESHOLD_LOW			0x12 /**< Microphone noise compression low */
#define BF20_MIC_THRESHOLD_LOWER		0x13 /**< Microphone noise compression lower */
#define BF20_MIC_THRESHOLD_VERY_LOW		0x14 /**< Microphone noise compression very low */

#define BF20_MIC_THRESHOLD_MIN			BF20_MIC_THRESHOLD_HIGH
#define BF20_MIC_THRESHOLD_MAX			BF20_MIC_THRESHOLD_VERY_LOW

//luminance
#define BF20_LUMINANCE_MIN				0x00 /**< LCD screen luminance 0 - minimum */
#define BF20_LUMINANCE_MAX				0x14 /**< LCD screen luminance 20 - maximum */

//speaker level
#define BF20_SPK_LEVEL_MIN				0x00 /**< Speaker level 0 - minimum */
#define BF20_SPK_LEVEL_MAX				0x14 /**< Speaker level 20 - maximum */


/****************************************************************************/
/*		BF20 FUNCTIONS														*/
/****************************************************************************/

/**
 * @brief Set PCM scenario
 * @param[in] device Device
 * @param[in] nScenario PCM scenario	(AB2LR / LR2LR)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetPCMScenario(TiproHidDevice *device, int nScenario);

/**
 * @brief Get PCM scenario
 * @param[in] device Device
 * @param[out] nScenario PCM scenario	(AB2LR / LR2LR)
 * @param[out] nInitScenario Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetPCMScenario(TiproHidDevice *device, int *nScenario, int *nInitScenario);

/**
 * @brief Set Microphone amplifier mode (Linear/Logarithmic)
 * @param[in] device Device
 * @param[in] nMicAmpMode icrophone amplifier mode (LIN/LOG)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetMicAmpMode(TiproHidDevice *device, int nMicAmpMode);

/**
 * @brief Get Microphone amplifier mode (Linear/Logarithmic)
 * @param[in] device Device
 * @param[out] nMicAmpMode Microphone amplifier mode (LIN/LOG)
 * @param[out] nInitMicAmpMode Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetMicAmpMode(TiproHidDevice *device, int *nMicAmpMode, int *nInitMicAmpMode);

/**
 * @brief Set LF speaker state (ON/OFF)
 * @param[in] device Device
 * @param[in] nState LF speaker state (on/off)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetLFSpeakerState(TiproHidDevice *device, int nState);

/**
 * @brief Get LF speaker state
 * @param[in] device Device
 * @param[out] nState LF speaker state (on/off)
 * @param[out] nInitState Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetLFSpeakerState(TiproHidDevice *device, int *nState, int *nInitState);

/**
 * @brief Sets if microphone signal 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 TiproBF20SetMicOnVUState(TiproHidDevice *device, int nState);

/**
 * @brief Get microphone signal shown on VU-meter state
 * @param[in] device Device
 * @param[out] nState Microphone signal on VU-meter state (on/off)
 * @param[out] nInitState Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetMicOnVUState(TiproHidDevice *device, int *nState, int *nInitState);

/**
 * @brief Sets the connection state (ON/OFF) of the gooseneck microphone to the LINE-IN port on the motherboard
 * @param[in] device Device
 * @param[in] nState Connection state (ON/OFF)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetMic2LineInState(TiproHidDevice *device, int nState);

/**
 * @brief Returns the connection state (ON/OFF) of the gooseneck microphone to the LINE-IN port on the motherboard
 * @param[in] device Device
 * @param[out] nState Connection state (ON/OFF)
 * @param[out] nInitState Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetMic2LineInState(TiproHidDevice *device, int *nState, int *nInitState);

/**
 * @brief Sets the connection mode (OFF/L/R/LR) of the motherboard LINE-OUT port to the speakers.
 * @param[in] device Device
 * @param[in] nMode Connection mode (OFF/L/R/LR)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetLineOut2SpkMode(TiproHidDevice *device, int nMode);

/**
 * @brief Returns the connection mode (OFF/L/R/LR) of the motherboard LINE-OUT port to the speakers.
 * @param[in] device Device
 * @param[out] nMode Connection mode (OFF/L/R/LR)
 * @param[out] nInitMode Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetLineOut2SpkMode(TiproHidDevice *device, int *nMode, int *nInitMode);

/**
 * @brief Sets the echo canceler mode (OFF/L/R/LR)
 * @param[in] device Device
 * @param[in] nMode Echo canceler mode (OFF/L/R/LR)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetEchoMode(TiproHidDevice *device, int nMode);

/**
 * @brief Returns the echo canceler mode (OFF/L/R/LR)
 * @param[in] device Device
 * @param[out] nMode Echo canceler mode (OFF/L/R/LR)
 * @param[out] nInitMode Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetEchoMode(TiproHidDevice *device, int *nMode, int *nInitMode);

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

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

/**
 * @brief Sets the LED state of illuminated PTT key
 * @param[in] device Device
 * @param[in] nState PTT LED state (PTT_LED_ON/PTT_LED_OFF/PTT_LED_BLINK)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetPTTKeyLEDState(TiproHidDevice *device, int nState);

/**
 * @brief Sets the operation of the illuminated PTT key with more paramters
 * @param[in] device Device
 * @param[in] nState PTT LED state (PTT_LED_ON/PTT_LED_OFF/PTT_LED_BLINK)
 * @param[in] nTBlinkOn On period for blink mode (ms)
 * @param[in] nTBlinkOff Off period for blink mode (ms)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetPTTKeyLEDStateEx(TiproHidDevice *device, int nState, int nTBlinkOn, int nTBlinkOff);

/**
 * @brief Returns the LED state of the illuminated 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 TiproBF20GetPTTKeyLEDState(TiproHidDevice *device, int *nState);

/**
 * @brief Mutes/un-mutes the microphone signal
 * @param[in] device Device
 * @param[in] nMute Mute/un-mute microphone
 * @return Command status: 0-OK, else error code
 */
int TiproBF20MuteMicrophone(TiproHidDevice *device, int nMute);

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

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

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

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

/**
 * @brief Sets the gooseneck microphone level
 * @param[in] device Device
 * @param[in] nLevel Microphone level
 * @param[in] bSetInit Write initial state to EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetMicrophoneLevel(TiproHidDevice *device, int nLevel, bool bSetInit);

/**
 * @brief Returns the googeneck microphone level
 * @param[in] device Device
 * @param[out] nLevel Microphone level
 * @param[out] nInitLevel Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetMicrophoneLevel(TiproHidDevice *device, int *nLevel, int *nInitLevel);

/**
 * @brief Sets the microphone optimal distance
 * @param[in] device Device
 * @param[in] nDistance Microphone optimal distance
 * @param[in] bSetInit Write initial state to EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetMicrophoneOptimalDistance(TiproHidDevice *device, int nDistance, bool bSetInit);

/**
 * @brief Gets the microphone optimal distance
 * @param[in] device Device
 * @param[out] nDistance Microphone optimal distance
 * @param[out] nInitDistance Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetMicrophoneOptimalDistance(TiproHidDevice *device, int *nDistance, int *nInitDistance);

/**
 * @brief Returns threshold for the microphone signal
 * @param[in] device Device
 * @param[out] nThreshold Microphone threshold
 * @param[out] nInitThreshold Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetMicrophoneThreshold(TiproHidDevice *device, int *nThreshold, int *nInitThreshold);

/**
 * @brief Sets threshold for the microphone signal
 * @param[in] device Device
 * @param[in] nThreshold Microphone threshold
 * @param[in] bSetInit Write initial state to EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetMicrophoneThreshold(TiproHidDevice *device, int nThreshold, bool bSetInit);

/**
 * @brief Returns compression for the microphone signal
 * @param[in] device Device
 * @param[out] nCompression Microphone compression
 * @param[out] nInitCompression Initial state from EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetMicrophoneCompression(TiproHidDevice *device, int *nCompression, int *nInitCompression);

/**
 * @brief Sets compression for the microphone signal
 * @param[in] device Device
 * @param[in] nCompression Microphone compression
 * @param[in] bSetInit Write initial state to EEPROM
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetMicrophoneCompression(TiproHidDevice *device, int nCompression, bool bSetInit);

/**
 * @brief Returns luminance for both stripe and LCD backlight
 * @param[in] device Device
 * @param[out] nLuminance Luminance index (0-darkest; 20-brightest)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20GetLuminance(TiproHidDevice *device, int *nLuminance);

/**
 * @brief Sets luminance for both stripe and LCD backlight
 * @param[in] device Device
 * @param[in] nLuminance Luminance index (0-darkest; 20-brightest)
 * @return Command status: 0-OK, else error code
 */
int TiproBF20SetLuminance(TiproHidDevice *device, int nLuminance);

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

#ifdef __cplusplus
}
#endif

#endif
