#include "Utils.hpp"

/**
 * @brief      Removes spaces.
 *
 * @param[in]  str   The string
 *
 * @return     String without spaces
 */
std::string removeSpaces(std::string str) {
	std::string cleanStr;
	for (int i = 0; i < str.size(); i++) {
		if (str[i] != ' ') cleanStr += str[i];
	}
	return cleanStr;
}

/**
 * @brief      Removes whitespace.
 *
 * @param[in]  str   The string
 *
 * @return     String without whitespace
 */
std::string removeWhitespace(std::string str) {
	std::string cleanStr;
	for (int i = 0; i < str.size(); i++) {
		switch (str[i]) {

			case ' ':
				break;

			case '\t':
				break;

			case '\n':
				break;

			default:
				cleanStr += str[i];

		}
	}
	return cleanStr;
}

void _thread_wait_for_str_cin(bool &done, std::string &text) {
	std::string result;

	// std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
	std::cin >> result;
	// std::cin.sync(); // działa z kompilatorem mingw (g++), ale nie MSVC
	text = result;
	done = true;
}

void _thread_wait_for_str_getline(bool& done, std::string& text) {
	std::string result;

	std::getline(std::cin, result);
	text = result;
	done = true;
}

short paths[4][44] = {

	// czerwony
	{
		114,
		103,  92,  81,  70,
		 69,  68,  67,  66,
		 55,  44,
		 45,  46,  47,  48,
		 37,  26,  15,   4,
		  5,   6,
		 17,  28,  39,  50,
		 51,  52,  53,  54,
		 65,  76,
		 75,  74,  73,  72,
		 83,  94, 105, 116,
		115, 104,  93,  82,  71
	},

	// niebieski
	{
		  6,
		 17,  28,  39,  50,
		 51,  52,  53,  54,
		 65,  76,
		 75,  74,  73,  72,
		 83,  94, 105, 116,
		115, 114,
		103,  92,  81,  70,
		 69,  68,  67,  66,
		 55,  44,
		 45,  46,  47,  48,
		 37,  26,  15,   4,
		  5,  16,  27,  38,  49
	},

	// żółty
	{
		 44,
		 45,  46,  47,  48,
		 37,  26,  15,   4,
		  5,   6,
		 17,  28,  39,  50,
		 51,  52,  53,  54,
		 65,  76,
		 75,  74,  73,  72,
		 83,  94, 105, 116,
		115, 114,
		103,  92,  81,  70,
		 69,  68,  67,  66,
		 55,  56,  57,  58,  59
	},

	// zielony
	{
		 76,
		 75,  74,  73,  72,
		 83,  94, 105, 116,
		115, 114,
		103,  92,  81,  70,
		 69,  68,  67,  66,
		 55,  44,
		 45,  46,  47,  48,
		 37,  26,  15,   4,
		  5,   6,
		 17,  28,  39,  50,
		 51,  52,  53,  54,
		 65,  64,  63,  62,  61
	}
};

short red_path[44] = {
	114,
	103,  92,  81,  70,
	 69,  68,  67,  66,
	 55,  44,
	 45,  46,  47,  48,
	 37,  26,  15,   4,
	  5,   6,
	 17,  28,  39,  50,
	 51,  52,  53,  54,
	 65,  76,
	 75,  74,  73,  72,
	 83,  94, 105, 116,
	115, 104,  93,  82,  71
};

short blue_path[44] = {
	  6,
	 17,  28,  39,  50,
	 51,  52,  53,  54,
	 65,  76,
	 75,  74,  73,  72,
	 83,  94, 105, 116,
	115, 114,
	103,  92,  81,  70,
	 69,  68,  67,  66,
	 55,  44,
	 45,  46,  47,  48,
	 37,  26,  15,   4,
	  5,  16,  27,  38,  49
};

short yellow_path[44] = {
	 44,
	 45,  46,  47,  48,
	 37,  26,  15,   4,
	  5,   6,
	 17,  28,  39,  50,
	 51,  52,  53,  54,
	 65,  76,
	 75,  74,  73,  72,
	 83,  94, 105, 116,
	115, 114,
	103,  92,  81,  70,
	 69,  68,  67,  66,
	 55,  56,  57,  58,  59
};

short green_path[44] = {
	 76,
	 75,  74,  73,  72,
	 83,  94, 105, 116,
	115, 114,
	103,  92,  81,  70,
	 69,  68,  67,  66,
	 55,  44,
	 45,  46,  47,  48,
	 37,  26,  15,   4,
	  5,   6,
	 17,  28,  39,  50,
	 51,  52,  53,  54,
	 65,  64,  63,  62,  61
};

short pawnInitialPositions[4][4] = {
	{
		 99, 100, 110, 111
	},
	{
		  9,  10,  20,  21
	},
	{
		  0,   1,  11,  12
	},
	{
		108, 109, 119, 120
	}
};

short colors_RGB[4][2][3] = {
	// czerwony
	{
		// obwódka
		{
			192,  67,  67
		},
		// wypełnienie
		{
			255, 166, 166
		}
	},
	// niebieski
	{
		// obwódka
		{
			102, 175, 187
		},
		// wypełnienie
		{
			187, 233, 255
		}
	},
	// żółty
	{
		// obwódka
		{
			211, 211,  30
		},
		// wypełnienie
		{
			255, 251, 141
		}
	},
	// zielony
	{
		// obwódka
		{
			102, 187, 103
		},
		// wypełnienie
		{
			187, 255, 200
		}
	}
};

/**
 * @brief      Convert field in fields matrix to relative position in paths matrix
 *
 * @param[in]  color  Player's color
 * @param[in]  field  Field in the matrix
 *
 * @return     Position inside paths relative to player's color
 */
short fieldToRelPos(short color, short field) {
	for (int i = 0; i < 44; i++) {
		if (paths[color][i] == field) {
			return i;
		}
	} return -1;
}

/**
 * @brief      Convert relative position in paths matrix to a field in fields matrix
 *
 * @param[in]  color  Player's color
 * @param[in]  field  Field in the matrix
 *
 * @return     Field in fields matrix relative to player's color
 */
short relPosToField(short color, short relPos) {
	if (relPos >= 0 && relPos < 44) return paths[color][relPos];
	else return -1;
}

/**
 * @brief      Gets the pawn initial position. Wrapper for pawnInitialPositions[][].
 *
 * @param[in]  color       Player's color
 * @param[in]  pawnNumber  Unique pawn number inside fields matrix
 *
 * @return     The pawn initial position.
 */
short getPawnInitialPosition(short color, short pawnNumber) {
	return pawnInitialPositions[color][pawnNumber];
}

cords3 color2RGBOutline(short color) {
	return cords3(colors_RGB[color][0][0], colors_RGB[color][0][1], colors_RGB[color][0][2]);
}

cords3 color2RGBFiller(short color) {
	return cords3(colors_RGB[color][1][0], colors_RGB[color][1][1], colors_RGB[color][1][2]);
}

cords2 fieldToXY(short field) {
	cords2 XY;
	XY.x = (field % 11) * 100 + 50;
	XY.y = static_cast<short>(field / 11) * 100 + 50;
	return XY;
}

short XYToField(short x, short y) {
	return static_cast<short>(y / 100) * 11 + static_cast<short>(x / 100);
}