/*****************************/
/* Inside The Machine - MKS  */
/*****************************/

//Includes
#ifndef _WORLDMANAGER_H
#define _WORLDMANAGER_H

#include "Engine.h"
#include "Levels.h"
#include <string>
#include <list>
#include <map>
#include "math.h"
#include "WorldState.h"
#include "entities/Entities.h"
//#include "entities/Entity.h"

//Defines
#define POLY_DEPTH_TEST_LESS   (0<<14)
#define POLY_DEPTH_TEST_EQUAL  (1<<14)

#define CAMERA_FOLLOW           0
#define CAMERA_FIXED            1
#define CAMERA_FREE             2

//Structures
struct SPRITE_LISTE		
{
	int e;        //Type de structure, inutile pour le moment
	int x, y;     //Position de l'entité dans le monde
	int type;     //Type d'entité
	int genre;    //Genre d'entités
	int p1, p2;   //Paramètres 1 et 2
	char raw[128];//Paramètres bruts de la liste
};

struct PenteInfo
{
	int v;   		//Identifiant de tile
	u8 hauteur[32];//Hauteur de chaque point
};   

//Types des std::map de pentes
//typedef std::map<int, PenteInfo> PentesMap;

//Classe de gestion du monde
class CEntity;
class CWorldManager
{
	public:
	   CWorldManager();
	   
	   //Fonctions générales
	   void SetLevel(int lev);       //Setting d'un niveau
	   void LoadLevel();             //Chargemment du niveau
	   void MakePentes();            //Crée la table des pentes
	   void FreeLevel();             //Libération du niveau de la mémoire
	   void RestartLevel(bool waypoint); //Redemarrage du niveau
	   void HandleWorld();           //Gestion du monde (entités, etc...)
	   void DrawWorld();             //Affiche le monde
	   void DrawParallaxScrolling(); //Calcule et affiche le scrolling parallaxe
	   void SetCamera();             //Positionne la caméra correctement
	   void ScrollCamera(int xdest, int ydest); //Scrolle la camera vers une nouvelle position
	   
	   //Fonctions des entités
	   void LoadEntities(const SPRITE_LISTE* lst, const unsigned int* len); //Chargemment des entités du niveau
	   void AddEntity(int x, int y, int type, int genre, int p1, int p2, char* raw); //Ajoute une entité au niveau
	   void AddEntHero(int x, int y, int genre, int p1, int p2, char* raw);    //Ajoute une entité heros
	   void AddEntEnnemy(int x, int y, int genre, int p1, int p2, char* raw);  //Ajoute une entité ennemie
	   void AddEntBoss(int x, int y, int genre, int p1, int p2, char* raw);    //Ajoute une entité boss
	   void AddEntEvent(int x, int y, int genre, int p1, int p2, char* raw);   //Ajoute une entité évenement
	   void AddEntLogic(int x, int y, int genre, int p1, int p2, char* raw);   //Ajoute une entité logique
	   void AddEntStatic(int x, int y, int genre, int p1, int p2, char* raw);  //Ajoute une entité statique
	   void DeleteMe(CEntity* ent);                                            //Détruis une entité du niveau
	   
	   //Fonctions de la Physique
	   void SetGravity(u8 x, u8 y);  //Paramètre la gravité dans le niveau
	   
	   //Fonctions d'effets graphiques
	   void DrawLight2();            //Affiche des effets de lumières en mode 2
	   void UpdateAlphaBuffer();     //Mets a jour le buffer alpha
	   void HBLFunc();               //Fonction apellée a chaque interruption hbl
	   void GetFramebuffer();        //Recupère les données du framebuffer
	   
	public:  
	   //Variables des entités
	   std::list<CEntity*> eList;               //Liste d'entités du niveau
	   std::list<CEntity*>::iterator eListItor; //Itérateur sur l'eList
	   bool heroLoaded;                         //Précise si le héros à été chargé ou pas
	   bool toRestart;                          //Dit si le niveau a besoin d'être rechargé
	   bool isFightingBoss;                     //Définit si le héros est ent train de se battre contre le boss
	   bool isBossKilled;                       //Définit si le boss est mort
	   bool isScrollEnd;
	   bool isGameFinished;
	   int screenAngle;
	   bool isFirstLoad;
	   bool lastLevel;
	   
	   //Variables du niveau
	   sLevel* curLevel;                           //Niveau courant
	   int startPosx, startPosy, endPosx, endPosy; //Position de départ, position d'arrivée
	   int wayPointx, wayPointy;
	   bool waypoint;
	   std::map<int, PenteInfo> pentes;            //Infos sur les pentes
		bool isMusic, isSoundEffetcs, isSound;      //Variables du son
	   sMusic music;                               //Musique de fond
	   
	   //Variables du scrolling
	   s32 bgscroll[8];                            //Scrolling de l'arrière plan
	   s32 oldScrollX, oldScrollY, scrollXSens;    //Ancienne valeur scrollx,y de la map
	   int centeredScrollX, centeredScrollY;       //Scrolling centrale
	   int cameraMode, fixPosx;                    //Mode de la caméra
	   int cameraDestx, cameraDesty;
	   
	   //Variables des effets
	   UL_IMAGE * alphaBuffer;                     //Image Alpha au dessus de l'écran (pour effect darkest)
	   u8 x1Fen1, x2Fen1, xCircle1, yCircle1;      //Positions des fenêtres
	   u8 vcount;                                  //Compteur VBL
	   
	   //Variables des profondeurs
	   int depthBackgroundLevel;
	   int depthLevelSprites;
	   int depthSpritesForeground;

	   //Pointeur sur l'entité Héros
	   eHeroCat * hero;
	   CSprite heroIcon, heroBarOver, heroLifeBar, heroEnergyBar;
	   
	   //Ressources Graphiques
	   CRessourceManager * resMan;
};   

#endif
