#include "GUIHolder.h"

GUIHolder::GUIHolder()
{
	this->focused = -1;
	mouseTarget=0;
}

GUIHolder::~GUIHolder()
{
}

void GUIHolder::init() 
{
	// initialize font
	font = new GUIFont("Arial");
	font->setWidth(5);
	font->setHeight(14);	
	font->init();
}

void GUIHolder::deinit()
{
	font->destroy();
	this->clear();
}

void GUIHolder::removeByCallback(std::string callback, bool deleteitems)
{
	lista::iterator iter;
	for (iter=elements.begin(); iter!=elements.end(); iter++) {
			
	  GUIElement *o = *iter;
	  if(o!=0)
	    if(o->getCallback() == callback)
		{
		  if (iter != elements.end())
		  {
			 elements.erase(iter);
			 if(deleteitems)
			 {
				delete o;
				o = 0;
			 }
			  return;
			 iter = elements.begin();  
		  }
		}
	}

}


GUIElement *GUIHolder::getByCallback(std::string callback)
{
	lista::iterator iter;
	for (iter=elements.begin(); iter!=elements.end(); iter++) {
			
	  GUIElement *o = *iter;
	  if(o!=0)
	    if(o->getCallback() == callback)
			return o;
	}

	return 0;
}

void GUIHolder::render(float dt)
{
	GUIElement *e = 0;
	GUIElement *focus = 0;
	int n=0;

	lista::iterator iter;
	for (iter=elements.begin(); iter!=elements.end(); iter++) {
			
	  GUIElement *o = *iter;
	  if(o!=0)
	  {
		  o->render(dt);

		  if(focused == n)
			  focus = o;
	  }
	  n++;
	}

	// no focus element - default to first element
	if(focus==0)
	{
		focused = 0;
		iter = elements.begin();
		focus = *iter;
	}

	// draw focus - if focus element is 'alive'	
	if(focus!=0)
	{
		glLineWidth(2);
		e = focus;
		glColor4f(1,0,0,0.65f);
		const float offset = 0.15f;
		glEnable(GL_BLEND);
		glBegin(GL_LINE_STRIP);
			glVertex2f(e->x-offset,		 e->y-offset);
			glVertex2f(e->x-offset,		 e->y+e->h+offset);
			glVertex2f(e->x+e->w+offset, e->y+e->h+offset);
			glVertex2f(e->x+e->w+offset, e->y-offset);
			glVertex2f(e->x-offset,		 e->y-offset);
		glEnd();
		glDisable(GL_BLEND);
		glLineWidth(1);
	}
}

std::string GUIHolder::processEvent(GUIEvent &e)
{

	lista::iterator iter;
	int n=0;
	std::string ret;
	ret = "";
	if(e.eventtype==GUIEVENT_KEYBOARDPRESSED)
	{
		if(((GUIKeyboardEvent &)e).pressed==false && strcmp("tab", ((GUIKeyboardEvent &)e).key)==0)
		{
			if(((GUIKeyboardEvent &)e).shift == true)
				this->focused--;
			else
				this->focused++;

			this->focused %= elements.size(); //elements->getNodeCount();

		} else {

			// key was not tab - process keyboard event

			for (iter=elements.begin(); iter!=elements.end(); iter++) 
			{
					
			  GUIElement *o = *iter;
			  if(o!=0)
			  {
				  if(focused == n)
				  {
					 ret = o->checkKeyboardEvents((GUIKeyboardEvent &)e);
					 if(ret.length()>0)
						focused = n;
				  }

			  }
			  n++;
			}

		}
		
		return "";
	}
	
	n=0;
	ret="";
	for (iter=elements.begin(); iter!=elements.end(); iter++) {
		
		GUIElement *elem = *iter;
		if(elem!=0)
		{

			switch(e.eventtype)
			{
			case GUIEVENT_MOUSEMOVED:
					ret = elem->checkMouseMovedEvents((GUIMouseMovedEvent &)e);

					if(mouseTarget!=0)
					{	// hack
						e.eventtype = 100;
						mouseTarget->checkMouseMovedEvents((GUIMouseMovedEvent &)e);
					}

				break;
			case GUIEVENT_MOUSEPRESSED:
					if(((GUIMousePressedEvent &)e).up==true) mouseTarget = 0;

					ret = elem->checkMousePressedEvents((GUIMousePressedEvent &)e);
					if(ret=="CHANGE_FOCUS_TO_THIS")
					{
						focused = n;
						ret = "";
					} else if(ret.length()>0)
					{
						focused = n;
						
						GUIElement *t = this->getByCallback(ret);
						if(t->widgetType==GUISLIDER) mouseTarget = t;

						return ret;
					} 
				break;
			}

		 
		}
		n++;
	} 

	return ret;
}
	
void GUIHolder::addWidget(GUIElement *e)
{
	if(this->focused==-1) 
		this->focused = 0;

	elements.push_back(e);
	e->setHolderPointer(this); 
}

void GUIHolder::clear()
{

	// clear all widgets and free them
	lista::iterator iter;
	  for (iter=elements.begin(); iter!=elements.end(); iter++) {
		  GUIElement *o= *iter;
		  if(o!=0)
		  {
			elements.erase(iter);
			iter = elements.begin();
			delete o;
		  }
	  }	    
}
