#include "gui.h"
#include "font.h"
#include "wmwindow.h"
#include "array.h"


typedef struct WidgetCatalogS {
	uint8_t    key;    // Magic
	RegisterT *value;
} WidgetCatalogT;


ColorT   *__guiBaseColors   = NULL;
SurfaceT *__guiBackBuffer   = NULL;
SurfaceT *__guiScreenBuffer = NULL;
FontT    *__guiFontVGA8x14  = NULL;


static uint8_t         _magicCount        = 0;
static WidgetCatalogT *_widgetCatalog     = NULL;
static uint8_t         _guiRunning        = 1;
static SurfaceT       *_mousePointer      = NULL;
static ColorT          _mouseTransparency;


void guiRun(void) {
	EventT event;

	while (_guiRunning) {
		// Read mouse & keyboard.
		platformEventGet(&event);

		// Paint desktop.
		videoSurfaceSet(__guiBackBuffer);
		videoSurfaceClear(GUI_CYAN);

		// Paint GUI.
		wmPaint(&event);

		// Paint mouse pointer.
		videoSurfaceBlitWithTransparency(__guiBackBuffer, event.x, event.y, _mousePointer, _mouseTransparency);

		// Copy to screen.
		videoSurfaceBlit(__guiScreenBuffer, 0, 0, __guiBackBuffer);

		// Emergency Exit?
		if (event.flags & EVENT_FLAG_KEYPRESS && event.key == KEY_ESC) guiStop();
	}
}


void guiRegister(WidgetRegisterT widgetRegister) {
	RegisterT *reg = widgetRegister(_magicCount);
	hmput(_widgetCatalog, _magicCount, reg);
	_magicCount++;
}


void guiShutdown(void) {
	while (hmlen(_widgetCatalog) > 0) {
		if (_widgetCatalog[0].value->unregister) _widgetCatalog[0].value->unregister(NULL);
		hmdel(_widgetCatalog, _widgetCatalog[0].key);
	}
	hmfree(_widgetCatalog);

	wmShutdown();

	fontUnload(&__guiFontVGA8x14);

	videoSurfaceDestroy(_mousePointer);
	videoSurfaceDestroy(__guiBackBuffer);

	platformShutdown();
}


void guiStartup(int16_t width, int16_t height, int16_t depth) {

	platformStartup(width, height, depth);

	__guiScreenBuffer = videoSurfaceScreenGet();
	__guiBackBuffer   = videoSurfaceCreate(videoDisplayWidthGet(), videoDisplayHeightGet());

	_mousePointer = imageLoad("mouse.png");
	_mouseTransparency = videoSurfacePixelGet(_mousePointer, videoSurfaceWidthGet(_mousePointer) - 2, 0);  // Find our transparency color.

	__guiFontVGA8x14 = fontLoad("vga8x14.dat");

	wmStartup();

	guiRegister(windowRegister);
}


void guiStop(void) {
	_guiRunning = 0;
}


void guiWidgetBaseSet(WidgetT *widget, uint8_t magic, uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
	widget->magic = magic;

	widget->r.x = x;
	widget->r.y = y;
	widget->r.w = w;
	widget->r.h = h;

	widget->reg = hmget(_widgetCatalog, magic);
}
