#if !defined(SURFACECACHE_H)
#define SURFACECACHE_H

#include <stdlib.h>
#include "Texture.h"
#include "LightMap.h"

#include "Surface.h"

#define MAX_SURFACES 1000 
#define MAX_DROP 1000

/****************************************************************************/
/** \class SurfaceCache
    \brief Der SurfaceCache ist ein Container fuer alle Surfaces, die in einem 
           Frame gerendert werden müssen. Die Anzahl der Surfaces im Cache ist 
           auf MAX_SURFACES begrenzt. Damit der Cache nicht ueberlaeuft, muessen 
           ungenutzte Eintraege entfernt werden. Die Strategie sieht wie folgt 
           aus: Jedes Surfaceobjekt besitzt einen Zaehler der in der Methode 
           refresh() inkrementiert wird. Erreicht der Zaehler eine bestimmte 
           Grenze (MAX_DROP), wird das Objekt aus dem Cache entfernt.
           Typ. wird refresh() bei jedem Frame einmal aufgerufen.
           Jeder Aufruf der Methode getSurface() setzt den Zaehler auf 0 zurueck.
           Wird ein Surfaceobjekt immer wieder fuer ein Frame verwendet, kann der
           Zaehler nicht die Grenze erreichen und wird damit auch nicht aus dem 
           Cache entfernt.
           Diese Strategie minmiert dynamisch den Speicherbedarf. Nachteil:
           Bewegt sich die Kamera uber eine laengere Zeit nicht, werden alle 
           nichtgenutzten Surfaces aus dem Cache entfernt. Wird nun die Kamera
           position veraendert (z.B. durch Drehen) muessen alle neuen Surfaces
           in den Cache geladen werden. Das macht sich durch einen Einbruch in der
           Framerate bemerkbar. 
           Besser: Den Fuellstand des Caches immer voll ausnutzen. Erst wenn
           mehr 100% erreicht wurde, nicht genutzte Surfaces entfernen. 
*****************************************************************************/
class SurfaceCache
{
public:
   static SurfaceCache* getInstance();

protected:
	SurfaceCache();

private:
 static SurfaceCache* _instance;

private:
  int m_usedCounter;
  long m_sid;
  Surface* m_surfaces[MAX_SURFACES];
  
  BYTE m_rgbIntensity[256][256];

public:
   ~SurfaceCache(void);

   void refresh();
   long addSurface(Texture& texture);
   long addSurface(Texture& texture, LightMap* lightMap, BYTE intensity);

   long updateSurface(long sid, Texture& texture);
   long updateSurface(long sid, Texture& texture, LightMap* lightMap, BYTE intensity);
   
   Surface* getSurface(long sid);
   int getCount(void);
};
#endif // !defined(SURFACECACHE_H)

