/****************************************************************************
*    Copyright © 2014-2025 The Tumultuous Unicorn Of Darkness
*
*    This program is free software: you can redistribute it and/or modify
*    it under the terms of the GNU General Public License as published by
*    the Free Software Foundation, either version 3 of the License, or
*    (at your option) any later version.
*
*    This program is distributed in the hope that it will be useful,
*    but WITHOUT ANY WARRANTY; without even the implied warranty of
*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
*    GNU General Public License for more details.
*
*    You should have received a copy of the GNU General Public License
*    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*
****************************************************************************/

/*
* PROJECT CPU-X
* FILE options.hpp
*/

#ifndef _OPTIONS_HPP_
#define _OPTIONS_HPP_

#include <cstdint>
#include <array>
#include <utility>
#include <vector>
#include "data.hpp"

/* Options definition */
#define OUT_GTK               (1 << 0)
#define OUT_NCURSES           (1 << 1)
#define OUT_DUMP              (1 << 2)
#define OUT_NO_CPUX           (1 << 10)
#define OUT_DMIDECODE         (1 << 11)
#define OUT_BANDWIDTH         (1 << 12)

enum OptKeymap
{
	ARROWS,
	EMACS,
	INVERTED_T,
	VIM,
	LAST_KEYMAP
};

enum OptTempUnit
{
	CELSIUS,
	FAHRENHEIT,
	KELVIN,
	RANKINE,
	LAST_TEMP_UNIT
};

enum TabNumber
{
	TAB_CPU,
	TAB_CACHES,
	TAB_MOTHERBOARD,
	TAB_MEMORY,
	TAB_SYSTEM,
	TAB_GRAPHICS,
	TAB_BENCH,
	TAB_ABOUT,
	LAST_TAB_NUMBER
};

class Options
{
public:
	/* Function's prototypes generated with:
	   grep -E "set_|get_" src/options.cpp | sed -e 's|^|static |g' -e 's|Options::||g' -e 's|)|);|g'
	*/
	static void set_cpuid_decimal(bool cpuid_decimal);
	static bool get_cpuid_decimal();
	static void set_color(bool color);
	static bool get_color();
	static void set_issue(bool issue);
	static bool get_issue();
	static void set_with_daemon(bool with_daemon);
	static bool get_with_daemon();
	static void set_fallback_cpu_temp(bool fallback_cpu_temp);
	static bool get_fallback_cpu_temp();
	static void set_fallback_cpu_volt(bool fallback_cpu_volt);
	static bool get_fallback_cpu_volt();
	static void set_fallback_cpu_freq(bool fallback_cpu_freq);
	static bool get_fallback_cpu_freq();
	static void set_fallback_cpu_mult(bool fallback_cpu_mult);
	static bool get_fallback_cpu_mult();
	static void init_page_visibility();
	static void set_page_visibility(TabNumber page, bool visible);
	static void set_page_visibility_auto(Data &data);
	static bool get_page_visibility(TabNumber page);
	static bool set_selected_page(TabNumber selected_page);
	static bool set_selected_page_next();
	static bool set_selected_page_prev();
	static TabNumber get_selected_page();
	static void set_num_types(uint8_t num_types);
	static bool set_selected_type(uint8_t selected_type);
	static uint8_t get_selected_type();
	static bool set_selected_test(uint8_t selected_test);
	static uint8_t get_selected_test();
	static void set_num_sticks(uint8_t num_sticks);
	static bool set_selected_stick(uint8_t selected_stick);
	static uint8_t get_selected_stick();
	static void set_num_gpus(uint8_t num_gpus);
	static bool set_selected_gpu(uint8_t selected_gpu);
	static uint8_t get_selected_gpu();
	static uint16_t get_selected_core_id();
	static void set_num_cores(uint8_t selected_type, uint16_t num_cores);
	static bool set_selected_core(uint16_t selected_core);
	static uint16_t get_selected_core();
	static bool set_output_type(uint16_t output_type);
	static bool output_type_is(uint16_t output_type);
	static uint16_t get_output_type();
	static bool set_refr_time(uint16_t refr_time);
	static uint16_t get_refr_time();
	static bool set_keymap(OptKeymap keymap);
	static OptKeymap get_keymap();
	static bool set_temp_unit(OptTempUnit temp_unit);
	static OptTempUnit get_temp_unit();

private:
	static inline bool cpuid_decimal     = false;
	static inline bool color             = true;
	static inline bool issue             = false;
	static inline bool with_daemon       = false;
	static inline bool fallback_cpu_temp = false;
	static inline bool fallback_cpu_volt = false;
	static inline bool fallback_cpu_freq = false;
	static inline bool fallback_cpu_mult = false;

	/* Note abouts std::pair:
	   - .first stores the current value
	   - .second stores the maximum allowed value
	*/
	static inline std::pair<uint8_t, uint8_t> selected_type  = { 0, -1 };
	static inline uint8_t                     selected_test  = 0;
	static inline std::pair<uint8_t, uint8_t> selected_stick = { 0, -1 };
	static inline std::pair<uint8_t, uint8_t> selected_gpu   = { 0, -1 };

	static inline std::pair<uint16_t, std::vector<uint16_t>> selected_core = { 0, {} };
	static inline uint16_t output_type                                     = 0;
	static inline uint16_t refr_time                                       = 1;

	static inline TabNumber selected_page = TAB_CPU;
	static inline OptKeymap keymap        = ARROWS;
	static inline OptTempUnit temp_unit   = CELSIUS;

	static inline std::array<bool, LAST_TAB_NUMBER> page_visible {};

	static bool check_selected_type_valid(uint8_t selected_type);
	static bool check_selected_stick_valid(uint8_t selected_stick);
	static bool check_selected_gpu_valid(uint8_t selected_gpu);
	static bool check_selected_core_valid(uint16_t selected_core);

	Options() = delete;
	~Options() = delete;
};


#endif /* _OPTIONS_HPP_ */
