#if !defined(LIGHTMANAGER_H)
#define LIGHTMANAGER_H

#include "LightZone.h"
#include "LightMap.h"
#include "Tile.h"

/****************************************************************************/
/** \class Light
    \brief Containerklasse fuer alle Lichtquellen

 Es gibt folgende Arten von Lichtquellen:
 - Ambient Light, Umgebungslicht: 
   Die Licht wird von der Umgebung reflektiert und erhellt den Raum ohne das 
   die Quelle ersichtlich ist (z.B. Tageslicht bei bedecktem Himmel).
   Die Intensitaet bleibt ueber die Entfernung gleich.
   
 - Directional Light (direktes Licht):
   Die Quelle ist unendlich weit entfernt, so dass die Lichtstrahlen quasi 
   parallel zueinander in eine Richtung verlaufen. Dadurch wird zur 
   Beschreibung nur ein einfacher Richtungsvektor benoetigt.  
   Die Intensitaet bleibt ueber die Entfernung gleich.
   Beispiel: Direkte Sonnenstrahlen.
     
 - Point Light (Punktlicht):
   Die Quelle hat eine Position. Die Lichtstahlen werden kugelfoermig von der
   Lichtquelle abgestrahlt.
   Die Intensitaet nimmt quadratisch mit der Entfernung ab
   Beispiel: Eine offene Kerzenflamme
     
 - Spot Light (Spot Light):
   Die Lichtstrahlen werden von einem Ausgangspunkt in eine Richtung ausgesendet
   Die Intensitaet nimmt quadratisch mit der Entfernung ab   
   Beispiel: Taschenlampe
   
   Hier werden derzeit nur Ambient, Directional und Pointlight unterstuetzt
   Diese Komponenten koennen fuer jede (Portal-)Zone einzeln eingestellt werden.
   D.h. Die Klasse Light ist ein Container fuer eine Liste von 'LightZone'
   Fuer jede (Portal-)Zone gibt es genau ein LightZone, welches die 
   zugehoerigen Lights (Ambient, Directional, Points) beinhaltet.
*****************************************************************************/
class LightManager  
{
public:
  static LightManager* getInstance();

protected:
   LightManager();

private:
   static LightManager* _instance;

public:
   virtual ~LightManager();

private:
   bool m_AmbientON;      // Flag fuer ambientes Licht An/Aus
   bool m_DirectionalON;  // Flag fuer directional Licht An/Aus
   bool m_LightMapON;     // Flag fuer LightMap An/Aus

public:
   std::vector<LightZone*> lightZoneList;
   std::vector<LightMap*> lightMaps;

   float m_gamma; // private oder public??
   int m_gammaR[256];
   int m_gammaG[256];
   int m_gammaB[256];

public:
   void addEnvironment(int zone, float ambient, float directionalMax, float pointMax);
   void setDirectionalLight(int zone, float dirX, float dirY, float dirZ);
   void addPointLight(int zone, float x, float y, float z);
 
   void calcPointLight(Tile& tile, LightZone& le);

   void calcLightMapGrid(Tile& tile);
   void calcLightMap(Tile& tile);

   void toggleAmbientLight();
   void toggleDirectionalLight();
   void toggleLightMap();
   void stepGamma(bool up);
   bool isAmbientON();
   bool isDirectionalON();
   bool isLightMapON();
   void calcGamma(float gamma);
   void load(DataInputStream& dataIn);
   void save(DataOutputStream dataOut);
   void dump();

private:
   void calcLightMapGrid(Tile& tile, LightZone& le);

   LightZone* getLightZone(int zone);
   float calcDirectional(Tile& tile, LightZone& le);
   float calcLPs(std::vector<LightPoint*> &lightPoints, float x, float y, float z, float pointMax);
   BYTE biInterpolate(int q12, int q22, int q11, int q21, int px, int py);
};

#endif // !defined(LIGHTMANAGER_H)
