/*********************************************************************//**
*	\brief Game.
*	Tento modul je vstupnim bodem enginu, spousti vykreslovani,
*	aktualizaci entit, provadi skilly hrace, startuje vypocet pohybu,
*	nahravani levelu.
*
*	\author Michal Jirous
*	\date 07.04.2009
*	\file game.h
**********************************************************************/

//TODO - vycisteni nepouzivanych veci!!!

#ifndef __GAME_H__
#define __GAME_H__

#include "game_frustum.h"
//#include "baseobject.h"
//#include "baseentity.h"
#include "ctrl_gamevars.h"
#include "ctrl_commands.h"

#include "textureslib.h"

#include "player.h"

//#include "collision.h"
#include "lexan.h"
#include "colors.h"
#include "graphics.h"
#include <time.h>
#include <stack>
#include <fstream>



#include "HUD_fade.h"
#include "clothsimul.h"
#include <sstream>
#include "fonts.h"

using namespace std;

#include <map>
	

//#include "al/al.h"
//#include "al/alc.h"
//#include "al/alut.h"


#include "interpolation.h"
#include <queue>



const int	SK_NO_SKILL			= -1;
const int	SK_TIME_TRAVEL		= 0;
const int	SK_STOP_TIME		= 1;
const int	SK_FORWARD_TELEPORT = 2;
const int	SK_COUNT			= 3;

const Uint32 TIME_TRAVEL_ANIMATION_TIME = 1000;
const Uint32 TIME_TRAVEL_PERIOD_UPDATE = 1000;

const float SKILLS_ENERGY_CONSUMING[ SK_COUNT ] = { 15.0f, 1.50f, 1.00f };

const float SK_FRWRD_TEL_SPEED_STEP = 0.2f;
const float SK_FRWRD_TEL_MAX_SPEED = DEFAULT_ENERGY / SKILLS_ENERGY_CONSUMING[ SK_FORWARD_TELEPORT ] * SK_FRWRD_TEL_SPEED_STEP;

#include "soundslib.h"


const Uint32 GAME_LOGO_LEVEL_IN_DURATION = 4000;
const Uint32 GAME_LOGO_LEVEL_IN_FADE_OUT_DURATION = 4000;


class CGame
{
public:		
	CGame();
	~CGame();
	Vector movement;
	TexturePool m_GlobalTexturesPool;
	int iteration;
	void destroy();
	//ALboolean loadEnvironmentMusic( string file );


	void setLevelParameters( parameters_t &parametersMap );
	int m_iCurrentCrosshair;
	int m_iCurrentActiveSkill;
	bool consumeEnergy( int skill, float multiplier = 1.0f );
	void startSkill( int sk );
	void stopSkill( int sk );
	
	void proceedBackTime();
	void proceedStopTime( bool stop = false);
	void proceedForwardTeleport( bool stop = false);

	float m_fTargetFOV;
	

	void proceedSkills();
	void allowEntity( CBasePhysics* );
	std::list<CBasePhysics*> m_AllowedEntities;
	void updateEntities( float seconds );
	void drawscene(   FrameTime &frame  );
	//void addObject(CBaseObject *o);
	
	void loadMap( string file, int nextRunningLevel );
	void deleteObjects(void);

	void quit();
	
	void init();
	
	/* funkce ovladani */
	/*void mouseOver(int x, int y);
	void mouseButton(int button, int state, int x, int y);
	void keyboardSpecDown(int key);
	void keyboardDown(int key);
	void keyboardSpecUp(int key);
	void keyboardUp(int key);*/
	Vector m_vecAnim;

	void run(void);

	int get_height(void);
	//void resetMouse(void);
	void resizeScene(int width, int heigth);
	void setRunningLevel(int);
	int getRunningLevel();
	
	void onPointingFinnished( RayTraceData &rayData );

	//CLoadMap pLoadMap;

	void checkInterAction(void);

	CPlayer *m_pPlayer;
	//bObject *baseObject, *back;

	unsigned long int m_uiTime;
	void startLevel();
	void addToStartedTime(clock_t time)
	{	
		startedTime += time;
		timeleft += time;
	}
	int m_iNumTargets;

	bool gameIsRunning()	{ return m_bGameStarted || m_bStartSequence; }

	

	CPlayer *setTaker()	{ return m_pPlayer;	}
	void incrementNumTargets()	{m_iNumTargets++;	}

	void attackExecution( CBaseEntity *object );
//	decal *dec;
	//void insertDecal(CInfoDecal *decal)	{ decalQueue.push(decal);	}
	void showCursor()	{ m_bShowCursor = true; }
	void hideCursor()	{ m_bShowCursor = false; }

	void showCrosshair()	{ m_bShowCrosshair = true; }
	void hideCrosshair()	{ m_bShowCrosshair = false; }
	bool m_bStartSequence;
	//void addBlendingObject( CBaseObject *obj )	{ blendList.push_back( obj );	}
	float m_fSkyDistance;
	float timeDelayModifier;

	//void insertFan( CFan *f )	{ fanList.push_back(f); }
	bool m_bUpdateFrustum;
	float m_fDefaultFov, m_fWFov;
	void setBasicDrawSettings();
	void setBasicDrawMatrixes();
	void setCurrentTranslateMatrix();
	void gameLoop();
	Uint32 getGameTime() { return m_uiGameTime; }
	Uint32 getPlayerTime()	{ return m_uiPlayerTime; }
	void restartGame();
	float m_uiTeleportSpeed;
private:
	void renderEmptyScreen();
	void renderLogo();
	bool m_bLevelFadeIn;
	void setLevelEnvironment();
	bool m_bDisplayLogo;
	TextureElement *m_pLogoTexture;
	GLuint m_LogoDList;

	SoundElement m_SoundNoEnergy;
	SoundElement m_SoundPlayerDead;
	SoundElement m_SoundBetterScore;
	SoundElement m_SoundScoreWorse;
	bool m_bLevelStarted;
public:
	Uint32 m_uiPlayerTimeDelayTotal;
	Uint32 m_uiPlayerTimeDelay;
	Uint32 m_uiPlayerTime;

	
	Uint32 m_uiTimeNormalDelayStarter;
	Uint32 m_uiTimeNormal;
	Uint32 m_uiTimeNormalDelay;
	Uint32 m_uiTimeNormalDelayTotal;

	Uint32 m_uiBackTimeDelay;
	
		
	Uint32 m_uiTimeServed;
	Uint32 m_uiGameTime;

	Uint32 m_uiTotalGameTargets;
	Uint32 m_uiTargetsDoneCount;
	void exitLevel();
	bool m_bLevelFinnished;
	std::string m_sNextLevel;
	std::string m_sCurrentLevel;
	std::string m_sLevelReportString;
	void processNextLevel();
	void onPlayerDeath();
private:
	Uint32 m_uiBackTimeMovesCount;
	Uint32 m_iuFrameStart;
	size_t m_uiTotalTimeUpdatesDone;
	size_t m_uiTotalFramesDone;
	size_t m_uiSupposedFramesCount;
	size_t m_uiTotalTexturesAnimationsCount;

	void drawWeapon();
	float  m_fMaxDistance;
	
	bool m_bIsAudioEnabled;
	
	bool m_bShowCursor, m_bShowCrosshair;
	
	bool m_bInit;
	time_t initTime;

	void setDecals();

	
	
	string dataString;

public:		
	Vector vecDir;
	Interpolation m_ViewInterpolation;
	Frustum m_Frustum;
private:
	int m_iRunningLevel;
	void calculateVecDir(void);
	void loadTextures(void);
	bool m_bGameStarted,  m_bGameOver, m_bEnviromentAnimation;
	clock_t timeleft, startedTime;

	int m_iNumFps;
	int m_iNumRuns;
	

	
	

	double w,h;

	float cam_rot;
	

	
};

extern CGame game;
#endif
