
#include "stdafx.h"
#include "CGUI.h"
#include "../TextRecord/CTextRecord.h"
#include "CButtonText.h"

static int g_iPocetGui = 0;

//////////////////////////////////////////////////////////////////////////
// ffclose - zavre soubor
//////////////////////////////////////////////////////////////////////////
static inline bool ffclose(FILE *f)
{
	fclose(f);
	return FALSE;
}

//////////////////////////////////////////////////////////////////////////
// CompileText - Prekompiluje text a zameni '$' za ' '
//////////////////////////////////////////////////////////////////////////
std::string CompileText(std::string text)
{
	std::string ret = text;
	for(register i=0; i < text.size(); i++)
	{
		if(text[i] == '$') ret[i] = ' ';
	}
	return ret;
}

//////////////////////////////////////////////////////////////////////////
// Construktor - 
//////////////////////////////////////////////////////////////////////////
C_GUI_0::C_GUI_0()
{
	char name_log[255];
	sprintf(name_log, "GuiLog%d.txt", g_iPocetGui);
	_logFile.Create(name_log);
	g_iPocetGui++;
	g_focus = NULL;
}

//////////////////////////////////////////////////////////////////////////
// Destruktor - 
//////////////////////////////////////////////////////////////////////////
C_GUI_0::~C_GUI_0()
{
	this->DeleteMenu();
}

//////////////////////////////////////////////////////////////////////////
// Add - prida dalsi prvek
//////////////////////////////////////////////////////////////////////////
void C_GUI_0::Add(C_BASEGUI_0 *o)
{
	_vBase.push_back(o);
}

//////////////////////////////////////////////////////////////////////////
// Render - 
//////////////////////////////////////////////////////////////////////////
void C_GUI_0::Render()
{
	bool bLight = (bool)glIsEnabled(GL_LIGHTING);
	if(bLight) glDisable(GL_LIGHTING);
	for(std::vector<C_BASEGUI_0*>::iterator i = _vBase.begin(); i < _vBase.end();i++)
	{	
		bool f = false;
		if( _focus == *i) f = true;
		(*i)->Render(f);
	}
	if(bLight) glEnable(GL_LIGHTING);
}

//////////////////////////////////////////////////////////////////////////
//
//////////////////////////////////////////////////////////////////////////
void C_GUI_0::RenderText()
{
	//cButtonText.DrawButtonText();
	glColor3f(1, 1, 1);
	if( g_bText ) g_font.Print(g_ButtonTextPos.x, g_ButtonTextPos.y, g_ButtonText.c_str() );
	g_bText=0;
}

//////////////////////////////////////////////////////////////////////////
// Keyboard - 
//////////////////////////////////////////////////////////////////////////
void C_GUI_0::Keyboard(bool keys[255])
{
	if(_vBase.size() == 0) return;
	for(std::vector<C_BASEGUI_0*>::iterator i = _vBase.end()-1; i+1 > _vBase.begin();i--)
	{	
		if( _focus == *i) (*i)->Keyboard(keys);
	}
}

//////////////////////////////////////////////////////////////////////////
// MouseClick
//////////////////////////////////////////////////////////////////////////
int C_GUI_0::MouseClick(int button, int x, int y)
{
	if(_vBase.size() == 0) return -1;
	for(std::vector<C_BASEGUI_0*>::iterator i = _vBase.end()-1; i+1 > _vBase.begin(); i--)
	{	
		TRect rect = (*i)->GetRect();
		POINT t = {x, y};
		(*i)->MouseClickEx(button, x, y);
		if(ColPointToRect(t,rect) && (button == W_MOUSE_LEFT || button == W_MOUSE_UNLEFT) && ((*i)->GetState()) && (*i)->GetVisible() )
		{
			_focus = (*i);
			(*i)->MouseClick(button,x,y);
			return int( i - _vBase.begin() );
			break;
		}else
		{
			if(button == 0) _focus = NULL;
		}
	}
	return -1;
}

//////////////////////////////////////////////////////////////////////////
// MouseMove
//////////////////////////////////////////////////////////////////////////
int C_GUI_0::MouseMove(int x, int y)
{
	int ret=-1;
	if(_vBase.size() == 0) return -1;
	for(std::vector<C_BASEGUI_0*>::iterator i = _vBase.end()-1; i+1 > _vBase.begin();i--)
	{	
		TRect rect = (*i)->GetRect();
		POINT t = {x, y};
		(*i)->MouseMoveEx(x, y);
		if(ColPointToRect(t, rect) && (*i)->GetVisible() )
		{
			(*i)->MouseMove(x, y);
			return  int( i - _vBase.begin() );
		}
	}
	return ret;
}

//////////////////////////////////////////////////////////////////////////
// _readstr - nacte jeden radek
//////////////////////////////////////////////////////////////////////////
void C_GUI_0::_readstr(FILE *f, std::string &str)				// Načte jeden použitelný řádek ze souboru
{
	char temp[255];
	do
	{
		fgets((char*) temp, 255, f);
	} while ((temp[0] == '#') || (temp[0] == '\n'));
	
	str = temp;
	return;
}

//////////////////////////////////////////////////////////////////////////
// LoadGUIScript - nacita GUI menu z vlastniho scriptu, 
// pozn, bouzel jsem to musel resit bez knihovny <fstream>, pac me to hazelo error
//////////////////////////////////////////////////////////////////////////
bool C_GUI_0::LoadGUIScript(std::string file_name, C_TEXTURE_MANAGER_0 *tm, int tmFlag)
{
	FILE *soubor;
	soubor = fopen(file_name.c_str(), "rt");
	if(!soubor) 
	{
		cError.ErrorMsg(0, true, true, "Error loading Menu", file_name.c_str() );
		return FALSE;
	}
	_logFile.ExWrite("Loading GUI script : ");
	_logFile.ExWriteln(file_name);
	std::string text_temp;
	char temp[255];
	float verze;

	static TRect image_rect = {0, 0, 0, 0};
	static char name[255]; name[0] = '#';
	static char image1[255]; image1[0] = '#';
	static char image2[255]; image1[0] = '#';
	static char image3[255]; image1[0] = '#';
	static char text[255]; text[0] = '#';
	static char group[255]; group[0] = '#';
	static char font[255]; font[0] = '#';
	static char size=0;
	static TRGBi color; color.r = -1;

	textREC.Add( file_name.c_str() );
	do
	{
		_readstr(soubor, text_temp);
		sscanf(text_temp.c_str(), "begin GUI_editor %f\n", &verze);
		if(verze == 1.0f)
		{
			//textREC.Add(" ++ ");
			
			sscanf(text_temp.c_str(), "object %s\n", &temp);
			// IMAGE
			if(!strcmp(temp,"IMAGE") )
			{
				sscanf(text_temp.c_str(), " name %s\n", &name);
				sscanf(text_temp.c_str(), " rect %f %f %f %f\n", &image_rect.x, &image_rect.y, &image_rect.width, &image_rect.height);
				sscanf(text_temp.c_str(), " image1 %s\n", &image1);
				sscanf(text_temp.c_str(), " color %d %d %d\n", &color.r, &color.g, &color.b);	
				if(image_rect.width > 0 && image_rect.height > 0 && image1[0] != '#' && color.r != -1 && name[0] != '#')
				{
					_logFile.ExWrite("Laoding IMAGE \"");
					_logFile.ExWrite(CompileText(name));
					_logFile.ExWriteln("\"");
					
					TScriptObject object;
					object.name = CompileText(name);
					object.type_object = 0;
					object.rect = image_rect;
					object.color = color;
					object.name_texture_1 = CompileText(image1);
					_script_object.push_back(object);
					temp[0] = '\0';
					// nulovat promnene
					image_rect = RECT_NULL;
					image1[0] = '#';
					color.r = -1;
					name[0] = '#';
				}
				
			}
			
			// BUTTON
			if(!strcmp(temp,"BUTTON") )
			{
				sscanf(text_temp.c_str(), " name %s\n", &name);
				sscanf(text_temp.c_str(), " rect %f %f %f %f\n", &image_rect.x, &image_rect.y, &image_rect.width, &image_rect.height);
				sscanf(text_temp.c_str(), " image1 %s\n", &image1);
				sscanf(text_temp.c_str(), " image2 %s\n", &image2);
				sscanf(text_temp.c_str(), " image3 %s\n", &image3);
				sscanf(text_temp.c_str(), " color %d %d %d\n", &color.r, &color.g, &color.b);	
				if(image_rect.width > 0 && image_rect.height > 0 && image1[0] != '#' && name[0] != '#' && image1[1] != '#' && image1[2] != '#' && color.r != -1)
				{
					_logFile.ExWrite("Laoding BUTTON \"");
					_logFile.ExWrite(CompileText(name));
					_logFile.ExWriteln("\"");

					TScriptObject object;
					object.name = CompileText(name);
					object.type_object = 1;
					object.rect = image_rect;
					object.color = color;
					object.name_texture_1 = CompileText(image1);
					object.name_texture_2 = CompileText(image2);
					object.name_texture_3 = CompileText(image3);
					_script_object.push_back(object);
					temp[0] = '\0';
					// nulovat promnene
					image_rect = RECT_NULL;
					image1[0] = '#';
					image1[1] = '#';
					image1[2] = '#';
					color.r = -1;
					name[0] = '#';
				}
			}//end
			if(!strcmp(temp,"CHECKBOX") )
			{
				sscanf(text_temp.c_str(), " name %s\n", &name);
				sscanf(text_temp.c_str(), " rect %f %f %f %f\n", &image_rect.x, &image_rect.y, &image_rect.width, &image_rect.height);
				sscanf(text_temp.c_str(), " image1 %s\n", &image1);
				sscanf(text_temp.c_str(), " image2 %s\n", &image2);
				sscanf(text_temp.c_str(), " color %d %d %d\n", &color.r, &color.g, &color.b);	
				if(image_rect.width > 0 && image_rect.height > 0 && image1[0] != '#' && image1[1] != '#' && color.r != -1 && name[0] != '#')
				{
					_logFile.ExWrite("Laoding CHECKBOX \"");
					_logFile.ExWrite(CompileText(name));
					_logFile.ExWriteln("\"");

					TScriptObject object;
					object.name = CompileText(name);
					object.type_object = 2;
					object.rect = image_rect;
					object.color = color;
					object.name_texture_1 = CompileText(image1);
					object.name_texture_2 = CompileText(image2);
					_script_object.push_back(object);
					temp[0] = '\0';
					// nulovat promnene
					image_rect = RECT_NULL;
					image1[0] = '#';
					image1[1] = '#';
					color.r = -1;
					name[0] = '#';
				}
			}//end
			if(!strcmp(temp,"RADIOBUTTON") )
			{
				sscanf(text_temp.c_str(), " name %s\n", &name);
				sscanf(text_temp.c_str(), " rect %f %f %f %f\n", &image_rect.x, &image_rect.y, &image_rect.width, &image_rect.height);
				sscanf(text_temp.c_str(), " image1 %s\n", &image1);
				sscanf(text_temp.c_str(), " image2 %s\n", &image2);
				sscanf(text_temp.c_str(), " color %d %d %d\n", &color.r, &color.g, &color.b);
				sscanf(text_temp.c_str(), " group %s\n", &group);
				if(image_rect.width > 0 && image_rect.height > 0 && image1[0] != '#' && image1[1] != '#' && group[0] != '#' && color.r != -1 && name[0] != '#')
				{
					_logFile.ExWrite("Laoding RADIOBUTTON \"");
					_logFile.ExWrite(CompileText(name));
					_logFile.ExWriteln("\"");
					
					TScriptObject object;
					object.name = CompileText(name);
					object.type_object = 3;
					object.rect = image_rect;
					object.color = color;
					object.name_texture_1 = CompileText(image1);
					object.name_texture_2 = CompileText(image2);
					object.group = CompileText(group);
					_script_object.push_back(object);
					temp[0] = '\0';
					// nulovat promnene
					image_rect = RECT_NULL;
					image1[0] = '#';
					image1[1] = '#';
					color.r = -1;
					group[0] = '#';
					name[0] = '#';
				}
			}//end
			if(!strcmp(temp,"LABEL") )
			{
				sscanf(text_temp.c_str(), " name %s\n", &name);
				sscanf(text_temp.c_str(), " rect %f %f %f %f\n", &image_rect.x, &image_rect.y, &image_rect.width, &image_rect.height);
				sscanf(text_temp.c_str(), " data1 %s\n", &font);
				sscanf(text_temp.c_str(), " size %d\n", &size);
				sscanf(text_temp.c_str(), " text %s\n", &text);
				sscanf(text_temp.c_str(), " color %d %d %d\n", &color.r, &color.g, &color.b);
				if(image_rect.width > 0 && image_rect.height > 0 && size != 0 && font[0] !='#' && text[0] != '#' && color.r != -1 && name[0] != '#')
				{
					_logFile.ExWrite("Laoding LABEL \"");
					_logFile.ExWrite(CompileText(name));
					_logFile.ExWriteln("\"");

					TScriptObject object;
					object.name = CompileText(name);
					object.type_object = 4;
					object.rect = image_rect;
					object.color = color;
					object.font = CompileText(font);
					object.size = size;
					object.text = CompileText(text);
					
					_script_object.push_back(object);
					temp[0] = '\0';
					// nulovat promnene
					image_rect = RECT_NULL;
					font[0] = '#';
					size = 0;
					color.r = -1;
					text[0] = '#';
					name[0] = '#';
				}
			}//end
			if(!strcmp(temp,"EDIT") )
			{
				sscanf(text_temp.c_str(), " name %s\n", &name);
				sscanf(text_temp.c_str(), " rect %f %f %f %f\n", &image_rect.x, &image_rect.y, &image_rect.width, &image_rect.height);
				sscanf(text_temp.c_str(), " data1 %s\n", &font);
				sscanf(text_temp.c_str(), " size %d\n", &size);
				sscanf(text_temp.c_str(), " text %s\n", &text);
				sscanf(text_temp.c_str(), " color %d %d %d\n", &color.r, &color.g, &color.b);
				if(image_rect.width > 0 && image_rect.height > 0 && size != 0 && font[0] !='#' && text[0] != '#' && color.r != -1 && name[0] != '#')
				{
					_logFile.ExWrite("Laoding EDIT \"");
					_logFile.ExWrite(CompileText(name));
					_logFile.ExWriteln("\"");

					TScriptObject object;
					object.name = CompileText(name);
					object.type_object = 5;
					object.rect = image_rect;
					object.color = color;
					object.font = CompileText(font);
					object.size = size;
					object.text = CompileText(text);
					
					_script_object.push_back(object);
					temp[0] = '\0';
					// nulovat promnene
					image_rect = RECT_NULL;
					font[0] = '#';
					size = 0;
					color.r = -1;
					text[0] = '#';
					name[0] = '#';
				}
			}//end
			if(!strcmp(temp,"SLIDER") )
			{
				static int max_arr, hod_arr, akt_arr;
				sscanf(text_temp.c_str(), " name %s\n", &name);
				sscanf(text_temp.c_str(), " rect %f %f %f %f\n", &image_rect.x, &image_rect.y, &image_rect.width, &image_rect.height);
				sscanf(text_temp.c_str(), " image1 %s\n", &image1);
				sscanf(text_temp.c_str(), " image2 %s\n", &image2);
				sscanf(text_temp.c_str(), " max_arr %d\n", &max_arr);
				sscanf(text_temp.c_str(), " hod_arr %d\n", &hod_arr);
				sscanf(text_temp.c_str(), " akt_arr %d\n", &akt_arr);
				sscanf(text_temp.c_str(), " color %d %d %d\n", &color.r, &color.g, &color.b);	
				if(image_rect.width > 0 && image_rect.height > 0 && image1[0] != '#' && image1[1] != '#' && color.r != -1 && name[0] != '#')
				{
					_logFile.ExWrite("Laoding SLIDER \"");
					_logFile.ExWrite(CompileText(name));
					_logFile.ExWriteln("\"");
					
					TScriptObject object;
					object.name = CompileText(name);
					object.type_object = 6;
					object.rect = image_rect;
					object.color = color;
					object.max_arr = max_arr;
					object.hod_arr = hod_arr;
					object.akt_arr = akt_arr;
					object.name_texture_1 = CompileText(image1);
					object.name_texture_2 = CompileText(image2);
					_script_object.push_back(object);
					temp[0] = '\0';
					// nulovat promnene
					max_arr = 0;
					hod_arr = 0;
					akt_arr = 0;
					image_rect = RECT_NULL;
					image1[0] = '#';
					image1[1] = '#';
					color.r = -1;
					name[0] = '#';
				}
			}//end
		}
	} while(text_temp != "end.");

	if(tm != NULL) _CreateScriptObject(tm, tmFlag);
	fclose(soubor);
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////
// _CreateScriptObject - z aktualniho scriptu vytvori objekty
//////////////////////////////////////////////////////////////////////////
void C_GUI_0::_CreateScriptObject(C_TEXTURE_MANAGER_0 *tm, int tmFlag)
{
	for(std::vector<TScriptObject>::iterator i = _script_object.begin(); i < _script_object.end(); i++)
	{
		uint object = (*i).type_object;
		switch (object)
		{
		//////////////////////////////////////////////////////////////////////////
		case 0:		// C_IMAGE_0
			{
				
				int id_texture1 = tm->AddTexture( (*i).name_texture_1, tmFlag );
				tm->ReloadTextures();
				this->Add(new C_GIMAGE_0(i->name, tm->GetIdTexture( id_texture1 ), PrevedRectNaScreen((*i).rect), (*i).color));
			}
		break;
		//////////////////////////////////////////////////////////////////////////
		case 1:		// C_BUTTON_0
			{
				int id_texture1 = tm->AddTexture( (*i).name_texture_1, tmFlag );
				int id_texture2 = tm->AddTexture( (*i).name_texture_2, tmFlag );
				int id_texture3 = tm->AddTexture( (*i).name_texture_3, tmFlag );
				tm->ReloadTextures();
				this->Add(new C_BUTTON_0(i->name, tm->GetIdTexture( id_texture1 ),
					tm->GetIdTexture( id_texture2 ), tm->GetIdTexture( id_texture3 ), PrevedRectNaScreen((*i).rect), (*i).color));
			}
		break;
		//////////////////////////////////////////////////////////////////////////
		case 2:		// C_CHECKBOX_0
			{
				int id_texture1 = tm->AddTexture( (*i).name_texture_1, tmFlag );
				int id_texture2 = tm->AddTexture( (*i).name_texture_2, tmFlag );
				tm->ReloadTextures();
				this->Add(new C_CHECKBOX_0(i->name, tm->GetIdTexture( id_texture1 ),tm->GetIdTexture( id_texture2 ), PrevedRectNaScreen((*i).rect), (*i).color));
			}
		break;
		//////////////////////////////////////////////////////////////////////////
		case 3:		// C_RADIOBUTTON_0
			{
				int id_texture1 = tm->AddTexture( (*i).name_texture_1, tmFlag );
				int id_texture2 = tm->AddTexture( (*i).name_texture_2, tmFlag );
				tm->ReloadTextures();
				this->Add(new C_RADIOBUTTON_0(i->name, tm->GetIdTexture( id_texture1 ),tm->GetIdTexture( id_texture2 ), PrevedRectNaScreen((*i).rect),(*i).group, (*i).color));
			}
		break;
		//////////////////////////////////////////////////////////////////////////
		case 4:		// C_LABEL_0
			{
				font_data fn;
				fn.init((*i).font.c_str() , (*i).size );
				this->Add( new C_LABEL_0(i->name, fn, PrevedRectNaScreen((*i).rect).x, PrevedRectNaScreen((*i).rect).y, (*i).text ) );
			}
		break;
		//////////////////////////////////////////////////////////////////////////
		case 5:		// C_EDIT_0
			{
				font_data fn;
				fn.init((*i).font.c_str() , (*i).size );
				this->Add( new C_EDIT_0(i->name, PrevedRectNaScreen((*i).rect), (*i).text , fn) );
			}
		break;
		//////////////////////////////////////////////////////////////////////////
		case 6:		// C_SLIDER_0
			{
				int id_texture1 = tm->AddTexture( (*i).name_texture_1, tmFlag );
				int id_texture2 = tm->AddTexture( (*i).name_texture_2, tmFlag );
				tm->ReloadTextures();
				this->Add(new C_SLIDER_0(i->name, tm->GetIdTexture( id_texture1 ),tm->GetIdTexture( id_texture2 ), PrevedRectNaScreen((*i).rect), (*i).max_arr, (*i).hod_arr, (*i).akt_arr));
			}
		break;
		}
	}
}

//////////////////////////////////////////////////////////////////////////
// SetScreen -
//////////////////////////////////////////////////////////////////////////
void C_GUI_0::SetScreen(float x, float y)
{
	_screen.x = x; _screen.y = y;
}

//////////////////////////////////////////////////////////////////////////
// _PrevedRectNaScreen - 
//////////////////////////////////////////////////////////////////////////
TRect C_GUI_0::PrevedRectNaScreen(TRect rect)
{
	if(_screen.x == 640 && _screen.y == 480) return rect;
	float delitel_x = _screen.x/640;
	float delitel_y = _screen.y/480;

	rect.x		*=delitel_x; 
	rect.width	*=delitel_x; 
	rect.y		*=delitel_y; 
	rect.height *=delitel_y; 
	return rect;
}

int C_GUI_0::PrevedIntXNaScreen(int x)
{
	if(_screen.x == 640 && _screen.y == 480) return x;
	float delitel_x = _screen.x/640.0f;
	float xx = x*delitel_x; 
	return xx;
}

int C_GUI_0::PrevedIntYNaScreen(int y)
{
	if(_screen.x == 640 && _screen.y == 480) return y;
	float delitel_y = _screen.y/480.0f;
	float yy = y*delitel_y; 
	return yy;
}

//////////////////////////////////////////////////////////////////////////
// DeleteMenu - smaze nahrane menu
//////////////////////////////////////////////////////////////////////////
void C_GUI_0::DeleteMenu()
{
	_vBase.clear();
	_script_object.clear();
	_focus = NULL;
}

//////////////////////////////////////////////////////////////////////////
// GetIterObject - 
//////////////////////////////////////////////////////////////////////////
int C_GUI_0::GetIterObject(std::string name)
{
	std::vector<C_BASEGUI_0*>::iterator i = _vBase.begin();
	for(; i < _vBase.end(); i++)
	{
		if( (*i)->GetName() == name ) return (int)(i - _vBase.begin());
	}
	return -2;
}