#include "pch.h"
#include "ScreenColors_Shared.h"
#include "StringUtil.h"

const std::array<std::array<uint32_t, 4>, 16> g_pColorPalettes_std =
{
	{
		//                                                              Palette#     01           10          11
		{Color_Black, Color_Blue, Color_Green, Color_Red},                // 00    синий   |   зелёный  |  красный
		{Color_Black, Color_Yellow, Color_Magenta, Color_Red},            // 01   жёлтый   |  сиреневый |  красный
		{Color_Black, Color_Cyan, Color_Blue, Color_Magenta},             // 02   голубой  |    синий   | сиреневый
		{Color_Black, Color_Green, Color_Cyan, Color_Yellow},             // 03   зелёный  |   голубой  |  жёлтый
		{Color_Black, Color_Magenta, Color_Cyan, Color_White},            // 04  сиреневый |   голубой  |   белый
		{Color_Black, Color_White, Color_White, Color_White},             // 05    белый   |    белый   |   белый
		{Color_Black, Color_DarkRed, Color_RedBrown, Color_Red},          // 06  тёмн-красн| красн-корич|  красный    !
		{Color_Black, Color_Salatovyi, Color_LightGreen, Color_Yellow},   // 07  салатовый | светл-зелён|  жёлтый     !
		{Color_Black, Color_Violet, Color_VioletBlue, Color_Magenta},     // 08  фиолетовый| фиол-синий | сиреневый   !
		{Color_Black, Color_LightGreen, Color_VioletBlue, Color_RedBrown},// 09 светл-зелён| фиол-синий |красн-корич  !
		{Color_Black, Color_Salatovyi, Color_Violet, Color_DarkRed},      // 10  салатовый | фиолетовый |тёмн-красный !
		{Color_Black, Color_Cyan, Color_Yellow, Color_Red},               // 11   голубой  |   жёлтый   |  красный
		{Color_Black, Color_Red, Color_Green, Color_Cyan},                // 12   красный  |   зелёный  |  голубой
		{Color_Black, Color_Cyan, Color_Yellow, Color_White},             // 13   голубой  |   жёлтый   |   белый
		{Color_Black, Color_Yellow, Color_Green, Color_White},            // 14   жёлтый   |   зелёный  |   белый
		{Color_Black, Color_Cyan, Color_Green, Color_White}               // 15   голубой  |   зелёный  |   белый
	}
};

// 0,1,2,3
const std::array<std::array<uint32_t, 4>, 2> g_pMonochromePalette_std =
{
	{
		{Color_Black, Color_White, Color_Black, Color_White},
		{Color_Black, Color_Black, Color_White, Color_White}
	}
};

const std::array<std::array<uint32_t, 4>, 8> g_pAdaptMonochromePalette_std =
{
	{
		// Gray
		{Color_Black, 0xff6B6B6B, 0xffa9a9a9, Color_White},
		{Color_Black, 0xff6B6B6B, 0xffa9a9a9, Color_White},
		// Green
		{0xff111b14, 0xff2e8b57, 0xff48a36d, Color_Green /*0xff9ac5a8*/},
		{0xff111b14, 0xff2e8b57, 0xff48a36d, Color_Green /*0xff9ac5a8*/},
		// Blue
		{0xff03000F, 0xff3300CC, 0xff3A00EA, Color_Blue},
		{0xff03000F, 0xff3300CC, 0xff3A00EA, Color_Blue},
		// Yellow
		{0xff0A0700, 0xffB57E00, 0xffFFAE00, Color_Yellow},
		{0xff0A0700, 0xffB57E00, 0xffFFAE00, Color_Yellow}
	}
};


std::array<std::array<uint32_t, 4>, 16> g_pColorPalettes = { {{0,}} };
std::array<std::array<uint32_t, 4>, 2> g_pMonochromePalette = { {{0,}} };
std::array<std::array<uint32_t, 4>, 8> g_pAdaptMonochromePalette = { {{0,}} };


std::wstring ColorToStr(const DWORD col)
{
	const std::wstring str = std::format(_T("#{:06x}"), (col & 0xffffff));
	return str;
}

// вход: массив из 4 слов
// выход: строки типа #rrggbb,#rrggbb,#rrggbb,#rrggbb
std::wstring PaletteToStr(const std::span<const uint32_t> pal)
{
	std::wstring strOut;
	bool bNoFirst = false;

	for (const auto &p : pal)
	{
		if (bNoFirst)
		{
			strOut += L",";
		}

		bNoFirst = true;
		strOut += ColorToStr(p);
	}

	return strOut;
}

// вход: strPal - строка типа #rrggbb,#rrggbb,#rrggbb,#rrggbb
// pal - массив из 4 слов
// выход: заполненный массив, сколько определится, столько и заполняется, но не более 4
void StrToPalette(const std::wstring &strPal, std::span<uint32_t> pal)
{
	auto str = strUtil::trim(strPal);
	int delim = 0;

	for (uint32_t &n : pal) // количество принимаемых значений
	{
		auto sharp = str.find(L'#', delim); // поищем начало числа

		if (sharp == std::wstring::npos)  // если не нашлось
		{
			break;      // значит всё, нечего больше определять
		}

		delim = str.find(L',', delim + 1); // поищем конец

		if (delim == std::wstring::npos) // если не нашлось - то конец это конец строки
		{
			delim = str.length();
		}

		sharp++; // сдвинемся с позиции '#', чтоб его не захватывать
		std::wstring strNum = strUtil::trim(str.substr(sharp, delim - sharp)); // выделим нужный участок
		n = 0xff000000; // начальное значение - 0

		if (!strNum.empty()) // если что-то было
		{
			size_t *p = nullptr;
			n |= (std::stoul(strNum, p, 16) & 0xffffff); //преобразуем в число
		}

		if (delim == str.length()) // если дошли до конца строки
		{
			break;  // то выходим из цикла
		}
	}
}

