/*
 * Logserver
 * Copyright (C) 2017-2025 Joel Reardon
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

#ifndef __COLOUR__H__
#define __COLOUR__H__

#include <cassert>
#include <ncurses.h>
#include <string>

#include "constants.h"

using namespace std;

/* class that performs colour-related helper functions */
class Colour {
public:
	// maps keyword index to a colour initialized in ncurses
	static int keyword_number_to_colour(int number) {
		static const vector<int> defaults = {
			COLOR_RED, COLOR_BLUE, COLOR_GREEN,
			COLOR_MAGENTA, COLOR_CYAN, COLOR_YELLOW
		};
		static const vector<int> many_defaults = {
			COLOR_RED, 8 + COLOR_BLUE, COLOR_GREEN,
			8 + COLOR_MAGENTA, 8 + COLOR_CYAN, COLOR_YELLOW,
			8 + COLOR_RED, COLOR_BLUE, 8 + COLOR_GREEN,
			COLOR_MAGENTA, COLOR_CYAN, 8 + COLOR_YELLOW
		};
		if (has_brights())
			return many_defaults[number % many_defaults.size()];
		return defaults[number % defaults.size()];
	}

	// returns true if console supports brights without bolding
	static bool has_brights() {
#ifdef CATCH_CONFIG_MAIN
		return false;
#else
		return COLORS >= 16;
#endif
	}

	/* 0 is used as default of white on black. converts ansi colour code to
	 * the ncurses colour index */
	static optional<int> ansi_colour(int val) {
		switch (val) {
			case 30: return COLOR_WHITE;
			case 31: return COLOR_RED;
			case 32: return COLOR_GREEN;
			case 33: return COLOR_YELLOW;
			case 34: return COLOR_BLUE;
			case 35: return COLOR_MAGENTA;
			case 36: return COLOR_CYAN;
			case 37: return COLOR_BLACK;
		}
		if (!has_brights()) return nullopt;
		switch (val) {
			case 90: return 8 + COLOR_WHITE;
			case 91: return 8 + COLOR_RED;
			case 92: return 8 + COLOR_GREEN;
			case 93: return 8 + COLOR_YELLOW;
			case 94: return 8 + COLOR_BLUE;
			case 95: return 8 + COLOR_MAGENTA;
			case 96: return 8 + COLOR_CYAN;
			case 97: return 8 + COLOR_BLACK;
		}
		return nullopt;
	}

	/* initializes the ncurses colour index */
	static void init_curses_colours() {
		assert(has_colors());
                start_color();
                init_pair(0, COLOR_WHITE, COLOR_BLACK);
                init_pair(1, COLOR_RED, COLOR_BLACK);
                init_pair(2, COLOR_GREEN, COLOR_BLACK);
                init_pair(3, COLOR_YELLOW, COLOR_BLACK);
                init_pair(4, COLOR_BLUE, COLOR_BLACK);
                init_pair(5, COLOR_MAGENTA, COLOR_BLACK);
                init_pair(6, COLOR_CYAN, COLOR_BLACK);
                init_pair(7, COLOR_BLACK, COLOR_WHITE);
		if (!has_brights()) return;
                init_pair(8, 8 + COLOR_WHITE, COLOR_BLACK);
                init_pair(9, 8 + COLOR_RED, COLOR_BLACK);
                init_pair(10, 8 + COLOR_GREEN, COLOR_BLACK);
                init_pair(11, 8 + COLOR_YELLOW, COLOR_BLACK);
                init_pair(12, 8 + COLOR_BLUE, COLOR_BLACK);
                init_pair(13, 8 + COLOR_MAGENTA, COLOR_BLACK);
                init_pair(14, 8 + COLOR_CYAN, COLOR_BLACK);
                init_pair(15, 8 + COLOR_BLACK, COLOR_WHITE);
	}


};

#endif  // __COLOUR__H__
