/*
 * ExNihilo 3D Engine
 * 
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 *
 * Please read AUTHORS file !!!
 * 
 *
 */

#include "ExCWindow.h"
//--------------------------------
// Constructor // Destructor
//--------------------------------
ExCWindow::ExCWindow(void)
{
Guard(ExCWindow::ExCWindow(void))
	Init();
UnGuard
}

ExCWindow::ExCWindow(ExCVec2D Size)
{
Guard(ExCWindow::ExCWindow(ExCVec2D Size))
	Init();
	SetWindowSize(Size);
	SetOldWindowSize(Size);
	RefreshSize();
	RefreshPosotion();
UnGuard
}

ExCWindow::ExCWindow(ExCVec2D Size,ExCVec2D Position)
{
Guard(ExCWindow::ExCWindow(ExCVec2D Size,ExCVec2D Position))
	Init();
	SetPosition(Position);
	SetOldPosition(Position);
	SetWindowSize(Size);
	SetOldWindowSize(Size);
	RefreshSize();
	RefreshPosotion();
UnGuard
}

ExCWindow::ExCWindow(ExCVec2D Size,ExCVec2D Position,std::string Title)
{
Guard(ExCWindow::ExCWindow(ExCVec2D Size,ExCVec2D Position,std::string Title))
	Init();
	SetWindowTitle(Title);
	SetPosition(Position);
	SetOldPosition(Position);
	SetWindowSize(Size);
	SetOldWindowSize(Size);
	RefreshSize();
	RefreshPosotion();
UnGuard
}

void ExCWindow::Init(void)
{
Guard(void ExCWindow::Init(void))
	ExCWindowObject::Init();
	SetName("ExCWindow");
	SetType(typeid(this).name());
	m_Parent=NULL;
	m_BeClosed=false;
	//------------------------------
	//Create window
	//------------------------------
	m_Window.SetName("MainWindow"+GetWindowTitle());
	m_Window.SetBackroundTexturing1(false,"back");
	m_Window.SetBackroundTexturing2(false,"fire");
	m_Window.SetBackroundColor(ExCVec3D(1.0f,1.0f,1.0f));
	m_Window.SetCanMouve(false);
	
UnGuard
}

ExCWindow::~ExCWindow(void)
{
}

//--------------------------------
// Methode
//--------------------------------
void ExCWindow::Draw(void)
{
Guard(void ExCWindow::Draw(void))
	//std::cout<<"Draw windows"<<std::endl;
	ExNihilo::EnterOrthoMode();
	glPushAttrib(GL_ALL_ATTRIB_BITS);
	glPushMatrix();
		glDisable(GL_LIGHTING);
		//Draw TitleBar
		m_TitleBar.Draw();
		//Draw Window
		m_Window.Draw();
	glPopMatrix();
	glPopAttrib();
	ExNihilo::LeaveOrthoMode();
UnGuard
}



ExCAction ExCWindow::InputCommand(ExCCommand Command)
{
Guard(ExCAction ExCWindow::InputCommand(ExCCommand Command))
	if(m_TitleBar.PointInWindow(ExCVec2D(Command.m_MousePosx,Command.m_MousePosy)))
	{
		//std::cout<<"Dans la bar"<<std::endl;
		return InputAction(m_TitleBar.InputCommand(Command));
	}
	if(m_Window.PointInWindow(ExCVec2D(Command.m_MousePosx,Command.m_MousePosy)))
	{
		//std::cout<<"Dans la fenetre"<<std::endl;
		return InputAction(m_Window.InputCommand(Command));
	}
	return NOTHING;
UnGuard
}

ExCAction ExCWindow::InputAction(ExCAction Action)
{
Guard(ExCAction ExCWindow::InputAction(ExCAction Action))
	/*switch(Action.m_Action)
	{
	default:
		return Action;
	}
	if(Action.m_NextAction){return *Action.m_NextAction;}
	else{return NOTHING;}*/
	return Action;
UnGuard
}

void ExCWindow::SetManagerTexture(ExManagerTexture * Texture)
{
Guard(void ExCWindow::SetManagerTexture(ExManagerTexture * Texture))
	ManagerTexture = Texture;
	m_TitleBar.SetManagerTexture(ManagerTexture);
	m_Window.SetManagerTexture(ManagerTexture);
UnGuard
}

void ExCWindow::RefreshPosotion(void)
{
Guard(void ExCWindow::RefreshPosotion(void))
	//std::cout<<"Refresh pos"<<std::endl;
	m_TitleBar.SetPosition(ExCVec2D(m_Position.GetX(),m_Position.GetY()));
	m_Window.SetPosition(ExCVec2D(m_Position.GetX(),(m_Position.GetY()+m_TitleBarSize)));
	for(unsigned int i=0;i<m_Window.GetVecWindowObject()->size();i++)
	{
		m_Window.GetVecWindowObject()->at(i)->SetPosition(
			ExCVec2D(m_Window.GetPosition()+(m_Window.GetVecWindowObject()->at(i)->GetPosition()-m_Window.GetOldPosition())));	
	}
UnGuard
}	
void ExCWindow::RefreshSize(void)
{
Guard(void ExCWindow::RefreshSize(void))
	m_TitleBar.SetWindowSize(ExCVec2D(m_WindowSize.GetX(),m_TitleBarSize));
	m_Window.SetWindowSize(ExCVec2D(m_WindowSize.GetX(),m_WindowSize.GetY()-m_TitleBarSize));
UnGuard
}	

void ExCWindow::SetWindowSize(ExCVec2D vec)
{
Guard(void ExCWindow::SetWindowSize(ExCVec2D vec))
	m_WindowSize=vec;
	RefreshSize();
UnGuard
}
void ExCWindow::SetOldWindowSize(ExCVec2D vec)
{
Guard(void ExCWindow::SetOldWindowSize(ExCVec2D vec))
	m_OldSize=vec;
UnGuard
}

void ExCWindow::SetWindowPosition(ExCVec2D vec)
{
Guard(void ExCWindow::SetWindowPosition(ExCVec2D vec))
	SetOldPosition(GetPosition());
	SetPosition(vec);
	RefreshPosotion();
	RefreshSize();

UnGuard
}

void ExCWindow::SetOldPosition(ExCVec2D vec)
{
Guard(void ExCWindow::SetOldPosition(ExCVec2D vec))
	m_OldPosition=vec;
UnGuard
}
void ExCWindow::SetTitleBarSize(float size)
{
Guard(void ExCWindow::SetTitleBarSize(float size))
	m_TitleBarSize=size;
	m_TitleBar.SetWindowSize(ExCVec2D(m_WindowSize.GetX(),m_TitleBarSize));
UnGuard
}	

void ExCWindow::SetWindowTitle(std::string Title)
{
	m_WindowTitle=Title;
	m_TitleBar.SetWindowTitle(Title);
}
std::string  ExCWindow::GetWindowTitle(void)
{
	return m_TitleBar.GetWindowTitle();
}
void ExCWindow::SetWindowOldTitle(std::string Title)
{
	m_WindowOldTitle=Title;
	m_TitleBar.SetWindowOldTitle(Title);
}
std::string  ExCWindow::GetWindowOldTitle(void)
{
	return m_TitleBar.GetWindowOldTitle();
}
void ExCWindow::SetWindowTitleColor(ExCVec3D Color)
{
	m_WindowTitleColor=Color;
	m_TitleBar.SetWindowTitleColor(Color);
}	
ExCVec3D ExCWindow::GetWindowTitleColor(void)
{
	return m_TitleBar.GetWindowTitleColor();
}

bool ExCWindow::PointInWindow(ExCVec2D point)
{
	if(ExCWindowObject::PointInWindow(point))
	{
		if(m_TitleBar.PointInWindow(point))return true;
		if(m_Window.PointInWindow(point))
		{
			if(m_Window.IsShowWindow())return true;
			else return false;
		}
		
	}
	return false;
	
}

bool ExCWindow::LoadFile(std::string FileName)
{
Guard(void ExCWindow::LoadFile(std::string FileName))
	char			buffer[255],b[255];
	std::string buffstring;
	std::ifstream file,fileControl;
	#ifdef UNIX_SRC
	sprintf(buffer, PREFIX "/ExNihilo/Data/Window/%s", FileName.data());
	#else
	sprintf(buffer, "../Data/Window/%s", FileName.data());
	#endif
	file.open(buffer,std::ios::in);
	if(file.is_open())
	{
		//read header 
		memset(b,0,255);file.getline(b,256,'\n');
		try
		{
			//READ MAIN WINDOW INFO
			ExNihilo::ExtracValueFromSring(b,"<WindowHeader>","<#WindowHeader>");
			Load(&file);

			//READ CONTENT WINDOW INFO
			memset(b,0,255);file.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<FileForWindow>","<#FileForWindow>");
			ReadWindowSubObject(this,buffstring);

			//READ BAR WINDOW INFO
			/*memset(b,0,255);file.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<FileForBar>","<#FileForBar>");
			ReadWindowSubObject(this,buffstring);
			*/
			m_TitleBar.LoadFile(ExNihilo::ExtracValueFromSring(b,"<FileForBar>","<#FileForBar>"));

		}catch(ExCExpStringNotFound){std::cout<<"Bad file type plok"<<buffer<<std::endl;}
	}else
	{
		std::cout<<"ExCExpFileNotFound:"<<buffer<<std::endl;
		throw   ExCExpFileNotFound();
	}
UnGuard
}

void ExCWindow::ReadWindowSubObject(ExCWindow *win,std::string FileName)
{
Guard(void ExCWindow::ReadWindowSubObject(ExCWindow *win,std::string FileName))
	char			buffer[255],b[255];
	std::string buffstring;
	std::ifstream file,fileButton,fileControl;
#ifdef UNIX_SRC
	sprintf(buffer, PREFIX "/ExNihilo/Data/Window/%s", FileName.data());
#else
	sprintf(buffer, "../Data/Window/%s", FileName.data());
#endif
	//std::cout<<buffer<<std::endl;
	file.open(buffer,std::ios::in);

	if(file.is_open())
	{
		//read header 
		memset(b,0,255);file.getline(b,256,'\n');
		try
		{
			buffstring=ExNihilo::ExtracValueFromSring(b,"<WindowHeader>","<#WindowHeader>");
			if(strcmp(buffstring.data(),"WindowContent")==0)
			{
				m_Window.Load(&file);	
				//Read all control
				memset(b,0,255);file.getline(b,256,'\n');
				int numberofcontrol=ExNihilo::ExtractIntValueFromSring(b,"<NumberOfControl>","<#NumberOfControl>");
				for(int i=0;i<numberofcontrol;i++)
				{
					memset(b,0,255);file.getline(b,256,'\n');
					ReadWindowControlObject(win->GetWindowContentPointer(),ExNihilo::ExtracValueFromSring(b,"<FileControl>","<#FileControl>"));
				}
			}
			if(strcmp(buffstring.data(),"BarContent")==0)
			{
				m_TitleBar.Load(&file);
				//READ CLOSE BUTTON
				memset(b,0,255);file.getline(b,256,'\n');
				buffstring=ExNihilo::ExtracValueFromSring(b,"<FileForButtonClose>","<#FileForButtonClose>");
#ifdef UNIX_SRC
				sprintf(buffer, PREFIX "/ExNihilo/Data/Window/%s", buffstring.data());
#else
				sprintf(buffer, "../Data/Window/%s", buffstring.data());
#endif
				fileButton.open(buffer,std::ios::in);
				if(fileButton.is_open())
				{
					memset(b,0,255);fileButton.getline(b,256,'\n');
					buffstring=ExNihilo::ExtracValueFromSring(b,"<WindowHeader>","<#WindowHeader>");
					m_CloseButton->Load(&fileButton);
					m_CloseButton->SetBackroundColor(ExCVec3D(1.0f,1.0f,1.0f));
				}fileButton.close();
				//READ Maximize BUTTON
				memset(b,0,255);file.getline(b,256,'\n');
				buffstring=ExNihilo::ExtracValueFromSring(b,"<FileForButtonMaximize>","<#FileForButtonMaximize>");
#ifdef UNIX_SRC
				sprintf(buffer, PREFIX "/ExNihilo/Data/Window/%s", buffstring.data());
#else
				sprintf(buffer, "../Data/Window/%s", buffstring.data());
#endif
				fileButton.open(buffer,std::ios::in);
				if(fileButton.is_open())
				{
					memset(b,0,255);fileButton.getline(b,256,'\n');
					buffstring=ExNihilo::ExtracValueFromSring(b,"<WindowHeader>","<#WindowHeader>");
					m_MaximizeButton->Load(&fileButton);
					m_MaximizeButton->SetBackroundColor(ExCVec3D(1.0f,1.0f,1.0f));
				}fileButton.close();
				//READ Minimize BUTTON
				memset(b,0,255);file.getline(b,256,'\n');
				buffstring=ExNihilo::ExtracValueFromSring(b,"<FileForButtonMinimize>","<#FileForButtonMinimize>");
#ifdef UNIX_SRC
				sprintf(buffer, PREFIX "/ExNihilo/Data/Window/%s", buffstring.data());
#else
				sprintf(buffer, "../Data/Window/%s", buffstring.data());
#endif
				fileButton.open(buffer,std::ios::in);
				if(fileButton.is_open())
				{
					memset(b,0,255);fileButton.getline(b,256,'\n');
					buffstring=ExNihilo::ExtracValueFromSring(b,"<WindowHeader>","<#WindowHeader>");
					m_MinimizeButton->Load(&fileButton);
					m_MinimizeButton->SetBackroundColor(ExCVec3D(1.0f,1.0f,1.0f));
				}fileButton.close();
				//READ MinimizeToBar BUTTON
				memset(b,0,255);file.getline(b,256,'\n');
				buffstring=ExNihilo::ExtracValueFromSring(b,"<FileForButtonMinimizeToBar>","<#FileForButtonMinimizeToBar>");
#ifdef UNIX_SRC
				sprintf(buffer, PREFIX "/ExNihilo/Data/Window/%s", buffstring.data());
#else
				sprintf(buffer, "../Data/Window/%s", buffstring.data());
#endif
				fileButton.open(buffer,std::ios::in);
				if(fileButton.is_open())
				{
					memset(b,0,255);fileButton.getline(b,256,'\n');
					buffstring=ExNihilo::ExtracValueFromSring(b,"<WindowHeader>","<#WindowHeader>");
					//ReadWindowObject(win->GetButtonMinimizeToBar(),&fileButton);
					m_MinimizeToBarButton->Load(&fileButton);
					m_MinimizeToBarButton->SetBackroundColor(ExCVec3D(1.0f,1.0f,1.0f));
				}fileButton.close();

			}
		}catch(ExCExpStringNotFound)
		{
			std::cout<<"ReadWindowSubObject::ExCExpStringNotFound";
		}
	}else throw   ExCExpFileNotFound();
	file.close();
	UnGuard
}

ExCWindowControl *  ExCWindow::ReadWindowControlObject(ExCWindowObject *win,std::string FileName)
{
	Guard(ExCWindowControl *  ExCWindow::ReadWindowControlObject(ExCWindowObject *win,std::string FileName))
		char			buffer[255],b[255];
	std::string buffstring;
	std::ifstream fileControl;
#ifdef UNIX_SRC
	sprintf(buffer, PREFIX "/ExNihilo/Data/Window/%s", FileName.data());
#else
	sprintf(buffer, "../Data/Window/%s", FileName.data());
#endif
	fileControl.open(buffer,std::ios::in);
	if(fileControl.is_open())
	{
		memset(b,0,255);fileControl.getline(b,256,'\n');
		buffstring=ExNihilo::ExtracValueFromSring(b,"<WindowHeader>","<#WindowHeader>");
		// EXCWINDOWLABEL CONTROL					
		if(strcmp(buffstring.data(),"ExCWindowLabel")==0)
		{
			ExCWindowLabel *NewLabel;
			NewLabel= new ExCWindowLabel;
			//ReadWindowObject(NewLabel,&fileControl);
			NewLabel->Load(&fileControl);
			win->AddObjectControl(NewLabel);
		}
		// EXCWINDOWEDITLABEL CONTROL					
		if(strcmp(buffstring.data(),"ExCWindowEditLabel")==0)
		{
			ExCWindowEditLabel *NewEditLabel;
			NewEditLabel= new ExCWindowEditLabel;
			//ReadWindowObject(NewLabel,&fileControl);
			NewEditLabel->Load(&fileControl);
			win->AddObjectControl(NewEditLabel);
		}
		// EXCWINDOWBUTTON CONTROL					
		if(strcmp(buffstring.data(),"ExCWindowButton")==0)
		{
			ExCWindowButton *NewButton;
			NewButton= new ExCWindowButton;
			//ReadWindowObject(NewButton,&fileControl);
			NewButton->Load(&fileControl);
			//READ ACTION FOR BUTTON
			memset(b,0,255);fileControl.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<ActionCommand>","<#ActionCommand>");
			ExCAction Action=ExNihilo::ExtractIntValueFromSring(buffstring,"<Action>","<#Action>");
			ExCCommand Command=ExNihilo::ExtractIntValueFromSring(buffstring,"<Command>","<#Command>");
			Action.m_Param=ExNihilo::ExtracValueFromSring(buffstring,"<Param>","<#Param>");
			NewButton->AddActionCommand(Action,Command);
			win->AddObjectControl(NewButton);
		}
		//EXCWINDOWBUTTONSWITCH CONTROL
		if(strcmp(buffstring.data(),"ExCWindowButtonSwitch")==0)
		{
			std::ifstream fileB1,fileB2;
			ExCWindowButtonSwitch *NewButton;
			NewButton= new ExCWindowButtonSwitch;
			//ReadWindowObject(NewButton,&fileControl);
			NewButton->Load(&fileControl);
			ExCWindowButton * Butt1,*Butt2;
			Butt1=new ExCWindowButton;
			Butt2=new ExCWindowButton;

			//Read Normal Button
			memset(b,0,255);fileControl.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<Button1>","<#Button1>");
	//ReadWindowObject(Butt1,buffstring,&fileB1);
			NewButton->m_Butt1=Butt1;


			//Read Alternate Button
			memset(b,0,255);fileControl.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<Button2>","<#Button2>");
	//ReadWindowObject(Butt2,buffstring,&fileB2);
			NewButton->m_Butt2=Butt2;

			//READ ACTION FOR BUTTON1
			memset(b,0,255);fileB1.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<ActionCommand>","<#ActionCommand>");
			ExCAction Action=ExNihilo::ExtractIntValueFromSring(buffstring,"<Action>","<#Action>");
			ExCCommand Command=ExNihilo::ExtractIntValueFromSring(buffstring,"<Command>","<#Command>");
			Action.m_Param=ExNihilo::ExtracValueFromSring(buffstring,"<Param>","<#Param>");
			Butt1->AddActionCommand(Action,Command);
			fileB1.close();

			//READ ACTION FOR BUTTON2
			memset(b,0,255);fileB2.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<ActionCommand>","<#ActionCommand>");
			Action=ExNihilo::ExtractIntValueFromSring(buffstring,"<Action>","<#Action>");
			Command=ExNihilo::ExtractIntValueFromSring(buffstring,"<Command>","<#Command>");
			Action.m_Param=ExNihilo::ExtracValueFromSring(buffstring,"<Param>","<#Param>");
			Butt2->AddActionCommand(Action,Command);
			fileB2.close();

			NewButton->SwitchValue();
			//NewButton->SwitchValue();
			win->AddObjectControl(NewButton);
		}
		//EXCWINDOWBUTTONSWITCHONMOUSE CONTROL
		if(strcmp(buffstring.data(),"ExCWindowButtonSwitchOnMouse")==0)
		{
			std::ifstream fileB1,fileB2;
			ExCWindowButtonSwitchOnMouse *NewButton;
			NewButton= new ExCWindowButtonSwitchOnMouse;
			//ReadWindowObject(NewButton,&fileControl);
			NewButton->Load(&fileControl);
			ExCWindowButton * Butt1,*Butt2;
			Butt1=new ExCWindowButton;
			Butt2=new ExCWindowButton;

			//Read Normal Button
			memset(b,0,255);fileControl.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<Button1>","<#Button1>");
	//ReadWindowObject(Butt1,buffstring,&fileB1);
			NewButton->m_Butt1=Butt1;


			//Read Alternate Button
			memset(b,0,255);fileControl.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<Button2>","<#Button2>");
	//ReadWindowObject(Butt2,buffstring,&fileB2);
			NewButton->m_Butt2=Butt2;

			//READ ACTION FOR BUTTON1
			memset(b,0,255);fileB1.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<ActionCommand>","<#ActionCommand>");
			ExCAction Action=ExNihilo::ExtractIntValueFromSring(buffstring,"<Action>","<#Action>");
			ExCCommand Command=ExNihilo::ExtractIntValueFromSring(buffstring,"<Command>","<#Command>");
			Action.m_Param=ExNihilo::ExtracValueFromSring(buffstring,"<Param>","<#Param>");
			Butt1->AddActionCommand(Action,Command);
			fileB1.close();

			//READ ACTION FOR BUTTON2
			memset(b,0,255);fileB2.getline(b,256,'\n');
			buffstring=ExNihilo::ExtracValueFromSring(b,"<ActionCommand>","<#ActionCommand>");
			Action=ExNihilo::ExtractIntValueFromSring(buffstring,"<Action>","<#Action>");
			Command=ExNihilo::ExtractIntValueFromSring(buffstring,"<Command>","<#Command>");
			Action.m_Param=ExNihilo::ExtracValueFromSring(buffstring,"<Param>","<#Param>");
			Butt2->AddActionCommand(Action,Command);
			fileB2.close();

			NewButton->SwitchValue();
			//NewButton->SwitchValue();
			win->AddObjectControl(NewButton);
		}
	}
	fileControl.close();
	return NULL;
	UnGuard
}