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

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

#ifdef WAPP_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 termcolour_data TermcolourData;
struct termcolour_data {
  HANDLE handle;
  WORD   default_colour;
  WORD   current_colour;

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

wapp_intern void init_data(TermcolourData *data);

wapp_intern WORD colours[COUNT_TERM_COLOUR] = {
    [WAPP_TERM_COLOUR_FG_BLACK]      = 0,
    [WAPP_TERM_COLOUR_FG_RED]        = FOREGROUND_RED,
    [WAPP_TERM_COLOUR_FG_GREEN]      = FOREGROUND_GREEN,
    [WAPP_TERM_COLOUR_FG_BLUE]       = FOREGROUND_BLUE,
    [WAPP_TERM_COLOUR_FG_CYAN]       = FOREGROUND_GREEN | FOREGROUND_BLUE,
    [WAPP_TERM_COLOUR_FG_MAGENTA]    = FOREGROUND_RED | FOREGROUND_BLUE,
    [WAPP_TERM_COLOUR_FG_YELLOW]     = FOREGROUND_RED | FOREGROUND_GREEN,
    [WAPP_TERM_COLOUR_FG_WHITE]      = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE,
    [WAPP_TERM_COLOUR_FG_BR_BLACK]   = FOREGROUND_INTENSITY,
    [WAPP_TERM_COLOUR_FG_BR_RED]     = FOREGROUND_RED | FOREGROUND_INTENSITY,
    [WAPP_TERM_COLOUR_FG_BR_GREEN]   = FOREGROUND_GREEN | FOREGROUND_INTENSITY,
    [WAPP_TERM_COLOUR_FG_BR_BLUE]    = FOREGROUND_BLUE | FOREGROUND_INTENSITY,
    [WAPP_TERM_COLOUR_FG_BR_CYAN]    = FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
    [WAPP_TERM_COLOUR_FG_BR_MAGENTA] = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
    [WAPP_TERM_COLOUR_FG_BR_YELLOW]  = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY,
    [WAPP_TERM_COLOUR_FG_BR_WHITE]   = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY,
};

void print_coloured_text(Str8RO *text, TerminalColour colour) {
  wapp_persist TermcolourData data = {0};
  if (data.handle == 0) {
    init_data(&data);
  }

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

  SetConsoleTextAttribute(data.handle, data.current_colour);
  printf(WAPP_STR8_SPEC, wapp_str8_varg((*text)));
}

wapp_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 // !WAPP_PLATFORM_WINDOWS
