#pragma once
// тут будут собраны все глобальные вещи, которые не относятся к конфигу


namespace STATUS_LINE // поля строки состояния главного окна
{
	enum FIELD : int
	{
		SYSTEM = 0,
		KBD_XLAT,
		KBD_CAPS,
		KBD_AR2,
		KBD_SU,
		SCR_REZ,
		CPU_FRQ,
		INFO,
		KBD_SHIFT // фейковая панель.
	};
}



// массивы названий страниц памяти в карте памяти для различных устройств
extern const std::array<const std::wstring, 16> g_arStrSMKPgNums;
extern const std::array<const std::wstring, 4> g_arStrMMVw1;
extern const std::array<const std::wstring, 5> g_arStrMMVw_A16M;
extern const std::array<const std::wstring, 5> g_arStrMMVw_SMK;
extern const std::array<const std::wstring, 4> g_arStrMMVw_AZ;

// массив подготовленных данных для карты памяти
extern std::array<std::array<std::wstring, 9>, 2> g_arStrMMVData;
// массив подготовленных данных для потокового дизассемблера
extern std::array<std::wstring, 18> g_arStrStDsData;

extern const CString g_ConsoleName;
extern const std::wstring g_strEmptyUnit; // идентификатор. означает, что к данному приводу/в данный слот/прочее ничего не подключено.


extern const std::array<TCHAR, 128> koi8tbl;

namespace Global
{
	CString     WordToOctString(const uint16_t word);
	CString     ByteToOctString(const uint8_t byte);
	void        WordToOctString(uint16_t word, CString &str);
	void        ByteToOctString(uint8_t byte, CString &str);
	uint16_t    OctStringToWord(const CString &str);
	CString     IntToString(const int iInt, const int radix = 10);
	CString     IntToFileLengthString(const int iInt);
	CString     MsTimeToTimeString(const int msTime);
	void        SetSafeName(std::wstring &str);
	void        SetSafeDir(std::wstring &str);

	std::wstring BKToUNICODE(std::span<uint8_t> pBuff);
	TCHAR       BKToWIDEChar(const uint8_t b);
	TCHAR       BKToSafeWIDEChar(const uint8_t b);
	void        UNICODEtoBK(const std::wstring &ustr, std::span<uint8_t> pBuff, const bool bFillBuf);
	uint8_t     WIDEtoBKChar(const TCHAR ch);

	int         ToInt(const CString &str);
	long        ToLong(const CString &str);
	long long   ToLongLong(const CString &str);
	unsigned long ToULong(const CString &str);
	unsigned long long ToULongLong(const CString &str);

	CString     DwordToStr(DWORD d);
	DWORD       StrToDword(const CString &str);

#ifdef _DEBUG
	void        GetLastErrorOut(LPTSTR lpszFunction);
#endif

	bool        CheckFFMPEG();

	bool        SaveRawFile(const uint8_t *buf, const uint16_t addr, const uint16_t len, const fs::path &strName);
	bool        SaveBinFile(const uint8_t *buf, const uint16_t addr, const uint16_t len, const fs::path &strName);

	struct BinFileParameters_t
	{
		uint16_t addr{ 0 };
		uint16_t length{ 0 };
		uint16_t offset{ 0 };
		bool     isCrc{ false };
	};

	bool        CheckBinHeader(const uintmax_t fsize, BinFileParameters_t &bfp);
	bool        CheckBinFile(const fs::path &pathName, BinFileParameters_t &bfp);
	bool        LoadBinFile(std::unique_ptr<uint8_t[]> &buf, uint16_t &addr, uint16_t &len, const fs::path &pathName, const bool bStrict);

	bool        isEmptyUnit(const CString &s);
	bool        isEmptyUnit(const std::wstring &s);
	bool        isEmptyUnit(const fs::path &s);

	inline int GetDigit(const uint16_t word, const int pos)
	{
		return (pos ? (word >> ((pos << 1) + pos)) : word) & 7;
	}

	static CString getCompileDate(const LPCTSTR &p_format = _T("%Y-%m-%d"))
	{
		COleDateTime tCompileDate;
		tCompileDate.ParseDateTime(_T(__DATE__), LOCALE_NOUSEROVERRIDE, 1033);
		return tCompileDate.Format(p_format);
	}

	static CString getCompileTime(const LPCTSTR &p_format = _T("%H-%M-%S"))
	{
		COleDateTime tCompileDate;
		tCompileDate.ParseDateTime(_T(__TIME__), LOCALE_NOUSEROVERRIDE, 1033);
		return tCompileDate.Format(p_format);
	}

	void    SetMonospaceFont(HWND hwnd, CFont *pFont);

	// когда нихрена не получается с форматным выводом std::format поможет это
	template<typename... Args>
	std::wstring dyna_wprint(std::wstring_view rt_fmt_str, Args &&... args)
	{
		return std::vformat(rt_fmt_str, std::make_wformat_args(args...));
	}

	template<typename... Args>
	std::string dyna_print(std::string_view rt_fmt_str, Args &&... args)
	{
		return std::vformat(rt_fmt_str, std::make_format_args(args...));
	}
}

