#ifndef _MODEL_H
#define _MODEL_H

#include "ModelBase.h"
#include "AsteroidsEnums.h"

namespace asteroids {

class Model : public Engine::ModelBase {
	public:
		virtual ~Model() {};
		virtual void Process();
		virtual void SetGameState (const unsigned int &state);
		float GetWorldWidth ();
		float GetWorldHeight ();

		/* Event handler */
		bool OnGameOver();
		/** \brief Resets values from a previous game */
		void OnNewGame ();
		void OnShipExplode ();

		/* Level loading etc. */
		int DoLoadLevel (const char* filename);
		int DoSaveLevel (const char* filename);
		void ResetLevel ();

		void ReloadLevel();
		void ProceedToNextLevel ();
		int GetPlayerLives () { return mPlayerLives; };
		unsigned int GetPoints () { return mPoints; };
		std::string GetPlayerName() { return mPlayerName; };
		void SetPlayerName(const std::string &name) {
			Engine::LogDebug("new player name: %s", name.c_str());
			mPlayerName = name;
		};

		std::string GetLevelName() { return mLevelName; };
		void SetLevelName(const std::string &name) {
			Engine::LogMessage("new level name: %s", name.c_str());
			mLevelName = name;
		}

		/* Highscore */
		struct HighscoreEntry {
			HighscoreEntry(): name ("unknown"), points (0) {	};
			HighscoreEntry (const char *e_name, const unsigned int e_points):
				name (e_name), points (e_points) { };

			std::string name;
			unsigned int points;
		};

		void LoadHighscoreList ();
		void SaveHighscoreList ();
		unsigned int AddHighscoreEntry(const std::string &name, const unsigned int points);
		bool HighscoreCmp (HighscoreEntry a, HighscoreEntry b);
		std::list<HighscoreEntry> mHighscoreList;
		unsigned int mNewestHighscoreEntryIndex;

	protected:
		/** \brief Initializes the system */
		virtual int OnInit (int argc, char* argv[]);
		virtual void OnDestroy() {
			Engine::ModelBase::OnDestroy();
			mAsteroids.clear();
			mLevelList.clear();
			SaveHighscoreList();
		};
		virtual void OnRegisterCommands ();

		virtual void OnCreateEntity (const int type, const unsigned int id);
		virtual void OnKillEntity (const Engine::EntityBase *entity); 

	private:
		unsigned int InitLevelList ();

		/** \brief Keeps a list of all asteroids */
		std::vector<unsigned int> mAsteroids;

		int mPlayerLives;
		unsigned int mPoints;
		unsigned int mCurrentLevelIndex;

		std::string mPlayerName;
		std::vector<std::string> mLevelList;
		std::string mLevelName;

		virtual bool OnReceiveEvent (const Engine::EventBasePtr &event);

	friend class View;
	friend class Controller;
};

}

#endif // _MODEL_H
