// vim:fileencoding=utf-8:foldmethod=marker

#include "../../../../common/aliases/aliases.h"
#include "../../../../common/platform/platform.h"
#include "../../../../base/strings/str8/str8.h"

#ifdef WP_PLATFORM_WINDOWS

#include "../terminal_colours.h"
#include "../../../../common/misc/misc_utils.h"
#include <stdio.h>

#define WIN32_LEAN_AND_MEAN
#include <Windows.h>

typedef struct TermcolourData TermcolourData;
struct TermcolourData {
	HANDLE handle;
	WORD   default_colour;
	WORD   current_colour;

	wpMiscUtilsReservePadding(sizeof(HANDLE) + sizeof(WORD) + sizeof(WORD));
};

wp_intern void init_data(TermcolourData *data);

wp_intern WORD colours[COUNT_TERM_COLOUR] = {
	[WP_TERM_COLOUR_FG_BLACK]      = 0,
	[WP_TERM_COLOUR_FG_RED]        = FOREGROUND_RED,
	[WP_TERM_COLOUR_FG_GREEN]      = FOREGROUND_GREEN,
	[WP_TERM_COLOUR_FG_BLUE]       = FOREGROUND_BLUE,
	[WP_TERM_COLOUR_FG_CYAN]       = FOREGROUND_GREEN | FOREGROUND_BLUE,
	[WP_TERM_COLOUR_FG_MAGENTA]    = FOREGROUND_RED | FOREGROUND_BLUE,
	[WP_TERM_COLOUR_FG_YELLOW]     = FOREGROUND_RED | FOREGROUND_GREEN,
	[WP_TERM_COLOUR_FG_WHITE]      = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
	[WP_TERM_COLOUR_FG_BR_BLACK]   = FOREGROUND_INTENSITY,
	[WP_TERM_COLOUR_FG_BR_RED]     = FOREGROUND_RED | FOREGROUND_INTENSITY,
	[WP_TERM_COLOUR_FG_BR_GREEN]   = FOREGROUND_GREEN | FOREGROUND_INTENSITY,
	[WP_TERM_COLOUR_FG_BR_BLUE]    = FOREGROUND_BLUE | FOREGROUND_INTENSITY,
	[WP_TERM_COLOUR_FG_BR_CYAN]    = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
	[WP_TERM_COLOUR_FG_BR_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
	[WP_TERM_COLOUR_FG_BR_YELLOW]  = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
	[WP_TERM_COLOUR_FG_BR_WHITE]   = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
};

void _printColouredText(WpStr8RO *text, WpTerminalColour colour) {
	wp_persist TermcolourData data = {0};
	if (data.handle == 0) {
		init_data(&data);
	}

	if (colour == WP_TERM_COLOUR_CLEAR) {
		data.current_colour = data.default_colour;
	} else {
		data.current_colour = colours[colour];
	}

	SetConsoleTextAttribute(data.handle, data.current_colour);
	printf(WP_STR8_SPEC, wpStr8Varg((*text)));
}

wp_intern void init_data(TermcolourData *data) {
	// create handle
	data->handle = GetStdHandle(STD_OUTPUT_HANDLE);

	// get console colour information
	CONSOLE_SCREEN_BUFFER_INFO csbi;
	GetConsoleScreenBufferInfo(data->handle, &csbi);
	data->default_colour = csbi.wAttributes;
	data->current_colour = data->default_colour;
}

#endif // !WP_PLATFORM_WINDOWS
