#ifndef LEVEL_H
#define LEVEL_H

#include <map>
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
#include <hash_map>

#include "SDL.h"
#include "SDL_opengl.h"
#include "glfuncs.h"
#include "Sprite.h"
#include "Tile.h"
#include "Person.h"
#include "SDL_mixer.h"
#include "Background.h"

class Player;

class Level
{
public:
	Level();
	~Level();

	void reset();

	bool update();
	void draw();
	void levelLoad(std::string filenamebase);
	void registerObject( Object* o );
	void registerTile( Tile* t, int h, int w );
	std::vector< Object* >& getObjects(){ return _objects; };
	Tile* getTile( int w, int h ){ return _tiles[_width * h + w]; };

	Tile* getTileFromPixels( int w, int h ) { return _tiles[_width * h / tileHeight + w / tileWidth]; }

	void deleteObject( Object* o );
	void scheduleDelete( Object* o );
	int getHeight(){ return _height; };
	int getWidth(){ return _width; };

	static const int tileHeight = 32;
	static const int tileWidth = 32;

	static Level *instance();

	Object *getObject(std::string id);
	Mix_Music* getMusic(){ return _music; };
	void setMusic( Mix_Music* music );
	Mix_Chunk* getSound( std::string filename );
	void loadSound( std::string filename );
	Player *getPlayer() {return _player;};

	//perhaps move the cut scene stuff somewhere else
	void setCutScene(bool cutScene);
	void setCutSceneText(std::string text) {_cutSceneText = text;}

	void addScore(int score) {_score += score;}
	void addKill(){_killed ++;};

	int getScore() {return _score;}
	void setScore(int score) {_score = score;}

	void drawHUD();

	void save();
	void restore();

	bool getWon(){return _won;};
	void setWon(bool won){_won = won;};

	
private:

	// loads up static maps
	void loadObjects();

	void readTextures(std::string extension);
	void readObjects(std::string dir);
	void levelTextureLoad(std::string filenamebase);
	void levelObjectLoad(std::string filenamebase);
	
	void levelSpecsLoad(std::string filenamebase);
	void addObject( Object* o, std::vector< Object* >& vec );
	Uint32 Level::loadPixelFile(std::string filename);

	bool _won;

	bool _timed;
	int _levelTimer;

	int _killed;
	int _totBad;

	int _height;
	int _width;

	std::string _filenamebase;

	//perhaps move the cut scene stuff somewhere else
	bool _cutScene;
	std::string _cutSceneText;

	static Level *_instance;

	static Uint32 WALKBEHIND;
	static Uint32 WALKINTO;
	static Uint32 WALKINFRONT;
	static std::map<Uint32,Sprite *> TEXTURES;
	static std::map<Uint32,std::string> OBJECTS;

	int _score;

	Player * _player;

	std::vector< Object* > _objects;
	std::vector< Tile* > _tiles;
	std::vector< Object* > _drawnObjects;
	std::vector< Object* > _deleteQueue;
	std::queue< Object* > _addQueue;
	std::map<std::string,Object*> _ids;
	Mix_Music* _music;
	std::map< std::string, Mix_Chunk* > _sounds;
	Background* _background;

	std::vector< Object* > _save;

	static bool _objectsLoaded;
};

#endif