/*********************************************************************//**
*	\brief 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.h
**********************************************************************/

#ifndef __CONTROL_H_
#define __CONTROL_H_

#include "algebraic.h"
#include "ctrl_gamevars.h"
#include "SDL/SDL.h"
#include "lexan.h"
#include <string>
#include <sstream>

namespace gameControl
{
	//command functions
	void goForward(void*);
	void goBackward(void*);
	/*void flashlight(void*);
	void flashlightColor(void*);*/
	void goLeft(void*);
	void goRight(void*);
	void goJump(void*);
	void goDuck(void*);
	//void commandMenu(void*);
	void loadconfig(void*);
	void quit(void*);
	void restart(void*);
	void backintime(void*);
	void timestop(void*);
	void forward_teleport(void*);
	//void changeCamera(void*);
	void loadMap(void*);
	void use(void*);
	void bind(void*);
	void alias(void*);

	void doAlias(void*);
	void mainMenu(void*);
	void resume(void*);
	void showConsole(void*);

	void saveconf(void*);
	void hudset(void*);
	void hudrefresh(void*);
	const int NUM_DIRECTIONS = 6;

	enum move_directions
	{
		MOVE_FORWARD = 0,
		MOVE_BACKWARD,
		MOVE_LEFT,
		MOVE_RIGHT,
		MOVE_UP,
		MOVE_DOWN
	};

	static const char* DEFAULT_CONFIG_FILE = "config.conf";
	static const char* ERROR_UNKNOWN_COMMAND = "Error: Unknown command -> ";
	static const char* ERROR_BIND_KEY = "Error: Unknown key for binding: ";
	static const char* ERROR_MISSING_PARAMETER = "Error: Missing parameter.";
	static const char* ERROR_SYNTAX_ERROR_VAR =	"Error: Syntax error while setting variable";
	static const char* ERROR_UNKNOWN_VAR_TYPE =	"Error: Wrong variable type.";

	const int PRESSED = 1;
	const int RELEASED = 0;

	const float GRAVITY_MODIFICATOR = 1000.0f;

	class CGameControl
	{
		variable *m_pVarMaxSpeed;
		variable *m_pVarAcceleration;
		variable *m_pVarGravity;
		variable *m_pVarFriction;

		bool setVariable( std::string name, variable *tmpVar, std::istringstream &in );//
		
		void bindCommand(string key, string commands);//

		//void checkCommand(string command, string parameter);
		void friction(Vector &v);//
		Vector calculateMovement(int direction, float speed);//
		
		Vector m_vecCurrent;
		Vector m_vecResult;


		bool processKey( int key, int pressed );
		bool processMouseMove( int x, int y );

		std::list<std::string> m_FutureCommands;

		

	public:
		void movementControl();
		void futureCommandsProceed();
		CGameControl();	//
		void init();	//
		
		int movDirection[NUM_DIRECTIONS];
		bool m_bUse;
		int m_iJump;
		
		void bindCommandAnalyse( istringstream &in );
		void aliasCommandAnalyse( istringstream &in );

		void run(void);								/////// <-important
		bool eventController( SDL_Event &event );	/////// <-important
	
		void decodeCommand(string s);	//

		bool loadConfig( string filename );//
		bool saveConfig( string filename );//
		void resetMouse();
		void setDirectionValue( int direction, int* value );

		void requestCommand( std::string command )	{ m_FutureCommands.push_back( command ); }
	};

	extern CGameControl game_control;
};


#endif
