/**
 * This is a test file and a terminal color table program
 */
import Ansi, { AnsiColor, Ground } from '../src/common/ansi.ts';
// ----------------------------------------------------------------------------
// Display table of the 256 type color console escape codes
// ----------------------------------------------------------------------------

const addColor = (fore: string, back: string): string => {
	let output = '';
	output += fore;
	output += back;

	return output;
};

const padNum = (num: number): string =>
	String(num).padStart(3, ' ').padEnd(5, ' ');

const colorBlock = (
	start: number,
	end: number,
	block: (i: number) => [string, string],
): string => {
	let output = '';

	for (let i = start; i < end; i++) {
		const [fg, bg] = block(i);

		output += addColor(fg, bg);
		output += padNum(i);
		output += Ansi.ResetFormatting;
	}
	return output;
};

function print16colorTable(): void {
	const drawRow = (start: number): string => {
		let end = start + 8;

		let blocks = [
			colorBlock(
				start,
				end,
				(i: number) => [Ansi.textFormat(i), Ansi.color.background.Black],
			),
			colorBlock(
				start,
				end,
				(i: number) => [Ansi.textFormat(i), Ansi.color.background.BrightWhite],
			),
		];

		start += 10;
		end += 10;

		blocks.push(
			colorBlock(
				start,
				end,
				(i: number) => [Ansi.color.Black, Ansi.textFormat(i)],
			),
		);
		blocks.push(
			colorBlock(
				start,
				end,
				(i: number) => [Ansi.color.BrightWhite, Ansi.textFormat(i)],
			),
		);

		return blocks.join(' '.repeat(5));
	};

	let colorTable = [
		drawRow(30),
		drawRow(90),
	].join('\n');

	colorTable += '\n';

	console.log(colorTable);
}

function print256colorTable(): void {
	let colorTable = '';
	// deno-fmt-ignore
	const breaks = [
		7, 15,
		21, 27, 33, 39, 45, 51, 
		57, 63, 69, 75, 81, 87, 
		93, 99, 105, 111, 117, 123, 
		129, 135, 141, 147, 153, 159, 
		165, 171, 177, 183, 189, 195, 
		201, 207, 213, 219, 225, 231, 
		237, 243, 249, 255,
	];
	const doubleBreaks = [15, 51, 87, 123, 159, 195, 231, 255];

	breaks.forEach((line, n) => {
		const start = (n > 0) ? breaks[n - 1] + 1 : 0;
		const end = line + 1;

		const blocks = [
			colorBlock(
				start,
				end,
				(
					i: number,
				) => [Ansi.color256(i, Ground.Fore), Ansi.color.background.Black],
			),
			colorBlock(
				start,
				end,
				(
					i: number,
				) => [Ansi.color256(i, Ground.Fore), Ansi.color.background.BrightWhite],
			),
			colorBlock(
				start,
				end,
				(i: number) => [Ansi.color.Black, Ansi.color256(i, Ground.Back)],
			),
			colorBlock(
				start,
				end,
				(i: number) => [Ansi.color.BrightWhite, Ansi.color256(i, Ground.Back)],
			),
		];

		colorTable += blocks.join(' '.repeat(5));
		colorTable += '\n';

		if (doubleBreaks.includes(line)) {
			colorTable += '\n';
		}
	});

	console.log(colorTable);
}

print16colorTable();
print256colorTable();

/**
 * Test code for highlighting
 */
const decimal: number[] = [0, 117];
const bigDecimal = 123456789123456789n;
const octal: number[] = [0o15, 0o1];
const bigOctal = 0o777777777777n;
const hexadecimal: number[] = [0x1123, 0x00111];
const bigHex = 0x123456789ABCDEFn;
const binary: number[] = [0b11, 0b0011];
const bigBinary = 0b11101001010101010101n;