#if !defined(ENGINE_H)
#define ENGINE_H

#include "Timer.h"
#include "AnimationManager.h"
#include "PartikelManager.h"
#include "Map.h"

#include "Text.h"
#include "SurfaceCache.h"

#include "Renderer.h"

/****************************************************************************/
/** \class Engine
    \brief Die Hauptklasse der 3D Engine
           Dieser Klasse beinhaltet ALLE Methoden, die fuer die Nutzung
           der Engine benoetigt werden.
*****************************************************************************/
class Engine  
{
public:
   static Engine* getInstance();

protected:
	Engine();

private:
 static Engine* _instance;

public:
	virtual ~Engine();

private:
   bool m_drawInfo;

   bool m_usePortalFrustum;
   bool m_rendering;

   Timer  m_timer;
   double m_frameRate;
   int    m_partikelCount;
  
   Map*      m_map;
   Camera*   m_camera;
   EngineIO* m_engineIO;
   LightManager*    m_lightManager;
   Frustum*  m_frustum;
   SkyBox*   m_skyBox; 

   AnimationManager* m_animationManager;
   PartikelManager*  m_partikelManager;
   SurfaceCache*     m_surfaceCache;
   Renderer*         m_renderer;
   
   int m_height;
   int m_width;

   Vec m_camdir;
   Vec m_campos;

   Matrix m_matTranslate;
   Matrix m_matRotate;
   Matrix m_matAnimate;

   bool m_isRendererInitialized;
  
   std::vector<Tile*>     m_tileList;
   std::vector<Partikel*> m_partikelList;
   
   Text* m_text;
   std::vector<Text*>     m_textList;
   
public:
   void initRenderer(int width, int height, BYTE* data);
   void renderFrame();

   void saveAsMapfile(char* fname);
   bool loadMapfile(char* fname);
   void calcAnimation();

   void calcLightMapGrid();
   void calcLightMap();

   bool inputKey(bool pressed, int key);
 
   double getFrameRate(void);
   int    getTilesPerFrame(void);
   int    getPartikelsPerFrame(void);

private:
   void animate (void);
   void culling (int zone, Frustum& frust);
   void paintZone();
   void paint2D(int zone, Frustum& frust);
   void paintSkyBox();
   void sortBack2Front();
   void solveZConflicts (void);
};
#endif // !defined(ENGINE_H)
