/*
 * Copyright (C) 2019      Kai Ludwig, DG4KLU
 * Copyright (C) 2019-2025 Roger Clark, VK3KYY / G4KYF
 *                         Daniel Caujolle-Bert, F1RMB
 *
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer
 *    in the documentation and/or other materials provided with the distribution.
 *
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * 4. Use of this source code or binary releases for commercial purposes is strictly forbidden. This includes, without limitation,
 *    incorporation in a commercial product or incorporation into a product or project which allows commercial use.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef _OPENGD77_SETTINGS_H_
#define _OPENGD77_SETTINGS_H_

#include "functions/codeplug.h"
#include "functions/trx.h"

enum USB_MODE { USB_MODE_CPS, USB_MODE_HOTSPOT, USB_MODE_DEBUG };
enum SETTINGS_UI_MODE { SETTINGS_CHANNEL_MODE = 0, SETTINGS_VFO_A_MODE, SETTINGS_VFO_B_MODE };
enum BACKLIGHT_MODE { BACKLIGHT_MODE_AUTO = 0, BACKLIGHT_MODE_SQUELCH, BACKLIGHT_MODE_MANUAL, BACKLIGHT_MODE_BUTTONS, BACKLIGHT_MODE_NONE };
enum HOTSPOT_TYPE { HOTSPOT_TYPE_OFF = 0, HOTSPOT_TYPE_MMDVM, HOTSPOT_TYPE_BLUEDV };
enum CONTACT_DISPLAY_PRIO { CONTACT_DISPLAY_PRIO_CC_DB_TA = 0, CONTACT_DISPLAY_PRIO_DB_CC_TA, CONTACT_DISPLAY_PRIO_TA_CC_DB, CONTACT_DISPLAY_PRIO_TA_DB_CC };
enum SCAN_MODE { SCAN_MODE_HOLD = 0, SCAN_MODE_PAUSE, SCAN_MODE_STOP };
enum SPLIT_CONTACT { SPLIT_CONTACT_SINGLE_LINE_ONLY = 0, SPLIT_CONTACT_ON_TWO_LINES, SPLIT_CONTACT_AUTO };
enum ALLOW_PRIVATE_CALLS_MODE { ALLOW_PRIVATE_CALLS_OFF = 0, ALLOW_PRIVATE_CALLS_ON, ALLOW_PRIVATE_CALLS_PTT };//, ALLOW_PRIVATE_CALLS_AUTO };
enum BAND_LIMITS_ENUM { BAND_LIMITS_NONE = 0 , BAND_LIMITS_ON_LEGACY_DEFAULT, BAND_LIMITS_FROM_CPS };
enum INFO_ON_SCREEN { INFO_ON_SCREEN_OFF = 0x00, INFO_ON_SCREEN_TS = 0x01, INFO_ON_SCREEN_PWR = 0x02, INFO_ON_SCREEN_BOTH = 0x03 };

#if defined(HAS_GPS)
#define SETTINGS_GPS_MODE_GET(x) ((x).gpsModeAndBaudsIndex & 0x0F)
#define SETTINGS_GPS_BAUDRATE_GET(x) (((x).gpsModeAndBaudsIndex & 0xF0) >> 4)
#define SETTINGS_GPS_MODE_SET(x, m) (((x).gpsModeAndBaudsIndex & 0xF0) | ((m) & 0x0F))
#define SETTINGS_GPS_BAUDRATE_SET(x, b) ((((b) & 0x0F) << 4) | ((x).gpsModeAndBaudsIndex & 0x0F))

typedef enum
{
	GPS_NOT_DETECTED,
	GPS_MODE_OFF,
	GPS_MODE_ON,
	GPS_MODE_ON_NMEA,
#if defined(LOG_GPS_DATA)
	GPS_MODE_ON_LOG,
#endif
	NUM_GPS_MODES,
} gpsMode_t;
#endif

typedef enum
{
	ROAMING_OFF     = 0U,
	ROAMING_MANUAL,
	ROAMING_5KM,
	ROAMING_10KM,
	ROAMING_20KM,
	ROAMING_MAX_NUM
} roaming_t;

#define ECO_LEVEL_MAX          5

#define SETTINGS_TIMEZONE_UTC 64
#define SETTINGS_UNITIALISED_LOCATION_LAT	0x7F000000U

// Bit patterns for DMR Beep
#define BEEP_TX_NONE             0x00
#define BEEP_TX_START            0x01
#define BEEP_TX_STOP             0x02
#define BEEP_RX_CARRIER          0x04
#define BEEP_RX_TALKER           0x08
#define BEEP_RX_TALKER_BEGIN     0x10

#if defined(PLATFORM_GD77) || defined(PLATFORM_GD77S) || defined(PLATFORM_DM1801) || defined(PLATFORM_DM1801A) || defined(PLATFORM_RD5R)
#define SETTINGS_DMR_MIC_ZERO	11U
#define SETTINGS_FM_MIC_ZERO	16U
#elif defined(PLATFORM_MD9600)
#define SETTINGS_DMR_MIC_ZERO	 8U
#define SETTINGS_FM_MIC_ZERO	 6U
#else
#define SETTINGS_DMR_MIC_ZERO	 5U
#define SETTINGS_FM_MIC_ZERO	 4U
#endif

#define LOCATION_DECIMAL_PART_MULIPLIER_FIXED_32 100000
#define LOCATION_DECIMAL_PART_MULIPLIER_FIXED_32_DOUBLE 1E-5
#define LOCATION_DECIMAL_PART_MULIPLIER_FIXED_24 10000
#define LOCATION_DECIMAL_PART_MULIPLIER_FIXED_24_DOUBLE 1E-4

extern int settingsCurrentChannelNumber;
extern int16_t *nextKeyBeepMelody;
extern CodeplugChannel_t settingsVFOChannel[2];
extern CodeplugGeneralSettings_t settingsCodeplugGeneralSettings;


#define SETTINGS_BITS_NUMBER_OF_BANKS 1U // Number of settings bits banks (max 4)
// bits #30 to #31 are used for storage bank index, settings bits are using the first 30 bits (#29 to #0)
#define SETTINGS_BITS_ARRAY_BANK(x) (((x) & 0xC0000000) >> 30)
#define SETTINGS_BITS_ARRAY_VALUE(x) ((x) & ~0xC0000000)
#define SETTINGS_BITS_BANK_0 (0 << 30) // 1
#if (SETTINGS_BITS_NUMBER_OF_BANKS >= 2U)
  #define SETTINGS_BITS_BANK_1 (1 << 30) // 2
  #if (SETTINGS_BITS_NUMBER_OF_BANKS >= 3U)
    #define SETTINGS_BITS_BANK_2 (2 << 30) // 3
    #if (SETTINGS_BITS_NUMBER_OF_BANKS == 4U)
      #define SETTINGS_BITS_BANK_3 (3 << 30) // 4
    #else
      #error settings banks max value is 4
    #endif
  #endif
#endif

typedef enum
{
	BIT_INVERSE_VIDEO               = (SETTINGS_BITS_BANK_0 | (1 << 0)),
	BIT_PTT_LATCH                   = (SETTINGS_BITS_BANK_0 | (1 << 1)),
	BIT_BATTERY_BARS_IN_HEADER      = (SETTINGS_BITS_BANK_0 | (1 << 2)), // companion to BIT_BATTERY_VOLTAGE_IN_HEADER: encodes the "Bars" battery display mode
	BIT_BATTERY_VOLTAGE_IN_HEADER   = (SETTINGS_BITS_BANK_0 | (1 << 3)),
	BIT_SETTINGS_UPDATED            = (SETTINGS_BITS_BANK_0 | (1 << 4)),
	BIT_TX_RX_FREQ_LOCK             = (SETTINGS_BITS_BANK_0 | (1 << 5)),
	BIT_ALL_LEDS_DISABLED           = (SETTINGS_BITS_BANK_0 | (1 << 6)),
	BIT_SCAN_ON_BOOT_ENABLED        = (SETTINGS_BITS_BANK_0 | (1 << 7)),
#if !defined(STM32F405xx)
	BIT_POWEROFF_SUSPEND            = (SETTINGS_BITS_BANK_0 | (1 << 8)),
#endif
	BIT_SATELLITE_MANUAL_AUTO       = (SETTINGS_BITS_BANK_0 | (1 << 9)),
	BIT_SCREEN_DIM_0                = (SETTINGS_BITS_BANK_0 | (1 << 10)), // low bit of the 3-bit screen-dim level
#if defined(PLATFORM_MD9600)
	BIT_SPEAKER_CLICK_SUPPRESS      = (SETTINGS_BITS_BANK_0 | (1 << 11)),
#endif
	BIT_DMR_CRC_IGNORED             = (SETTINGS_BITS_BANK_0 | (1 << 12)),
	BIT_APO_WITH_RF                 = (SETTINGS_BITS_BANK_0 | (1 << 13)),
	BIT_SAFE_POWER_ON               = (SETTINGS_BITS_BANK_0 | (1 << 14)),
	BIT_AUTO_NIGHT                  = (SETTINGS_BITS_BANK_0 | (1 << 15)),
	BIT_AUTO_NIGHT_OVERRIDE         = (SETTINGS_BITS_BANK_0 | (1 << 16)),
	BIT_AUTO_NIGHT_DAYTIME          = (SETTINGS_BITS_BANK_0 | (1 << 17)),
#if defined(HAS_SOFT_VOLUME)
	BIT_VISUAL_VOLUME               = (SETTINGS_BITS_BANK_0 | (1 << 18)),
#endif
	BIT_SECONDARY_LANGUAGE          = (SETTINGS_BITS_BANK_0 | (1 << 19)),
	BIT_SCREEN_DIM_1                = (SETTINGS_BITS_BANK_0 | (1 << 20)), // middle bit of the 3-bit screen-dim level
	BIT_SCREEN_DIM_2                = (SETTINGS_BITS_BANK_0 | (1 << 29)), // high bit of the 3-bit screen-dim level (kept off low legacy bits)
	BIT_DISPLAY_CHANNEL_DISTANCE    = (SETTINGS_BITS_BANK_0 | (1 << 21)),
#if defined(PLATFORM_MD2017)
	BIT_TRACKBALL_ENABLED           = (SETTINGS_BITS_BANK_0 | (1 << 22)),
	BIT_TRACKBALL_FAST_MOTION       = (SETTINGS_BITS_BANK_0 | (1 << 23)),
#endif
#if defined(PLATFORM_MDUV380) && !defined(PLATFORM_VARIANT_UV380_PLUS_10W)
	BIT_FORCE_10W_RADIO             = (SETTINGS_BITS_BANK_0 | (1 << 24)),
#endif
	BIT_TX_INHIBIT                  = (SETTINGS_BITS_BANK_0 | (1 << 25)),
#if defined(HAS_COLOURS) || defined(PLATFORM_MD9600)
	BIT_DISPLAY_TIME_IN_HEADER      = (SETTINGS_BITS_BANK_0 | (1 << 26)),
#endif
	BIT_CHANNELS_ARE_READ_ONLY      = (SETTINGS_BITS_BANK_0 | (1 << 27)),
	BIT_UI_USES_DOUBLE_HEIGHT       = (SETTINGS_BITS_BANK_0 | (1 << 28)),

	// Last usable bit is 29
	//BIT_xxxxxxx_xxxxxxxxxxxx      = (SETTINGS_BITS_BANK_1 | (1 << 0)),
	//BIT_xxxxxxx_xxxxxxxxxxxx      = (SETTINGS_BITS_BANK_2 | (1 << 0)),
	//BIT_xxxxxxx_xxxxxxxxxxxx      = (SETTINGS_BITS_BANK_3 | (1 << 0)),
} bitfieldOptions_t;

#if defined(PLATFORM_MD9600)
#define RADIO_BANDS_TOTAL_NUM_SQUELCH 2
#else
#define RADIO_BANDS_TOTAL_NUM_SQUELCH 3
#endif

typedef struct
{
	uint32_t   lat; // fixed point encoded as 1 sign bit, 8 bits integer, 23 bits as decimal
	uint32_t   lon; // fixed point encoded as 1 sign bit, 8 bits integer, 23 bits as decimal
} settingsLocation_t;

typedef struct
{
	uint32_t 			magicNumber;
	// The following settings won't be reset default from magicNumber 0x4761
	settingsLocation_t 	location;
	uint8_t				timezone;// Lower 7 bits are the timezone. 64 = UTC, values < 64 are negative TZ values.  Bit 8 is a flag which indicates TZ/UTC. 0 = UTC
	// -----------------------------------------------
	uint8_t				beepOptions; // 2 pairs of bits + 1 (TX and RX beeps)
	uint16_t			vfoSweepSettings; // 3bits: channel step | 5 bits: RSSI noise floor | 7bits: gain
	uint32_t			overrideTG;
	uint32_t			vfoScanLow[2]; // low frequency for VFO Scanning
	uint32_t			vfoScanHigh[2]; // High frequency for VFO Scanning
	uint32_t			bitfieldOptions[SETTINGS_BITS_NUMBER_OF_BANKS]; // see bitfieldOptions_t
	uint32_t			aprsBeaconingSettingsPart1[2];
#if defined(LOG_GPS_DATA)
	uint32_t			gpsLogMemOffset; // Current offset from the NMEA logging flash memory address start.
#endif
	int16_t				currentIndexInTRxGroupList[3]; // Current Channel, VFO A and VFO B
	int16_t				currentZone;
	uint16_t			userPower;
	uint16_t			tsManualOverride;
#if (defined(PLATFORM_RD5R) || defined(PLATFORM_MD9600))
	int16_t				currentChannelIndexInZone;
	int16_t				currentChannelIndexInAllZone;
#else // These two has to be used on any platform but RD5R and MD-9600
	int16_t				UNUSED_1;
	int16_t				UNUSED_2;
#endif
	uint16_t			aprsBeaconingSettingsPart2;
	uint8_t				txPowerLevel;
	uint8_t				txTimeoutBeepX5Secs;
	uint8_t				beepVolumeDivider;
	uint8_t				micGainDMR;
	uint8_t				micGainFM;
	uint8_t				backlightMode; // see BACKLIGHT_MODE enum
	uint8_t				backLightTimeout; // 0 = never timeout. 1 - 255 time in seconds
	int8_t				displayContrast;
	int8_t				displayBacklightPercentage[NIGHT + 1];
	int8_t				displayBacklightPercentageOff; // backlight level when "off"
	uint8_t				initialMenuNumber;
	uint8_t				extendedInfosOnScreen;
	uint8_t				txFreqLimited;
	uint8_t				scanModePause;
	uint8_t				scanDelay;
	uint8_t				dmrRxAGC;
	uint8_t				hotspotType;
	uint8_t				scanStepTime;
	uint8_t				currentVFONumber;
	uint8_t				dmrDestinationFilter;
	uint8_t				dmrCaptureTimeout;
	uint8_t				dmrCcTsFilter;
	uint8_t				analogFilterLevel;
	uint8_t    			privateCalls;
	uint8_t				contactDisplayPriority;
	uint8_t				splitContact;
	uint8_t				voxThreshold; // 0: disabled
	uint8_t				voxTailUnits; // 500ms units
	uint8_t				audioPromptMode;
	int8_t				temperatureCalibration;// Units of 0.5 deg C
	uint8_t				batteryCalibration; // Units of 0.01V (NOTE: only the 4 lower bits are used)
	uint8_t				squelchDefaults[RADIO_BANDS_TOTAL_NUM_SQUELCH]; // VHF, 200 and UHF
	uint8_t				ecoLevel;// Power saving / economy level
	uint8_t				apo; // unit: 30 minutes (max 24 => 12 hours)
	uint8_t				keypadTimerLong;
	uint8_t				keypadTimerRepeat;
	uint8_t				autolockTimer; // in minutes
	roaming_t			roaming;
#if defined(HAS_GPS)
	// 4 lower bits: gpsMode_t,
	//
	// On STM32F405xx only:
	// 4 higher bits: baudrate index (0U: value is undetected,
	//                                otherwise value minus 1 is passed to gpsSetBaudRateByIndex())
	// Use SETTINGS_GPS_*GET/SET macros.
	uint8_t				gpsModeAndBaudsIndex;
#endif
	uint8_t				lastTalkerOnScreenTimer; // in seconds, 0..30
} settingsStruct_t;

typedef enum DMR_DESTINATION_FILTER_TYPE
{
	DMR_DESTINATION_FILTER_NONE = 0,
	DMR_DESTINATION_FILTER_TG,
	DMR_DESTINATION_FILTER_DC,
	DMR_DESTINATION_FILTER_RXG,
	NUM_DMR_DESTINATION_FILTER_LEVELS
} dmrDestinationFilter_t;

// Bit patterns
#define DMR_CC_FILTER_PATTERN  0x01
#define DMR_TS_FILTER_PATTERN  0x02

// NOTE. THIS ENUM IS USED AS BIT PATTERNS, DO NOT CHANGE THE DEFINED VALUES WITHOUT UPDATING ANY CODE WHICH USES THIS ENUM
typedef enum DMR_CCTS_FILTER_TYPE
{
	DMR_CCTS_FILTER_NONE = 0,
	DMR_CCTS_FILTER_CC = DMR_CC_FILTER_PATTERN,
	DMR_CCTS_FILTER_TS = DMR_TS_FILTER_PATTERN,
	DMR_CCTS_FILTER_CC_TS = DMR_CC_FILTER_PATTERN | DMR_TS_FILTER_PATTERN,
	NUM_DMR_CCTS_FILTER_LEVELS
} dmrCcTsFilter_t;

typedef enum ANALOG_FILTER_TYPE
{
	ANALOG_FILTER_NONE = 0,
	ANALOG_FILTER_CSS,
	NUM_ANALOG_FILTER_LEVELS
} analogFilter_t;

typedef enum AUDIO_PROMPT_MODE
{
	AUDIO_PROMPT_MODE_SILENT = 0,
	AUDIO_PROMPT_MODE_BEEP,
	AUDIO_PROMPT_MODE_NO_KEY_BEEP,
	AUDIO_PROMPT_MODE_VOICE_LEVEL_1,
	AUDIO_PROMPT_MODE_VOICE_LEVEL_2,
	AUDIO_PROMPT_MODE_VOICE_LEVEL_3 ,
	NUM_AUDIO_PROMPT_MODES,
	AUDIO_PROMPT_MODE_VOICE_THRESHOLD = AUDIO_PROMPT_MODE_VOICE_LEVEL_1
} audioPromptMode_t;

typedef enum PROMPT_AUTOPLAY_THRESHOLD
{
	PROMPT_THRESHOLD_1 = AUDIO_PROMPT_MODE_VOICE_LEVEL_1,
	PROMPT_THRESHOLD_2,
	PROMPT_THRESHOLD_3,
	PROMPT_THRESHOLD_NEVER_PLAY_IMMEDIATELY
} audioPromptThreshold_t;

typedef struct
{
	volatile bool   triggered;
	volatile bool	isEnabled;
	volatile bool	qsoInfoUpdated;
	volatile bool   dmrIsValid;
	int				dmrTimeout;
	uint8_t			dmrFrameSkip;
	int 			savedRadioMode;
	uint8_t			savedSquelch;
	int 			savedDMRCcTsFilter;
	int 			savedDMRDestinationFilter;
	uint8_t 		savedDMRCc;
	int 			savedDMRTs;
} monitorModeSettingsStruct_t;

extern settingsStruct_t nonVolatileSettings;
extern CodeplugChannel_t *currentChannelData;
extern CodeplugChannel_t channelScreenChannelData;
extern CodeplugContact_t contactListContactData;
extern CodeplugDTMFContact_t contactListDTMFContactData;
extern int contactListContactIndex;
extern volatile int settingsUsbMode;
extern monitorModeSettingsStruct_t monitorModeData;

// Do not use the following settingsSet<TYPE>(...) functions, use settingsSet() instead
void settingsSetBOOL(bool *s, bool v);
void settingsSetINT8(int8_t *s, int8_t v);
void settingsSetUINT8(uint8_t *s, uint8_t v);
void settingsSetINT16(int16_t *s, int16_t v);
void settingsSetUINT16(uint16_t *s, uint16_t v);
void settingsSetINT32(int32_t *s, int32_t v);
void settingsSetUINT32(uint32_t *s, uint32_t v);

// Do not use the following settingsInc/Dec<TYPE>(...) functions, use settingsIncrement/Decrement() instead
void settingsIncINT8(int8_t *s, int8_t v);
void settingsIncUINT8(uint8_t *s, uint8_t v);
void settingsIncINT16(int16_t *s, int16_t v);
void settingsIncUINT16(uint16_t *s, uint16_t v);
void settingsIncINT32(int32_t *s, int32_t v);
void settingsIncUINT32(uint32_t *s, uint32_t v);

void settingsDecINT8(int8_t *s, int8_t v);
void settingsDecUINT8(uint8_t *s, uint8_t v);
void settingsDecINT16(int16_t *s, int16_t v);
void settingsDecUINT16(uint16_t *s, uint16_t v);
void settingsDecINT32(int32_t *s, int32_t v);
void settingsDecUINT32(uint32_t *s, uint32_t v);

// Workaround for Eclipse's CDT parser angriness because it doesn't support C11 yet
#ifdef __CDT_PARSER__
#define settingsSet(S, V) do { /* It uses C11's _Generic() at compile time */ S = V; } while(0)
#else
#define settingsSet(S, V) _Generic((S),   \
	bool:     settingsSetBOOL,            \
	int8_t:   settingsSetINT8,            \
	uint8_t:  settingsSetUINT8,           \
	int16_t:  settingsSetINT16,           \
	uint16_t: settingsSetUINT16,          \
	int32_t:  settingsSetINT32,           \
	uint32_t: settingsSetUINT32           \
	)(&S, V)
#endif

#ifdef __CDT_PARSER__
#define settingsIncrement(S, V) do { /* It uses C11's _Generic() at compile time */ S += V; } while(0)
#else
#define settingsIncrement(S, V) _Generic((S),   \
	int8_t:   settingsIncINT8,            \
	uint8_t:  settingsIncUINT8,           \
	int16_t:  settingsIncINT16,           \
	uint16_t: settingsIncUINT16,          \
	int32_t:  settingsIncINT32,           \
	uint32_t: settingsIncUINT32           \
	)(&S, V)
#endif

#ifdef __CDT_PARSER__
#define settingsDecrement(S, V) do { /* It uses C11's _Generic() at compile time */ S -= V; } while(0)
#else
#define settingsDecrement(S, V) _Generic((S),   \
	int8_t:   settingsDecINT8,            \
	uint8_t:  settingsDecUINT8,           \
	int16_t:  settingsDecINT16,           \
	uint16_t: settingsDecUINT16,          \
	int32_t:  settingsDecINT32,           \
	uint32_t: settingsDecUINT32           \
	)(&S, V)
#endif

void settingsSetOptionBit(bitfieldOptions_t bit, bool set);
bool settingsIsOptionBitSetFromSettings(settingsStruct_t *sets, bitfieldOptions_t bit);
bool settingsIsOptionBitSet(bitfieldOptions_t bit);

// How the battery level is shown in the header. Encoded across two option bits
// (BIT_BATTERY_VOLTAGE_IN_HEADER / BIT_BATTERY_BARS_IN_HEADER) for backwards
// compatibility: an unset pair reads as PERCENTAGE, matching legacy behaviour.
typedef enum
{
	BATTERY_UNIT_PERCENTAGE = 0,
	BATTERY_UNIT_VOLTAGE,
	BATTERY_UNIT_BARS,
	NUM_BATTERY_UNIT_DISPLAY
} batteryUnitDisplay_t;

batteryUnitDisplay_t settingsGetBatteryUnitDisplay(void);
void settingsSetBatteryUnitDisplay(batteryUnitDisplay_t mode);

void settingsSetDirty(void);
void settingsSetVFODirty(void);
void settingsSaveIfNeeded(bool immediately);
// Screen dimming: idle backlight as a fraction of the configured brightness.
typedef enum
{
	SCREEN_DIM_OFF = 0,  // feature disabled (use the normal backlight-off level)
	SCREEN_DIM_100,      // stay at 100% of configured brightness when idle
	SCREEN_DIM_50,       // dim to 50%
	SCREEN_DIM_30,       // dim to 30%
	SCREEN_DIM_15,       // dim to 15%
	SCREEN_DIM_NUM
} screenDimLevel_t;
uint8_t settingsGetScreenDimLevel(void);
void settingsSetScreenDimLevel(uint8_t level);

bool settingsSaveSettings(bool includeVFOs);
bool settingsLoadSettings(bool reset);
bool settingsRestoreDefaultSettings(void);
void settingsEraseCustomContent(void);
//void settingsInitVFOChannel(int vfoNumber);
void enableVoicePromptsIfLoaded(bool enableFullPrompts);
int settingsGetScanStepTimeMilliseconds(void);
bool settingsLocationIsValid(void);
double settingsLocationGetLatitude(void);
double settingsLocationGetLongitude(void);

#endif
