// game.h: Beispielspieler für Asteroids
// Matthias Fuchs
// Original: Harald Bögeholz / c't
#ifndef gameH
#define gameH

#include "connection.h"
#include "interfaceplayer.h"
#include "objectmanager.h"
#include "gamestatus.h"
#include "debuglogger.h"
#include "console.h"
#include "scheduler.h"

#include <sstream>

// Winkelbytes=========================
vector<int>* assign(int v0, int v1, int v2, int v3, int v4, int v5, int v6, int v7);
void initialize_winkelbyte();

class Game
{
public:
	Game(Connection &con, InterfacePlayer *pl);
	void SetPlayer(InterfacePlayer *pl);
 	void Run(unsigned int numofframes = ~0);
	GameStatus::State GetState(void) const;
protected:
	void InterpretScreen(const FramePacket &packet, GameStatus& game);
	bool InterpretHighscoreScreen(const FramePacket &packet, int pos, char* curchar);
	void WriteHighscore(const char *str);
private:
	Connection &connection;
	InterfacePlayer *player;
	unsigned int lastframepoints;
	unsigned int lastnbigasteroid;
	unsigned int lastnmidasteroid;
	unsigned int lastnsmallasteroid;
	int lastsaucersize;
	GameStatus::State oldgamestate;
	bool shipwaspresent;
	bool inhyperspace;
	bool shiplost;
	unsigned int lastlifes;
	
};

class StatTimers {
public:
	unsigned __int32 maxTime;
	float avgTime;
	unsigned __int32 totalTime;
	
	StatTimers() {
		Clear();
	}
	
	void Clear() {
		maxTime = 0;
		avgTime = 0;
		totalTime = 0;
	}
	
	const char* ToString() {
		std::stringstream msg;
		msg << "avg: " << avgTime << " - max: " << maxTime << " - total: " << totalTime;
		return msg.str().c_str();
	}
	
};

// quick'n'dirty
class Stats {
public:
	int m_numShots;
	int m_numHits;
	int m_numSmallSaucers;
	int m_numLargeSaucers;
	int m_numSmallAsteroids;
	int m_numMediumAsteroids;
	int m_numLargeAsteroids;
	int m_numFrames;
	int m_lastScore;
	int m_score;
	int m_scoreDiff;
	
	int m_numLocks;
	float m_avgLockDist;
	float m_maxLockDist;
	float m_avgLockAngle;
	float m_maxLockAngle;	

	float m_numFramesPerSec;	
	float m_pointsPerSec;
	
	int m_numScoreAvgUpdates;
	
	StatTimers frameTimes;
	StatTimers maketurnTimes;
	
	unsigned int m_startTimer;	
	unsigned int m_scoreTimer;
	
	Stats();	
	void Reset();	
	void Start();	
	void IncShots();	
	void IncSmallAsteroids();	
	void IncMediumAsteroids();	
	void IncLargeAsteroids();	
	void IncSmallSaucers();	
	void IncLargeSaucers();	
	void UpdateLocks(float dist, float angle);
	void UpdateMakeTurnPerformance(unsigned __int32 ticks);
	void UpdateStats(unsigned __int32 ticks, int score);	
	void PrintStats();	
	
	void PrintLine(int y, const char* label, const char* a, const char* b);
	void PrintLine(int y, const char* label, const char* a, const char* b, const char* c);
		
	void off();
	void on();
	
	static unsigned __int32 StatsGetTimer();
	
	Stats& operator<<(const char* str);
	Stats& operator<<(const float f);
	Stats& operator<<(const int i);
	
private:
	std::stringstream msgBuffer;
	int m_lastMsgLength;
	int m_lines;
	bool m_active;	
};

#endif
