//Copyright (C) 2007 SiegeLord
//See ReadMe.txt and License.txt for copying information

#include "../include/engine/gui.h"
#include "../include/engine/gfx.h"
#include "../include/engine/input.h"
#include "../include/engine/timer.h"

void CenterMouseOnTheFirst(SGUIItem* item)
{
	if(item->children.size() == 0)
		return;

	g_nMouseX = item->children[0]->x + item->children[0]->w - 1;
	g_nMouseY = item->children[0]->y + item->children[0]->h - 1;
	g_bMouseLocked = true;
}

void UpdateGUIPosition(SGUIItem* item, int cur_x, int cur_y)
{
	item->net_x = item->x;
	item->net_y = item->y;

	item->net_x += cur_x;
	item->net_y += cur_y;

	const int size = item->children.size();
	FOR1(size)
	{
		UpdateGUIPosition(item->children[ii], item->net_x, item->net_y);
	}
}

int HandleGUI(SGUIItem* item)
{
	if(!item->active)
		return 0;

	int ret = item->Handle();

	const int size = item->children.size();
	FOR1(size)
	{
		ret |= HandleGUI(item->children[ii]);
	}

	return ret;
}

int DoGUILogic(SGUIItem* item, int x, int y)
{
	UpdateGUIPosition(item, x, y);
	return HandleGUI(item);
}

void DrawGUI(SGUIItem* item)
{
	if(!item->visible || !item->active)
		return;

	item->Draw();

	const int size = item->children.size();
	FOR1(size)
	{
		DrawGUI(item->children[ii]);
	}
}

void DestroyGUI(SGUIItem* item)
{
	const int size = item->children.size();
	FOR1(size)
	{
		DestroyGUI(item->children[ii]);
	}

	delete item;
}

int GetMask(int n)
{
	return 1 << n;
}

////////////////////////////////////////////
//		Dummy Stuff
////////////////////////////////////////////

SGUIItem* InitGUIItem(SGUIItem* item, SGUIItem* parent, int x, int y, int w, int h)
{
	//memset(item, 0, sizeof(SGUIItem));

	item->parent = parent;
	item->x = x;
	item->y = y;
	item->h = h;
	item->w = w;

	item->active = true;
	item->visible = true;

	if(parent)
		parent->children.push_back(item);

	item->type = dummygui_type;

	return item;
}

////////////////////////////////////////////
//		KeyboardDummy Stuff
////////////////////////////////////////////

//I believe that key dummy captures any input and cycles among its children according to the keys pressed

int SKeyDummy::Handle()
{
	SGUIItem* child = 0;
	int child_pos = -1;

	const int size = children.size();

	if(size == 0)
		return 0;

	FOR1(size)
	{
		child = children[ii];

		if(g_nMouseX > child->net_x
		&& g_nMouseX < child->net_x + child->w
		&& g_nMouseY > child->net_y
		&& g_nMouseY < child->net_y + child->h)
		{
			child_pos = ii;
			break;
		}
	}
	bool first = false;
	if(child_pos == -1)
	{
		child = children[0];
		child_pos = 0;
		first = true;
	}

	if(first)
	{
		if(IsKeyJustPressed(KEY_UP) || IsKeyJustPressed(KEY_DOWN)
			|| IsKeyJustPressed(KEY_ENTER))
		{
			g_nMouseX = child->net_x + child->w - 1;
			g_nMouseY = child->net_y + child->h - 1;
			g_bMouseLocked = true;
		}
	}
	else
	{
		if(IsKeyJustPressed(KEY_UP))
		{
			child_pos--;
			if(child_pos < 0)
				child_pos += children.size();

			child = children[child_pos];

			g_nMouseX = child->net_x + child->w - 1;
			g_nMouseY = child->net_y + child->h - 1;
			g_bMouseLocked = true;
		}
		if(IsKeyJustPressed(KEY_DOWN))
		{
			child_pos++;
			child_pos %= children.size();

			child = children[child_pos];

			g_nMouseX = child->net_x + child->w - 1;
			g_nMouseY = child->net_y + child->h - 1;
			g_bMouseLocked = true;
		}
	}

	return 0;
}

SKeyDummy* CreateKeyDummy(SGUIItem* parent, int x, int y, int w, int h)
{
	SKeyDummy* item = new SKeyDummy();
	InitGUIItem(item, parent, x, y, w, h);
	return item;
}

////////////////////////////////////////////
//		Button Stuff
////////////////////////////////////////////

int SButton::Handle()
{
	if(!active)
		return 0;
	if(g_nMouseX > net_x
		&& g_nMouseX < net_x + w
		&& g_nMouseY > net_y
		&& g_nMouseY < net_y + h)
	{
		if(IsMKeyDown(0) || IsKeyDown(KEY_ENTER))
		{
			color = color_press;
			factor = time;
		}
		else//this adds to the factor
		{
			if(factor < 0)
				factor = 0;
			factor += g_fRawDelta;
			if(factor > time)
				factor = time;

			color = BlendColors(color_up, color_hover, factor / time);
		}

		if(IsMKeyJustReleased(0) || IsKeyJustPressed(KEY_ENTER))
		{
			return return_value;
		}
	}
	else//this subtracts from the factor
	{
		if(factor < -time)//special reset switch
		{
			color = color_up;
			factor = -time;
		}
		else
		{
			if(factor > 0)
				factor = 0;
			factor -= g_fRawDelta;
			if(factor < -time)
				factor = -time;

			color = BlendColors(color_hover, color_up, -factor / time);
		}
	}
	return 0;
}

void SButton::Draw()
{
	if(!visible)
		return;

	if(text)
		DrawTextAlign(text, net_x + w / 2, net_y + h / 2, 0, 0, color, fnt);

	DrawModeAlpha();
	float old_thick = SetLineThickness(2.0f);

	DrawRect(net_x, net_y, net_x + w, net_y + h, -10, color);

	SetLineThickness(old_thick);

	DrawModeSolid();
}

SButton::~SButton()
{
	delete[] text;
}

SButton* CreateButton(SGUIItem* parent, int x, int y, int w, int h, int ret, const char* text
				 	 , FONT* fnt)
{
	SButton* item = new SButton();
	InitGUIItem(item, parent, x, y, w, h);

	if(text)
		item->text = strdup(text);
	else
		item->text = 0;
	item->return_value = ret;
	item->fnt = fnt;

	item->color_hover = 0xffffcd34;
	item->color_press = 0xffffffff;
	item->color_up = 0xffbc9727;
	item->time = 0.5;
	item->factor = -10.0f;

	return item;
}

////////////////////////////////////////////
//		TextBox Stuff
////////////////////////////////////////////

void STextBox::Draw()
{
	DrawTextAlign(text, net_x + w / 2, net_y + h / 2, v_align,
		h_align, color, fnt);
}

STextBox::~STextBox()
{
	delete[] text;
}

STextBox* CreateTextBox(SGUIItem* parent, int x, int y, int w, int h, const char* text,
				  int v_align, int h_align, zColor color, FONT* fnt)
{
	STextBox* item = new STextBox();
	InitGUIItem(item, parent, x, y, w, h);

	item->text = text;
	item->color = color;
	item->v_align = v_align;
	item->h_align = h_align;
	item->fnt = fnt;

	return item;
}
////////////////////////////////////////////
//		TextBoxEx Stuff
////////////////////////////////////////////
