/*
 * 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 !!!
 * 
 * $Id: ExManagerWindow.cpp,v 1.22 2002/12/13 11:45:02 data Exp $
 *
 */

#include "ExManagerWindow.h"

bool ExManagerWindow::m_flag = false; 
ExManagerWindow* ExManagerWindow::m_instance = NULL; 

ExManagerWindow::ExManagerWindow(void){
Guard(ExManagerWindow::ExManagerWindow(void))
	m_ShowGrille=false;

//	m_Antialliasing=true;
	
	/*
	options = new ExCOptions;
	
	m_ShowFps = options->getWindowShowfps ();
	
	m_WindowSizeX = options->getWindowResolutionX ();
	m_WindowSizeY = options->getWindowResolutionY ();
		m_Bits = options->getWindowDepth ();
	m_Rate = options->getWindowRate ();
	m_FullScreen = options->getWindowFullscreen () ;
	*/
	m_ShowFps = true;
	m_WindowSizeX = 800;
	m_WindowSizeY = 600;
	m_WindowSizeXOld = m_WindowSizeX;
	m_WindowSizeYOld = m_WindowSizeY;
	m_WindowPosX=0;
	m_WindowPosY=0;
	m_Bits = 16;
	m_Rate = 75;
	m_FullScreen = true ;
	m_OldMode=m_FullScreen;
	m_Cursor=GLUT_CURSOR_CROSSHAIR;
	
	m_Title=new char[strlen("ExNihilo Engine Version ")+20];
	sprintf(m_Title,"ExNihilo Engine Version %s",VERSION);
	
	m_IconTitle=new char[strlen("ExNihilo Engine Version ")+20];
	sprintf(m_IconTitle,"ExNihilo Engine Version %s",VERSION);

UnGuard
}

ExManagerWindow::~ExManagerWindow(void)
{
Guard(ExManagerWindow::~ExManagerWindow(void))
	m_flag=false;
UnGuard
}

ExManagerWindow* ExManagerWindow::CreateSingleton(void){
Guard(ExManagerWindow* ExManagerWindow::CreateSingleton(void))
	if(!m_flag)
	{
		m_flag = true; // We are creating the error log now, so set flag to true
		m_instance = new ExManagerWindow; // Create the error log
	}else
	{
		std::cout<<"Error singleton already created"<<std::endl;
	}
	return m_instance; 
UnGuard
}

void ExManagerWindow::CreateNewWindow(int SizeX,int SizeY,int PosX,int PosY,char *argv){
Guard(ExManagerWindow::CreateNewWindow(int SizeX,int SizeY,int PosX,int PosY,char *argv))
	m_WindowSizeX=SizeX;
	m_WindowSizeY=SizeY;
	m_WindowSizeXOld=SizeX;
	m_WindowSizeYOld=SizeY;
	m_WindowPosX=PosX;
	m_WindowPosY=PosY;
	glutInitWindowPosition(m_WindowPosX,m_WindowPosY);
	glutInitWindowSize(m_WindowSizeX,m_WindowSizeY);		
	m_WindowHandler=glutCreateWindow(m_Title);
	glutSetIconTitle(m_IconTitle);
	SetCursor(m_Cursor);
UnGuard
}

void ExManagerWindow::CreateNewWindow(int SizeX,int SizeY,char *argv){
Guard(ExManagerWindow::CreateNewWindow(int SizeX,int SizeY,char *argv))
	m_WindowSizeX=SizeX;
	m_WindowSizeY=SizeY;
	m_WindowSizeXOld=SizeX;
	m_WindowSizeYOld=SizeY;
	glutInitWindowPosition(m_WindowPosX,m_WindowPosY);
	glutInitWindowSize(m_WindowSizeX,m_WindowSizeY);		
	m_WindowHandler=glutCreateWindow(m_Title);
	glutSetIconTitle(m_IconTitle);
	SetCursor(m_Cursor);
UnGuard
}

void ExManagerWindow::Move(int Posx,int Posy){
Guard(ExManagerWindow::Move(int Posx,int Posy))
	m_WindowPosX=Posx;
	m_WindowPosY=Posy;
	glutPositionWindow(Posx,Posy);
UnGuard
}


void ExManagerWindow::SetResolution(int SizeX,int SizeY){
Guard(ExManagerWindow::SetResolution(int SizeX,int SizeY))
	m_WindowSizeXOld=m_WindowSizeX;
	m_WindowSizeYOld=m_WindowSizeY;	
	m_WindowSizeX=SizeX;
	m_WindowSizeY=SizeY;
UnGuard
}

void ExManagerWindow::SetWindowTitle(char *Title){
Guard(ExManagerWindow::SetWindowTitle(char *Title))
	m_Title = new char[strlen(Title)];
	sprintf(m_Title,"%s",Title);
	glutSetWindowTitle(m_Title);
UnGuard
}

void ExManagerWindow::SetIconTitle(char *Title){
Guard(ExManagerWindow::SetIconTitle(char *Title))
	m_IconTitle=new char[strlen(Title)];
	sprintf(m_IconTitle,"%s",Title);
	glutSetIconTitle(m_IconTitle);
UnGuard
}

void ExManagerWindow::SetCursor(int Cursor){
Guard(ExManagerWindow::SetCursor(int Cursor))
	glutSetCursor(Cursor);
UnGuard
}


void ExManagerWindow::Apply(void){
Guard(ExManagerWindow::Apply(void))
	if(m_FullScreen)
	{
		char *game;
		game=new char[15];
		sprintf(game,"%dx%d:%d@%d",m_WindowSizeX,m_WindowSizeY,m_Bits,m_Rate);
		if(m_OldMode)
		{
			glutDestroyWindow(m_WindowHandler);
		}

		glutGameModeString(game);

		if (glutGameModeGet(GLUT_GAME_MODE_POSSIBLE)) 
		{
			m_WindowHandler=glutEnterGameMode();
			GlutCallBack();
			glutSetWindow(m_WindowHandler);
			FluxAction->Push(ExCAction(RELOAD));
		}else 
		{
			std::cout << "Can not switch to fullscreen  error with your graphic card or glut lib " << std::endl;
		}
	}else
	{
		if(m_OldMode)
		{
			glutLeaveGameMode();
			glutInitWindowPosition(m_WindowPosX,m_WindowPosY);
			glutInitWindowSize(m_WindowSizeX,m_WindowSizeY);		
			m_WindowHandler=glutCreateWindow(m_Title);
		}else
		{
			glutReshapeWindow(m_WindowSizeX,m_WindowSizeY);
		}
	}
UnGuard
}

void ExManagerWindow::ShowFps(void)
{
Guard(void ExManagerWindow::ShowFps(void))
	frame++;
	timeframe=glutGet(GLUT_ELAPSED_TIME);
	if (timeframe - timebase > 1000) 
	{
		sprintf(s,"FPS:%4.2f",frame*1000.0/(timeframe-timebase));
		timebase = timeframe;		
		frame = 0;
	}
	char TimeSinceStart[30];
	sprintf(TimeSinceStart,"Time since start:%f",(double)((double)glutGet(GLUT_ELAPSED_TIME)/1000));
	ExNihilo::DrawCadre(15,10,165,50,0.2f,0.0f,0.6f,0.9f);
	ExNihilo::WriteToScreen(18,25,1,1,1,m_Title);
	ExNihilo::WriteToScreen(18,40,1,1,1,s);
	ExNihilo::WriteToScreen(18,55,1,1,1,TimeSinceStart);
	
UnGuard
}

ExCAction ExManagerWindow::InputCommand(ExCCommand Command)
{
Guard(ExManagerWindow::InputCommand(ExCCommand Command))
	return	NOTHING;
UnGuard
}

ExCAction ExManagerWindow::InputAction(ExCAction Action)
{
Guard(ExManagerWindow::InputAction(ExCAction Action))
	switch(Action.m_Action)
	{
	case SET_RESOLUTION_800_600_16:
		SetResolution(800,600);
		SetBits(16);
		SetFullScreen(true);
		Apply();
		break;
	
	case SET_RESOLUTION_800_600_24:
		SetResolution(800,600);
		SetBits(24);
		SetFullScreen(true);
		Apply();
		break;

	case SET_RESOLUTION_800_600_32:
		SetResolution(800,600);
		SetBits(32);
		SetFullScreen(true);
		Apply();
		break;

	case SET_RESOLUTION_1024_768_16:
		SetResolution(1024,768);
		SetBits(16);
		SetFullScreen(true);
		Apply();
		break;
	
	case SET_RESOLUTION_1024_768_24:
		SetResolution(1024,768);
		SetBits(24);
		SetFullScreen(true);
		Apply();
		break;
	
	case SET_RESOLUTION_1024_768_32:
		SetResolution(1024,768);
		SetBits(32);
		SetFullScreen(true);
		Apply();
		break;
	
	case SET_RESOLUTION_1600_1200_16:
		SetResolution(1600,1200);
		SetBits(16);
		SetFullScreen(true);
		Apply();
		break;
	
	case SET_RESOLUTION_1600_1200_24:
		SetResolution(1600,1200);
		SetBits(24);
		SetFullScreen(true);
		Apply();
		break;
	
	case SET_RESOLUTION_1600_1200_32:
		SetResolution(1600,1200);
		SetBits(32);
		SetFullScreen(true);
		Apply();
		break;
	
	case SHOW_FPS_STAT:
		SetFpsState(true);
		break;

	case HIDE_FPS_STAT:
		SetFpsState(false);
		break;

	case ENABLE_GRIDE:
		SetGrilleState(true);
		break;

	case DISABLE_GRIDE:
		SetGrilleState(false);
		break;

	case SWITCH_GRIDE:
		if(GetGrilleState())
		{
			InputAction(DISABLE_GRIDE);	
		}else
		{
			InputAction(ENABLE_GRIDE);
		}
		break;
	case SET_POLYGONMODE_POINTS:
		glPolygonMode(GL_FRONT_AND_BACK,GL_POINT);
		break;

	case SET_POLYGONMODE_LINES:
		glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
		break;

	case SET_POLYGONMODE_FILL:
		glPolygonMode(GL_FRONT_AND_BACK,GL_FILL);
		break;

	default: return NOTHING;
	}
	return	NOTHING;
UnGuard
}