/**
 * @file Speakerbox.h
 * 
 * Speakerbox
 * 
 * This file includes functions for communication with Speakerbox.
 * 
 * Speakerbox (SBX) is an intercom module.
 * 
 * Tipro
 * 
 * support@tipro.si
 * 
 * Copyright 2021
 */
 
#ifndef _TIPRO_TIPROHIDAPI_SPEAKERBOX_H_
#define _TIPRO_TIPROHIDAPI_SPEAKERBOX_H_

#include "TiproHidDevice.h"

#ifdef __cplusplus
extern "C" {
#endif

/****************************************************************************/
/*		SPEAKERBOX DEFINES                                                  */
/****************************************************************************/

// available devices
#define SBX_DEVICE_HANDSFREE					0x00 /**< Handsfree device */
#define SBX_DEVICE_HANDSET						0x01 /**< Handset device connected into speakerbox*/
#define SBX_DEVICE_HEADSET						0x02 /**< Headset device connected into speakerbox*/
#define SBX_DEVICE_HANDSET_HEADSET				0x03 /**< Handset and headset device */
#define SBX_DEVICE_HANDSFREE_HANDSET_HEADSET	0x04 /**< Handsfree, handset and headset device */
#define SBX_DEVICE_ILLEGAL						0xFF

// microphone
#define SBX_MIC_ACTIVE					0x00 /**< Microphone is active. */
#define SBX_MIC_MUTE					0x01 /**< Microphone is muted. */

#define SBX_MIC_LEVEL_P7				0x00
#define SBX_MIC_LEVEL_P6				0x01
#define SBX_MIC_LEVEL_P5				0x02
#define SBX_MIC_LEVEL_P4				0x03
#define SBX_MIC_LEVEL_P3				0x04 /**< Microphone attenuation level +3 (maximum) */
#define SBX_MIC_LEVEL_P2				0x05 /**< Microphone attenuation level +2 */
#define SBX_MIC_LEVEL_P1				0x06 /**< Microphone attenuation level +1 */
#define SBX_MIC_LEVEL_0					0x07 /**< Microphone attenuation level 0 */
#define SBX_MIC_LEVEL_M1				0x08 /**< Microphone attenuation level -1 */
#define SBX_MIC_LEVEL_M2				0x09 /**< Microphone attenuation level -2 */
#define SBX_MIC_LEVEL_M3				0x0A /**< Microphone attenuation level -3 (minimum) */	
#define SBX_MIC_LEVEL_M4				0x0B
#define SBX_MIC_LEVEL_M5				0x0C
#define SBX_MIC_LEVEL_M6				0x0D
#define SBX_MIC_LEVEL_M7				0x0E
#define SBX_MIC_LEVEL_ILLEGAL			0xFF

#define SBX_MIC_LEVEL_LOW				SBX_MIC_LEVEL_M2
#define SBX_MIC_LEVEL_MID				SBX_MIC_LEVEL_0
#define SBX_MIC_LEVEL_HIGH				SBX_MIC_LEVEL_P2

// paramters limited to usefull range
#define SBX_MIC_LEVEL_MIN				SBX_MIC_LEVEL_P3
#define SBX_MIC_LEVEL_MAX				SBX_MIC_LEVEL_M3

// compression settings
#define SBX_MIC_COMPRESSION_OFF					0x00 /**< Microphone compression off */
#define SBX_MIC_COMPRESSION_LOW					0x01 /**< Microphone compression low */
#define SBX_MIC_COMPRESSION_MID					0x02 /**< Microphone compression medium */
#define SBX_MIC_COMPRESSION_ILLEGAL				0xFF

#define SBX_MIC_COMPRESSION_MIN				SBX_MIC_PROFILE_OFF
#define SBX_MIC_COMPRESSION_MAX				SBX_MIC_PROFILE_MID

// optimal distance
#define SBX_MIC_DISTANCE_VERY_SHORT			0x00 /**< Very short distance (~10 cm) */
#define SBX_MIC_DISTANCE_SHORT				0x01 /**< Short distance (~30 cm) */
#define SBX_MIC_DISTANCE_MEDIUM				0x02 /**< Medium distance (~100 cm) */
#define SBX_MIC_DISTANCE_LONG				0x03 /**< Long distance (~200 cm) */
#define SBX_MIC_DISTANCE_ILLEGAL			0xFF

#define SBX_MIC_DISTANCE_MIN				SBX_MIC_DISTANCE_VERY_SHORT
#define SBX_MIC_DISTANCE_MAX				SBX_MIC_DISTANCE_LONG

// noise threshold
#define SBX_MIC_THRESHOLD_VERY_LOW		0x10 /**< Microphone noise threshold very low */
#define SBX_MIC_THRESHOLD_LOW			0x11 /**< Microphone noise threshold low */
#define SBX_MIC_THRESHOLD_MID			0x12 /**< Microphone noise threshold medium */
#define SBX_MIC_THRESHOLD_HIGH			0x13 /**< Microphone noise threshold high */
#define SBX_MIC_THRESHOLD_ILLEGAL		0xFF

#define SBX_MIC_PROFILE_EX_MIN			SBX_MIC_THRESHOLD_VERY_LOW
#define SBX_MIC_PROFILE_EX_MAX			SBX_MIC_THRESHOLD_HIGH

// sidetone
#define SBX_SIDETONE_LEVEL_M6DB			0x00 /**< Sidetone level -6 dB (maximum) */
#define SBX_SIDETONE_LEVEL_M9DB			0x01 /**< Sidetone level -9 dB */
#define SBX_SIDETONE_LEVEL_M12DB		0x02 /**< Sidetone level -12 dB */
#define SBX_SIDETONE_LEVEL_M15DB		0x03 /**< Sidetone level -15 dB */
#define SBX_SIDETONE_LEVEL_M18DB		0x04 /**< Sidetone level -18 dB */
#define SBX_SIDETONE_LEVEL_M21DB		0x05 /**< Sidetone level -21 dB */
#define SBX_SIDETONE_LEVEL_M24DB		0x06 /**< Sidetone level -24 dB */
#define SBX_SIDETONE_LEVEL_M27DB		0x07 /**< Sidetone level -27 dB */
#define SBX_SIDETONE_LEVEL_M30DB		0x08 /**< Sidetone level -30 dB (minimum) */
#define SBX_SIDETONE_OFF				0xFE
#define SBX_SIDETONE_ILLEGAL			0xFF

#define SBX_SIDETONE_MIN				SBX_SIDETONE_LEVEL_M6DB
#define SBX_SIDETONE_MAX				SBX_SIDETONE_LEVEL_M30DB

// speakers
#define SBX_SPK_ACTIVE					0x00 /**< Speaker is active. */
#define SBX_SPK_MUTE					0x01 /**< Speaker is muted. */

#define SBX_SPK_LEVEL_MIN				0x00 /**< Handsfree speaker level 0 (minimum) */
#define SBX_SPK_LEVEL_MAX				0x14 /**< Handsfree speaker level 20 (maximum) */
#define SBX_SPK_LEVEL_ILLEGAL			0xFF

#define SBX_ALERT_ACTIVE				0x00 /**< Alert line is active. */
#define SBX_ALERT_MUTE					0x01 /**< Alert line is muted. */

#define SBX_HANDSET_HEADSET_LEVEL_9DB	0x00 /**< Handset and headset speaker level +9 dB (maximum) */
#define SBX_HANDSET_HEADSET_LEVEL_6DB	0x01 /**< Handset and headset speaker level +6 dB */
#define SBX_HANDSET_HEADSET_LEVEL_3DB	0x02 /**< Handset and headset speaker level +3 dB */
#define SBX_HANDSET_HEADSET_LEVEL_0DB	0x03 /**< Handset and headset speaker level 0 dB */
#define SBX_HANDSET_HEADSET_LEVEL_M6DB	0x04 /**< Handset and headset speaker level -6 dB */
#define SBX_HANDSET_HEADSET_LEVEL_M12DB	0x05 /**< Handset and headset speaker level -12 dB */
#define SBX_HANDSET_HEADSET_LEVEL_M18DB	0x06 /**< Handset and headset speaker level -18 dB */
#define SBX_HANDSET_HEADSET_LEVEL_M24DB	0x07 /**< Handset and headset speaker level -24 dB */
#define SBX_HANDSET_HEADSET_LEVEL_M30DB	0x08 /**< Handset and headset speaker level -30 dB */
#define SBX_HANDSET_HEADSET_LEVEL_M36DB	0x09 /**< Handset and headset speaker level -36 dB */
#define SBX_HANDSET_HEADSET_LEVEL_M42DB	0x0A /**< Handset and headset speaker level -42 dB (minimum) */
#define SBX_HANDSET_HEADSET_ILLEGAL		0xFF

#define SBX_HANDSET_HEADSET_LEVEL_MIN	SBX_HANDSET_HEADSET_LEVEL_9DB
#define SBX_HANDSET_HEADSET_LEVEL_MAX	SBX_HANDSET_HEADSET_LEVEL_M42DB

#define SBX_ALERT_AS_ALERT				0x00 /**< Right speaker is used for alert signals; left speaker is used for voice communication. */
#define SBX_ALERT_AS_VOICE				0x01 /**< Both speakers are used for voice communication. */
#define SBX_ALERT_NOT_USED				0x02
#define	SBX_ALERT_ILLEGAL				0xFF

// indicators
#define SBX_LED_OFF						0x00 /**< LED is off. */
#define SBX_LED_ON						0x01 /**< LED is on. */
// Task#98 - supported in >FW 5.xx.61
#define SBX_LED_BLINK					0x02
#define SBX_LED_BLINK_INV				0x03

// keys
#define SBX_KEY_SB_1					0x01
#define SBX_KEY_SB_2					0x02
#define SBX_KEY_SB_3					0x03
#define SBX_KEY_SB_4					0x04
#define SBX_KEY_SB_5					0x05
#define SBX_KEY_SB_6					0x06
#define SBX_HANDSET_PTT					0x07
#define SBX_HEADSET_PTT					0x08
#define SBX_HANDSET_HOOK				0x09
#define SBX_HEADSET_CONNECTED			0x0A

//state of the keys
#define SBX_KEY_PRESSED					0x80 /**< Key is pressed. */
#define SBX_KEY_RELEASED				0x00 /**< Key is released. */

#define SBX_KEY_ILLEGAL					0xFF

#define HANDSET_ONHOOK					0x80 /**< Handset is onhook. */
#define HANDSET_OFFHOOK					0x00 /**< Handset is offhook. */

#define HEADSET_CONNECTED				0x80 /**< Headset is connected. */
#define HEADSET_DISCONNECTED			0x00 /**< Headset is disconnected. */

#define HEADSET_EX_STATE_DISCONNECTED	0x00 /**< Headset is disconnected. */
#define HEADSET_EX_STATE_CONNECTED_1	0x80 /**< Headset is connected (state 1). */
#define HEADSET_EX_STATE_CONNECTED_2	0x81 /**< Headset is connected (state 2). */

#define HANDSET_KEY_PRESSED				0x80 /**< Handset key is pressed. */
#define HANDSET_KEY_RELEASED			0x00 /**< Handset key is released. */

// LED luminance
#define SBX_LED_LUMINANCE_MIN			0x00
#define SBX_LED_LUMINANCE_MAX			0x0A

// PTT LED control
#define PTT_LED_OFF						0x00
#define PTT_LED_ON						0x10
#define PTT_LED_BLINK					0x20

// RGB PTT LED control (currently not available in HW)
#define PTT_LED_OFF						0x00
#define PTT_LED_R_ON					0x01
#define PTT_LED_R_BLINK					0x02
#define PTT_LED_G_ON					0x04
#define PTT_LED_G_BLINK					0x0C
#define PTT_LED_B_ON					0x10
#define PTT_LED_B_BLINK					0x20

// Auto Luminance (BF10 and SBX)
#define AUTO_LUMINANCE_MODE_1			0xE0
#define AUTO_LUMINANCE_MODE_2			0xE1
#define AUTO_LUMINANCE_MODE_3			0xE2
#define AUTO_LUMINANCE_OFF				0x00	// manual mode

// Analog audio
#define SBX_ANALOG_AUDIO_OFF			0x00
#define SBX_ANALOG_AUDIO_LEFT			0x01
#define SBX_ANALOG_AUDIO_RIGHT			0x02
#define SBX_ANALOG_AUDIO_BOTH			0x03


/****************************************************************************/
/*		SPEAKERBOX FUNCTIONS                                                */
/****************************************************************************/

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

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

/**
 * @brief Sets the LED state of the illuminated keys
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nKey Illuminated key index (SBX_KEY_SB_1, SBX_KEY_SB_2, SBX_KEY_SB_3, SBX_KEY_SB_4, SBX_KEY_SB_5, SBX_KEY_SB_6)
 * @param[in] nState State of the LED (SBX_LED_ON, SBX_LED_OFF)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetLEDState (TiproHidDevice *device, int nFsNum, int nKey, int nState);

/**
 * @brief Returns the LED state of the illuminated keys
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nKey Illuminated key index (SBX_KEY_SB_1, SBX_KEY_SB_2, SBX_KEY_SB_3, SBX_KEY_SB_4, SBX_KEY_SB_5, SBX_KEY_SB_6)
 * @param[out] nState State of the LED (SBX_LED_ON, SBX_LED_OFF)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetLEDState (TiproHidDevice *device, int nFsNum, int nKey, int *nState);

/**
 * @brief Sets the level of the connected headset/handset device
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nLevel Level of the signal
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetExternalDeviceLevel (TiproHidDevice *device, int nFsNum, int nLevel);

/**
 * @brief Returns the current level of the connected headset/handset device
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[out] nLevel Level of the signal
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetExternalDeviceLevel (TiproHidDevice *device, int nFsNum, int *nLevel);

/**
 * @brief Returns the state of the headset
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[out] nState Headset state (HEADSET_CONNECTED, HEADSET_DISCONNECTED)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetExternalHeadsetState (TiproHidDevice *device, int nFsNum, int *nState);

/**
 * @brief Mutes/un-mutes the microphone signal
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nMute Mute/un-mute microphone (SBX_MIC_MUTE, SBX_MIC_ACTIVE)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxMuteMicrophone (TiproHidDevice *device, int nFsNum, int nMute);

/**
 * @brief Puts speakerbox to On-line mode
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGoOnline (TiproHidDevice *device, int nFsNum);

/**
 * @brief Returns On-line / Off-line mode
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[out] nOnline 0-Offline; 1-Online
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxIsOnline (TiproHidDevice *device, int nFsNum, int *nOnline);

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

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

/**
 * @brief Sets the device where both speaker and microphone signals will be switched to (on-line mode only)
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nDevice Device to be made active
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetActiveDevice (TiproHidDevice *device, int nFsNum, int nDevice);

/**
 * @brief Returns the level of the microphone signal
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[out] nLevel Microphone level
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetMicrophoneLevel (TiproHidDevice *device, int nFsNum, int *nLevel);

/**
 * @brief Sets the level of the microphone signal
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nLevel Microphone level
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetMicrophoneLevel (TiproHidDevice *device, int nFsNum, int nLevel);

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

/**
 * @brief Returns the optimal distance of the handsfree microphone
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[out] nDistance Microphone optimal distance
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetMicrophoneOptimalDistance (TiproHidDevice *device, int nFsNum, int *nDistance);

/**
 * @brief Sets the optimal distance for the handsfree microphone
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nDistance Microphone optimal distance
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetMicrophoneOptimalDistance (TiproHidDevice *device, int nFsNum, int nDistance);

/**
 * @brief Sets the microphone threshold
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nThreshold Microphone threshold
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetMicrophoneThreshold (TiproHidDevice *device, int nFsNum, int nThreshold);

/**
 * @brief Returns the microphone threshold
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[out] nThreshold Microphone threshold
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetMicrophoneThreshold (TiproHidDevice *device, int nFsNum, int *nThreshold);

/**
 * @brief Sets the microphone compression
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nCompression Microphone compression
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetMicrophoneCompression (TiproHidDevice *device, int nFsNum, int nCompression);

/**
 * @brief Returns the microphone compression
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[out] nCompression Microphone compression
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetMicrophoneCompression (TiproHidDevice *device, int nFsNum, int *nCompression);

/** Specific device versions **/
/**
 * @brief Sets the specific device's microphone threshold
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nThreshold Microphone threshold
 * @param[in] nDevice Device to set (handsfree, handset/headset)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetMicrophoneThresholdEx (TiproHidDevice *device, int nFsNum, int nThreshold, int nDevice);

/**
 * @brief Sets the specific device's microphone compression
 * @param[in] device Device
 * @param[in] nFsNum Selected speakerbox module number
 * @param[in] nCompression Microphone compression
 * @param[in] nDevice Device to set (handsfree, handset/headset)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetMicrophoneCompressionEx (TiproHidDevice *device, int nFsNum, int nCompression, int nDevice);

/**
 * @brief Returns state of the keys
 * @param device Device
 * @param nHandsetNum Selected handset module number
 * @param nPTTKey PTT key state (KEY_PRESSED / KEY_RELEASED)
 * @param nHookState Hook state (KEY_PRESSED / KEY_RELEASED)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetHandsetStateEx (TiproHidDevice *device, int nHandsetNum, int *nPTTKey, int *nHookState);

/**
 * @brief Returns state of the keys
 * @param device Device
 * @param nFsNum Selected speakerbox module number
 * @param nKey Key index
 * @param nState State of the key (KEY_PRESSED / KEY_RELEASED)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetKeyState (TiproHidDevice *device, int nFsNum, int nKey, int *nState);

/**
 * @brief 
 * @param device Device
 * @param nFsNum Selected speakerbox module number
 * @param nTBlinkA
 * @param nTBlinkB
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxSetLEDBlinkSpeed (TiproHidDevice *device, int nFsNum, int nTBlinkA, int nTBlinkB);

/**
 * @brief 
 * @param device Device
 * @param nFsNum Selected speakerbox module number
 * @param nTBlinkA
 * @param nTBlinkB
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetLEDBlinkSpeed (TiproHidDevice *device, int nFsNum, int *nTBlinkA, int *nTBlinkB);

/**
 * @brief Returns state of the keys
 * @param device Device
 * @param nHandsetNum Selected handset module number
 * @param nPTTKey PTT key state	(KEY_PRESSED / KEY_RELEASED)
 * @param nHookState Hook state (KEY_PRESSED / KEY_RELEASED)
 * @return Command status: 0-OK, else error code
 */
int TiproSpeakerboxGetHandsetState(TiproHidDevice *device, int nHandsetNum, int *nPTTKey, int *nHookState);

#ifdef __cplusplus
}
#endif

#endif
