#include "vga.h"
#include "io.h"
#include "paging.h"
#include "log.h"

static uint cursor_x = 0;
static uint cursor_y = 0;

static uchar color = WHITE;

static ushort *fb = (ushort *)PHYS_TO_VIRT(0xB8000);

#define BUFFER_SIZE 16
static char buffer[BUFFER_SIZE];
static uint buffer_index = 0;
static bool in_escape = false;

static void move_cursor()
{
	ushort pos = cursor_y * 80 + cursor_x;

	outb(0x3d4, 0x0e);
	outb(0x3d5, pos >> 8);
	outb(0x3d4, 0x0f);
	outb(0x3d5, pos & 0xff);
}

static void scroll()
{
	ushort blank = ' ' | color << 8;

	while (cursor_y >= 25) // end of line
	{
		// scroll everything up
		memcpy(fb, &fb[80], 24 * 80 * 2);

		for (int i = 24 * 80; i < 25 * 80; i++)
		{
			fb[i] = blank;
		}

		cursor_y--;
	}
}

void vga_set_color(enum vga_colors fg, enum vga_colors bg)
{
	color = (bg << 4) | (fg & 0xf);
}

void got_escape()
{
	if (buffer[0] != '[')
		return;

	int c = parse_int(buffer+1);

	static const char ansi_to_vga_colors[] =
	{
		[30] = BLACK,
		RED,
		GREEN,
		LIGHT_BROWN,
		BLUE,
		MAGENTA,
		CYAN,
		WHITE,
		[90] = LIGHT_GREY,
		LIGHT_RED,
		LIGHT_GREEN,
		LIGHT_BROWN,
		LIGHT_BLUE,
		LIGHT_MAGENTA,
		LIGHT_CYAN,
		WHITE,
	};

	if (c == 0)
	{
		color = WHITE;
	}
	else if ((c >= 30 && c <= 37) || (c >= 90 && c <= 97))
	{
		color &= 0xf0;
		color |= ansi_to_vga_colors[c];
	}
	else if ((c >= 40 && c <= 47) || (c >= 100 && c <= 107))
	{
		color &= 0x0f;
		color |= ansi_to_vga_colors[c - 10] << 4;
	}
}

void vga_put(char c)
{
	if (in_escape)
	{
		if (buffer_index >= BUFFER_SIZE || c == 'm')
		{
			// For now we are only supporting color escape sequences.
			if (c == 'm')
				got_escape();

			// Escape sequence is too long, sorry. Failing silently.
			in_escape = false;
			buffer_index = 0;
			memset(buffer, 0, sizeof(buffer));
		}
		else
		{
			buffer[buffer_index++] = c;
		}

		return;
	}

	switch (c)
	{
	case '\b':
		if (cursor_x > 0)
			cursor_x--;
		fb[cursor_y * 80 + cursor_x] = ' ' | (color << 8);
		break;
	case '\t':
		cursor_x = (cursor_x + 8) & ~7;
		break;
	case '\n':
		cursor_y++;
	case '\r':
		cursor_x = 0;
		break;
	case 033:
		in_escape = true;
		break;
	default:
		fb[cursor_y * 80 + cursor_x] = c | (color << 8);
		cursor_x++;
	}

	if (cursor_x >= 80) // off screen
	{
		cursor_x = 0;
		cursor_y++;
	}

	scroll();
	move_cursor();
}

void vga_clear()
{
	for (int i = 0; i < 25 * 80; i++)
	{
		fb[i] = ' ' | (WHITE << 8);
	}
	
	cursor_x = 0;
	cursor_y = 0;
	move_cursor();
}

void vga_write(char *c)
{
	for (int i = 0; c[i]; i++)
		vga_put(c[i]);
}

void vga_putd(uint d)
{
	char str[48];
	memset(str, 0, 48);
	uint i = 0;

	do
	{
		str[i++] = (d % 10) + '0';
		d /= 10;
	} while (d > 0 && i < 48); // should never be more than 48 digits anyway

	for (uint j = i; j; j--)
	{
		vga_put(str[j - 1]);
	}
}

static bool vga_put_nibble(uchar n, bool first)
{
	if (first && n == 0)
		return true;
	else if (n <= 9)
		vga_put('0' + n);
	else
		vga_put('A' + n - 10);

	return false;
}

void vga_putx(uint x)
{
	bool first = true;

	for (int shift = 24; shift >= 0; shift -= 8)
	{
		uchar byte = x >> shift;

		first = vga_put_nibble((byte & 0xf0) >> 4, first);
		first = vga_put_nibble(byte & 0x0f, first);
	}
}

void init_vga()
{
	// Enable and set max scan line
	outb(0x3D4, 0x09);
	outb(0x3D5, 15);

	// Cursor end line
	outb(0x3D4, 0x0B);
	outb(0x3D5, 15);

	// Cursor start line
	outb(0x3D4, 0x0A);
	outb(0x3D5, 14);
}
