/*********************************************************************//**
*	Game controlle.
*	Trida ovlada pomoci udalosti hru. Zpracovava udalosti
*			klavesnice a mysi a analyzuje a provadi herni prikazy.
*			Provadi vypocet pohybu hrace a je pocatkem v detekci
*			a reakci na kolize
*
*	author: Michal Jirous
*	date: 17.7.2008
*	file: ctrl_gamecontroller.cpp
**********************************************************************/

#include "ctrl_gamecontrol.h"
#include "sys_console.h"
#include "ctrl_binding.h"
#include "ctrl_keydatabase.h"
#include "ctrl_gamevars.h"
#include "ctrl_commands.h"
#include <fstream>
#include "game.h"
#include "sys_config.h"
#include "parsing.h"
#include "sys_controller.h"
#include "ctrl_var_definition.h"
#include "mathematic.h"
#include "HUD.h"

#include "ctrl_weapon_manager.h"
#include "level_collision.h"

using namespace systemConsole;
using namespace gameControl;
using namespace std;

CGameControl gameControl::game_control;

CGameControl::CGameControl()
{
	memset( movDirection, 0, NUM_DIRECTIONS );
	m_bUse = false;
}

void CGameControl::init()
{
	/*key_database::		loadDatabase( "config/key_database.list" );
	binding::			loadDatabase( "config/watched_commands.list" );
	gamevarsLibrary::	init();
	commandsLibrary::	init();*/
	console << "Initializing game control module...";
	binding::setBindsFromWatchedCommandMap();
	loadConfig( "config.conf" );
	
	//game vars musi byt uz inicializovany
	m_pVarMaxSpeed = gamevarsLibrary::getVariable(vardef::MAXSPEED_NAME );
	m_pVarAcceleration = gamevarsLibrary::getVariable(vardef::ACCELERATION_NAME );
	m_pVarGravity = gamevarsLibrary::getVariable(vardef::GRAVITY_NAME );
	m_pVarFriction = gamevarsLibrary::getVariable(vardef::FRICTION_NAME );

	console << "done" << endline;
	/*
	*	Lexan initialization
	*/

	//m_Lexan.setSkippingEmptyCharacters( true );
	//m_Lexan.setDefaultEmptyCharactersSettings(true);
	//
	//for(int i = 32; i < 128; i++)
	//{
	//	//if( isalpha(i) || isdigit(i) )
	//		m_Lexan.setAllowedCharacter(i);
	//}
	//m_Lexan.createDefaultNode();
	//m_Lexan.setDefaultReturnValue( IDENTIFICATOR );

	//
	//for( int i = 0; i < LEXAN_FIELD_SIZE; i++ )
	//{
	//	if(i >31 && i < 128)
	//	m_Lexan.setCycleForChar( i );	//vsechny znaky (tj. klavesy mohou byt ident
	//}



	//m_Lexan.setEndCharacters("; ");
	//m_Lexan.init();
	//m_Lexan.addSubject(";", CTRL_SEMICOLON, true );
	//
	//for( int i = 0; i < LEXAN_FIELD_SIZE; i++ )
	//{
	//	if(isSpace(i))
	//	{
	//		m_Lexan.addSubject( string()+(char)i , LEXAN_SPACE, true);
	//		m_Lexan.setEndCharacters(string()+(char)i);
	//	}
	//}

	/*
	*	End lexan initialization
	*/


}

void CGameControl::decodeCommand( string sCmd )
{
	istringstream strIn, globalIn;
	strIn.str( sCmd );
	
	while( !strIn.eof() )
	{
		bool endOfCommand = false;
		string sCommand = parsing::readCommand( strIn, endOfCommand );
		
		if( !sCommand.empty() )
		{
			command *tmpCommand = commandsLibrary::getCommand( sCommand );
			if( tmpCommand )
			{
				commandsLibrary::doCommand( tmpCommand, &strIn );
				continue;
			}

			variable *tmpVar = gamevarsLibrary::getVariable( sCommand );
			if( tmpVar )
			{
				if( !endOfCommand )
					setVariable( sCommand, tmpVar, strIn );
				else
					gamevarsLibrary::printVar( sCommand, tmpVar );
				continue;
			}

			console << ERROR_UNKNOWN_COMMAND << "'" << sCommand << "'." << endline;
		}
	}
	//string s = sCommand;

	//if(s.empty()) return;

	//m_Lexan.loadString( s );	//nacteme string do lexanu
	//variable *tmpVar = NULL;
	//command *tmpCommand = NULL;
	//string sRemain = "";
	//int iValue = 0;
	//while( (iValue = m_Lexan()) != END_OF_FILE )	//cteme az do konce stringu
	//{
	//	if( iValue == CTRL_SEMICOLON ) continue;

	//	if( iValue != IDENTIFICATOR ) return;
	//	string sCommand = m_Lexan.getSymbolName();		//vraci cele jedno slovo, tj. ve vetsine pripadu prikaz
	//
	//	tmpCommand = commandsLibrary::getCommand( sCommand );	//nacteme prikaz z databaze
	//	tmpVar = gamevarsLibrary::getVariable( sCommand );		//nacteme promenou z databaze
	//	m_Lexan.skipEmptyCharacters();				//preskocime prazdne znaky
	//	string sParameter = "";
	//	if(sCommand == "alias" && tmpCommand != NULL)
	//	{
	//		sParameter = m_Lexan.getRemainingString();
	//		commandsLibrary::doCommand( tmpCommand, &sParameter);
	//		return;
	//	}
	//	else
	//	{
	//		sParameter = m_Lexan.readTillCharacter(';');
	//		if( sParameter.empty() && sCommand == "bind"  )
	//		{
	//			m_Lexan();
	//			sParameter = m_Lexan.getSymbolName();
	//			sParameter += m_Lexan.readTillCharacter(';');
	//		}
	//	}
	//	
	//	
	//	sRemain = m_Lexan.getRemainingString();
	//	if( tmpCommand != NULL )
	//	{
	//		commandsLibrary::doCommand( tmpCommand, &sParameter);
	//	}
	//	else if( tmpVar != NULL)
	//	{
	//		if(sParameter.empty())
	//			console << "\"" << sCommand << "\" = \"" << tmpVar->print() << "\"" << endline;
	//		else
	//			if(setVariable( sCommand, sParameter ))
	//				console << "->" << sCommand << " set to " << tmpVar->print() << endline;
	//		//pGame->m_fSkyDistance = sqrt( 3.0f * pow(gamevarsLibrary::getfData("maxdistance"),2.0f) );  
	//	}
	//	else
	//	{
	//		console <<  "-> Unknown command" << endline;
	//		return;
	//	}
	//	
	//	m_Lexan.loadString( sRemain );
	//}
}





bool CGameControl::setVariable( std::string name, variable *tmpVar, std::istringstream &in )
{
	if( !tmpVar )
		return false;
	
	string parameter = parsing::readPosibleQuotedCommandParm( in );
	if( parameter.empty() )
	{
		console << ERROR_SYNTAX_ERROR_VAR << endline;
		return false;
	}
	switch( tmpVar->type )
	{
		case VAR_STRING:
			if( gamevarsLibrary::setVariable( tmpVar, parameter) )
			{	
				console << "'" << name << "' set to '" << parameter << "'." << endline;
				return true;
			}
			else
				return false;
		case VAR_INT:
			{
				int value = stringToInt( parameter );
				if( gamevarsLibrary::setVariable( tmpVar, value) )
				{	
					console << "'" << name << "' set to '" << value << "'." << endline;
					return true;
				}
				else
					return false;
			}
		case VAR_FLOAT:
			{
				float value = stringToFloat( parameter );
				if( gamevarsLibrary::setVariable( tmpVar, value ) )
				{	
					console << "'" << name << "' set to '" << value << "'." << endline;
					return true;
				}
				else
					return false;

				
			}
	}

	console << ERROR_UNKNOWN_VAR_TYPE << endline;
	return false;
}

void CGameControl::friction(Vector &vecMove )
{
	float fFriction;
	if( m_pVarFriction )
		fFriction = gamevarsLibrary::getfData( m_pVarFriction );
	else
		fFriction = vardef::FRICTION_DEFAULT;
		vecMove = vecMove - vecMove * fFriction;
}


Uint32 g_uiTimeG;
bool g_hh = false;

Vector CGameControl::calculateMovement( int direction, float speed )
{
	Vector moveVector;
	
	//funkce vytvori vektor na zaklade zadane velikosti a rotace podle osy Z
	if( (direction == MOVE_FORWARD || direction == MOVE_BACKWARD) &&
		(game.m_pPlayer->m_iWaterLevel > LEGS_IN_WATER || game.m_pPlayer->m_bIsOnLadder) )
	{
		moveVector.createFrom2Angles(game.m_pPlayer->angles.x, game.m_pPlayer->angles.z, speed);
	}
	else	
		moveVector.createFromAngle(game.m_pPlayer->angles.z, speed);

	float X = moveVector[0];
	float Y = moveVector[1];
	float Z = moveVector[2];

	switch(direction)
	{
		case MOVE_FORWARD:
			return Vector(X,Y,Z);
		case MOVE_BACKWARD:
			return Vector(-X,-Y,-Z);
		case MOVE_LEFT:
			return Vector(-Y,X,0);
		case MOVE_RIGHT:
			return Vector(Y,-X,0);
		case MOVE_UP:
			return Vector( 0, 0, speed );
		case MOVE_DOWN:
			return Vector( 0, 0, -speed);
	}
	return Vector(X,Y,Z);
}

void CGameControl::run()
{
	movementControl();
	futureCommandsProceed();
}

#include "game_loadmap.h"
#include "level_loader.h"


void CGameControl::movementControl()
{
	if( !game.m_pPlayer )
		return;

		float fMaxSpeed, fAcceleration;
		
		
		if( m_pVarMaxSpeed )
			fMaxSpeed = gamevarsLibrary::getfData( m_pVarMaxSpeed );
		else
			fMaxSpeed = vardef::MAXSPEED_DEFAULT;

		if( m_pVarAcceleration )
			fAcceleration = gamevarsLibrary::getfData( m_pVarAcceleration );
		else
			fAcceleration = vardef::ACCELERATION_DEFAULT;


		//Velocity lastPlayerVelocity;
		//if( !game.m_pPlayer->m_bIsOnLadder )	//pouze kdyz neni na zebriku (pohyb po zebriku je specialni)
		//	vecLastPlayerMove = game.m_pPlayer->getMoveVector();


		//kdyz je skrceny, tak je akcelerace polovicni, stejne tak plavani
		if( game.m_pPlayer->m_iDuckOffset > 0 )
			fAcceleration *= 0.5f;	//polovicni
		if( game.m_pPlayer->m_iWaterLevel > LEGS_IN_WATER )
			fAcceleration *= 0.5f;

		Force vecNewMove;
		//game.m_pPlayer->m_bLadderJumpOut = false;
		if( !game.m_pPlayer->isDeath() )
		{
			for(int i =0; i < NUM_DIRECTIONS;i++)
			{
				if(i == MOVE_UP )
				{
					if( movDirection[MOVE_UP] )
					{
						if( game.m_pPlayer->m_iWaterLevel < BODY_IN_WATER && !game.m_pPlayer->m_bIsOnLadder )
						{
							/*if( m_iJump == 2 )
							{
								m_iJump = 0;
								vecNewMove += game.m_pPlayer->jump( fAcceleration, movDirection[MOVE_UP],0.0f);
							}*/
						}
						else if( (game.m_pPlayer->m_iWaterLevel & HEAD_IN_WATER ) )
							vecNewMove += calculateMovement( i, fAcceleration);
						else if( game.m_pPlayer->m_bIsOnLadder )	//skok ze zebriku je pohyb ve smeru normaly zebriku
						{
							game.m_pPlayer->m_bIsOnLadder = false;
							vecNewMove += Vector( game.m_pPlayer->m_vecLastLadderNormal, fAcceleration);
						}
					}
					continue;
				}
				else if( i == MOVE_DOWN )
				{
					if( movDirection[i] && game.m_pPlayer->m_iWaterLevel & BODY_IN_WATER && !game.m_pPlayer->m_bIsOnLadder )
						vecNewMove += calculateMovement( i, fAcceleration);
					continue;
				}

				if(movDirection[i] && ( !game.m_pPlayer->isInAir() || game.m_pPlayer->m_iWaterLevel & BODY_IN_WATER || game.m_pPlayer->m_bIsOnLadder ))
					vecNewMove += calculateMovement( i, fAcceleration);
				//minimalni velikost vektoru je 1
				else if(movDirection[i] && game.m_pPlayer->isInAir() /*&& Vector(vecLastPlayerMove[0],vecLastPlayerMove[1],0.0f).absolute() < 1*/ )
				{
					Vector movement = calculateMovement( i, 1.0f );	//pohyb ve vzduchu	
					if( movement.scalarMultiply( game.m_pPlayer->m_Model.m_vecMovement ) > 90.0f )
						vecNewMove += Vector( movement, fAcceleration );	//pohyb ve vzduchu	
					else
						vecNewMove += movement;
				}
			}
		}

		//vztlakova sila (tu by si mela voda sama spocitat)
		/*Vector vecWaterForce;
		if( game.m_pPlayer->m_iWaterLevel & BODY_IN_WATER )
			vecWaterForce = -vecGravity * 0.8f;*/
		
		

		Vector horizontal( vecNewMove );
		
		if( game.m_pPlayer->m_iWaterLevel < BODY_IN_WATER )
			horizontal.z = 0;

		if( !game.m_pPlayer->isInAir() && horizontal.absolute() > fMaxSpeed )
			vecNewMove = Vector( horizontal, fMaxSpeed);

		game.m_pPlayer->addForce( vecNewMove * game.m_pPlayer->getWeight() );



		/*if( !game.m_pPlayer->m_bIsOnLadder )
			vecNewMove = vecNewMove + vecWaterForce;*/

		//m_vecCurrent = vecNewMove;
		/*if( !game.m_pPlayer->isInAir() &&  game.m_pPlayer->m_iWaterLevel < BODY_IN_WATER )
			friction( m_vecCurrent );*/
		/*if( game.m_pPlayer->m_iWaterLevel > LEGS_IN_WATER )
			m_vecCurrent = m_vecCurrent * 0.7f;*/

		/*if( game.m_pPlayer->m_bJumpoutOfWater )
		{
			m_vecCurrent += Vector( 0,0,-fAcceleration );
		}*/


		/*Vector playerOrigin = game.m_pPlayer->origin;
	

		game.m_vecAnim = playerOrigin;
		game.m_pPlayer->setMoveVector( -m_vecCurrent );
		bool ddd = false;*/



		/*Uint32 startTime = SDL_GetTicks();

		for( int i = 0; i < game.iteration; i++ )
		{
			collisionSystem.processMoving();
			if( i == game.iteration-1 )
				break;
			Vector or = -game.m_pPlayer->origin;
				Vector v = (or - playerOrigin);
				game.m_pPlayer->teleport( v  );
				or = -game.m_pPlayer->origin;
				game.m_pPlayer->setMoveVector( -m_vecCurrent );
				
		}

		cout << game.iteration << " " << SDL_GetTicks() - startTime << endl;*/
		
		
		
		
		/*Vector storeOrigin = game.m_pPlayer->origin;
		Vector storeForce = game.m_pPlayer->getForce();
		Vector storeVelocity =  game.m_pPlayer->getVelocity();
		float storeFriction = game.m_pPlayer->getFriction();*/
		
		//collision.collisionDetection( sceneObjectLibrary::getSceneObjectRoot(),game.m_pPlayer);

		/*Vector plane( 0, -320, 200 ), plane2( 0, -8, 104 );
		Vector normal = plane - plane2;
		normal = normal * Vector( 1,0,0);
		Plane p( normal, plane );
		
		float f = p.m_vecNormal.multiply( game.m_pPlayer->m_Model.m_Points[BRN] ) + p.m_fDistance;
		if( g_hh && f < 0.0f && game.m_pPlayer->m_Model.m_Points[BRN].y > -320 )
		{
        	bool a = false;
			bool b = true;
			while( b )
			{
				Vector or = game.m_pPlayer->origin;
				Vector v = (storeOrigin - or);
				game.m_pPlayer->teleport( v  );
	
				game.m_pPlayer->setForce( storeForce);
				game.m_pPlayer->setVelocity( storeVelocity);
				game.m_pPlayer->setFriction( storeFriction);



				collisionSystem.processMoving();
			}
		
	
		}*/

		


		



}


void CGameControl::futureCommandsProceed()
{
	for( list<string>::iterator iter = m_FutureCommands.begin(); iter != m_FutureCommands.end(); iter++ )
		decodeCommand( (*iter) );
	m_FutureCommands.clear();
}



bool CGameControl::loadConfig( string filename )
{
	console << "Loading user game configuration." << endline;
	ifstream fin;
	string file = "config/" + filename;
	
	fin.open(file.c_str());
	if(!fin.is_open())
	{
		console << "File '" << filename << "' doesn't exist" << endline;
		return false;
	}
	char c = 0;
	string command;
	while( (c=fin.get()) != -1)
	{
		if( c == '\n' )
		{
			decodeCommand(command);
			command.clear();
		}
		command += c;
	}
	decodeCommand(command);
	fin.close();
	console << "user configuration file '" << file << "' has been loaded." << endline;
	return true;
}

bool CGameControl::saveConfig(string filename)	//save all variables and binds
{
	return false;
}

void bindCommand(string key, string commands);

//void checkCommand(string command, string parameter);


void CGameControl::setDirectionValue( int direction, int* value )
{
	if( isInRange( direction, 0, NUM_DIRECTIONS ) )
		movDirection[direction] = *value;

}


void CGameControl::bindCommandAnalyse( istringstream &in )
{
	string key = parsing::readPosibleQuotedData( in );
	
	if(key.length() == 1)
	{
		if(parsing::isAlpha(key.at(0)))
		{
			key[0] = parsing::toUpper(key.at(0));
		}
	}

	int iKey = key_database::getKey( key );
	if( iKey == -1 )
	{
		systemConsole::console << ERROR_BIND_KEY << "'" << key << "'." << systemConsole::endline;
		return;
	}


	string sCommand = parsing::readPosibleQuotedCommandParm( in );		//zbytek by mel byt prikaz :)
	if(	sCommand.empty() )
	{
		console << ERROR_MISSING_PARAMETER << endline;
		return;
	}
	binding::setBind( iKey, sCommand );
}

void CGameControl::aliasCommandAnalyse( istringstream &in )
{
	string sAlias = parsing::readPosibleQuotedData( in );
	string sBack = "";
	bool bBack = false;
	if( sAlias.at(0) == '-')
	{
		sBack = "+" + sAlias.substr(1);
		command *tmpCom = commandsLibrary::getCommand( sBack );
		if(tmpCom == NULL) 
		{
			console << "-> Missing '+' alias" << endline;
			return;
		}
		else
			bBack = true;
	}


	string sCommands = parsing::readPosibleQuotedCommandParm( in );		//zbytek by mel byt prikaz :)
	if(	sCommands.empty() )
	{
		console << "-> Missing commands or syntax error" << endline;
		return;
	}
	if(bBack)
		commandsLibrary::addAliasCom( sAlias ,&doAlias, sBack, false, sCommands );
	else
		commandsLibrary::addAliasCom( sAlias ,&doAlias, "", false, sCommands );

}

bool CGameControl::processKey( int key, int pressed )
{
	string sCommand = binding::getBind( key );
	if( sCommand.empty() )
		return false;
	
	if( pressed == RELEASED )
	{
		command *pCommand = commandsLibrary::getCommand( sCommand );
		if(pCommand != NULL)
		{
			if(pCommand->reverse != NULL)
				sCommand = pCommand->reverse->sCommand;
			else
				return false;
		}
	}
	
	decodeCommand( sCommand );
	return true;
}

void CGameControl::resetMouse()
{
	int middle_w = systemconf::getSystemInfo().m_iResolutionWidth >> 1;
		int middle_h = systemconf::getSystemInfo().m_iResolutionHeight >> 1;
		SDL_WarpMouse( middle_w, middle_h );
}


bool CGameControl::processMouseMove( int x, int y )
{
	systemconf::SystemInfo *Info = &systemconf::getSystemInfo();
	int middle_w = Info->m_iResolutionWidth >> 1, middle_h = Info->m_iResolutionHeight >> 1;

	if( middle_w != x || middle_h != y )
	{
		if( game.m_bLevelFinnished )
		{
			SDL_WarpMouse( middle_w, middle_h ); 
			return true;
		}


		CPlayer *pPlayer = game.m_pPlayer;
		float sensitivity = gamevarsLibrary::getfData("sensitivity");
		int reverse = gamevarsLibrary::getiData("reverse_mouse_h");
		if( pPlayer == NULL )
			return false;

		if( pPlayer->isDeath() ) 
			return false;

		//pretypovat na float
		//horizontalni pohyb (rotace podle osy Z)
		pPlayer->angles.z -= ( (float)( x - middle_w ) / 20.0f ) * sensitivity;
		weapon_manager::weaponManager.addHDeflection( (float)(x - middle_w) );
		if( pPlayer->angles.z > 180)
			pPlayer->angles.z -= 360;
		else if( pPlayer->angles.z < -180 )
			pPlayer->angles.z += 360;
		
		weapon_manager::weaponManager.addVDeflection( (float)(y - middle_h) );
		//vertikalni pohyb (rotace podle osy X)
		if( reverse )
			pPlayer->angles.x -= ( (float)( y - middle_h ) / 20.0f ) * sensitivity;
		else
			pPlayer->angles.x += ( (float)( y - middle_h ) / 20.0f ) * sensitivity;
		if( pPlayer->angles.x < -90 )
			pPlayer->angles.x = -90;
		else if( pPlayer->angles.x > 90 )
			pPlayer->angles.x = 90;

		SDL_WarpMouse( middle_w, middle_h ); 
		return true;
	}

	return false;
}



bool CGameControl::eventController( SDL_Event &event )
{
	switch( event.type )
	{
		case SDL_KEYDOWN:
			if( event.key.keysym.sym == key_database::DEFAULT_CONSOLE_KEY )
			{
				systemController::setRunningLevel( systemController::CONSOLE );
				return true;
			}
			/*else if( event.key.keysym.sym == key_database::DEFAULT_MAINMENU_KEY )
			{
				systemController::setRunningLevel( systemController::MAINMENU );
				return true;
			}*/
			else
				return processKey( event.key.keysym.sym, PRESSED );
		case SDL_KEYUP:
			return processKey( event.key.keysym.sym, RELEASED);
		case SDL_MOUSEBUTTONDOWN:
			return processKey( event.button.button + binding::MAX_KEYBOARD_KEYS, PRESSED );
		case SDL_MOUSEBUTTONUP:
			return processKey( event.button.button + binding::MAX_KEYBOARD_KEYS, RELEASED );
		case SDL_MOUSEMOTION:
			return processMouseMove( event.motion.x, event.motion.y );
	}

	return false;
}





/************************************************************************************
*************************************************************************************
************			COMMAND FUNCTION DEFINITIONS                   **************
*************************************************************************************
************************************************************************************/

void gameControl::goForward(void* parameter)
{
	if( parameter )
		game_control.setDirectionValue( MOVE_FORWARD, (int*)parameter );
}
	
void gameControl::goBackward(void* parameter)
{
	if( parameter )
		game_control.setDirectionValue( MOVE_BACKWARD, (int*)parameter );
}

void gameControl::goLeft(void* parameter)
{
	if( parameter )
		game_control.setDirectionValue( MOVE_LEFT, (int*)parameter );
}

void gameControl::goRight(void* parameter)
{
	if( parameter )
		game_control.setDirectionValue( MOVE_RIGHT, (int*)parameter );
}

void gameControl::goJump(void* parameter)
{
	if( parameter )
	{
		if( *(int*)parameter == 1)	//stisknuti
			game.m_pPlayer->jump();

		game_control.setDirectionValue( MOVE_UP, (int*)parameter );
	}
}

void gameControl::goDuck(void* parameter)
{
	if( parameter )
	{
		game_control.setDirectionValue( MOVE_DOWN, (int*)parameter );
		game.m_pPlayer->duck( *(int*)parameter );
	}
}

void gameControl::loadconfig(void* parameter)
{
	istringstream *strIn = (istringstream*)parameter;
	string filename = parsing::readPosibleQuotedCommandParm( *strIn );
	game_control.loadConfig( filename.c_str() );
}

void gameControl::quit(void* parameter)
{	
	systemconf::requestQuit();
}

void gameControl::loadMap(void* parameter)
{
	istringstream *strIn = (istringstream*)parameter;
	string filename = parsing::readPosibleQuotedCommandParm( *strIn );
	game.loadMap( filename, systemController::GAME );
}

void gameControl::restart(void*)
{
	game.restartGame();
}

void gameControl::backintime(void*parameter)
{
	game.startSkill( SK_TIME_TRAVEL );
}
void gameControl::timestop(void*parameter)
{
	if( *(int*)parameter == 1)
		game.startSkill( SK_STOP_TIME );
	else
		game.stopSkill( SK_STOP_TIME );
}
void gameControl::forward_teleport(void*parameter)
{
	if( *(int*)parameter == 1)
		game.startSkill( SK_FORWARD_TELEPORT );
	else
		game.stopSkill( SK_FORWARD_TELEPORT );
}

void gameControl::use( void* parameter )
{
	g_hh = true;

	if( parameter )
	{
		int value = *(int*)parameter;
		if(value == 0 && !game_control.m_bUse)
		{
			game_control.m_bUse = true;
			game.iteration ++;
			game.m_pPlayer->setEnergy( game.m_pPlayer->getEnergy() - 1 );
			collisionSystem.processPlayerUsage();
		}
		else if(value == 1)
		{
			game_control.m_bUse = false;
		}
	}
}




void gameControl::bind(void* parameter)
{
	if( parameter != NULL )
		game_control.bindCommandAnalyse( *(istringstream*)parameter );
}

void gameControl::alias(void* parameter)
{
	if( parameter != NULL )
		game_control.aliasCommandAnalyse( *(istringstream*)parameter );
}

void gameControl::doAlias(void* parameter)
{
	if( parameter )
		game_control.decodeCommand( *(string*)parameter );
}
#include "globaltime.h"
void gameControl::mainMenu(void* parameter)
{
	systemController::setRunningLevel( systemController::MAINMENU );
	global_time::timeStop();/////////
}

void gameControl::resume(void* parameter)
{
	if( systemconf::getSystemInfo().m_bResumeAllowed && systemController::getRunningLevel() != systemController::GAME )
	{
		gameControl::game_control.resetMouse();
		systemController::setRunningLevel( systemController::GAME );
		global_time::timeStart();////////////
	}
}

void gameControl::showConsole(void* parameter)
{
	systemController::setRunningLevel( systemController::CONSOLE );
}

void gameControl::saveconf(void* parameter)
{
	istringstream *strIn = (istringstream*)parameter;

	string filename = parsing::readPosibleQuotedCommandParm( *strIn );

	game_control.saveConfig( filename );
}

void gameControl::hudset(void*)
{
	bool overwrite = true;
	if( systemController::getRunningLevel() == systemController::CONSOLE )
		overwrite = false;
	systemController::setRunningLevel( systemController::HUD_SET, overwrite );
}

void gameControl::hudrefresh(void*)
{
	HUD::hud.refresh();
}
