#if !defined(TILE_H)
#define TILE_H

#include "Vertex.h"
#include "Plane.h"
#include "Triangle.h"
#include "LightMap.h"

class Triangle;

/****************************************************************************/
/** \class Tile
    \brief Die Tile ist eine Spezialisierung eines Polygons. Es beschreibt ein 
           Rechteck im 3D-Raum. Der Tile ist eine Textur zugewiesen, die genau 
           in diese vier Eckpunkte eingespannt ist. Sie wird im Texuremapper 
           auf die Canvas projiziert.
*****************************************************************************/
class Tile : public Plane  
{
public:
   enum TILE_TYP {FLOOR=1, WALL=2, PORTAL=3}; 
   long   m_sid;  // SurfaceID
   int    m_typ;
   int    m_textureID;
   char   m_name[100]; // TODO: war vorher String
   int    m_zoneTHIS;
   int    m_zoneOTHER;
   int    m_scrollFlag;
   int    m_animationID;
  
   float m_d;      // Distanz vom Ursprung zur Plane
  
  // Die Tile besteht aus 4 Punkten plus dem letzten Pseudopunkt
  // der identsch ist mit dem ersten Punkt:
   int m_numVertices; // Wird in der cpp-Datei auf 4 gesetzt
  
  Vertex* m_vertexOrg;  
  Vertex* m_vertex;     
  
  // Die Tile besteht aus 4 Punkten. Sie kann potentiell 
  // 4 Planes des Frustums schneiden, d.h es koennen max. 
  // 8 Liniensegmente entstehen (plus dem letzten pseudo punkt
  private:
  void initialize();

  int m_numClipVertices;

  public:
   int m_maxFC; // Anzahl der tatsaechlich ermittelten Vertices:  
   Vertex* m_vFC; 

   float* m_x;       // x' projiziert auf Plane
   float* m_y;       // y' projiziert auf Plane
   float* m_u;       // u  Texelkoordinate in x-Richtung
   float* m_v;       // v  Texelkoordinate in y-Richtung
  
  // Und weil die gecklippte Tile aus mehr als 4 Eckpunkten bestehen
  // kann, muss dieses 'richtige' Polygon trianguliert, d.h. in Dreiecke
  // aufgeteilt werden.
  private:
  int m_numTriangles;

  public:
   int m_maxTri; // Anzahl der tatsaechlich ermittelten Triangles:  
   Triangle* m_tri; 
  
   float   m_ambientLight;
   float   m_directionalLight;
   LightMap* m_lightMap;

   // Bounding Rectangles:
   float m_minXDist2D;
   float m_maxXDist2D;
   float m_minYDist2D;
   float m_maxYDist2D;

   float m_minXDist3D;
   float m_maxXDist3D;
   float m_minYDist3D;
   float m_maxYDist3D;
   float m_minZDist3D;
   float m_maxZDist3D;
  
   bool m_hasLightMapGrid; 
   BYTE m_lightMapGrid[33][33];

public:
   void setLightMap(LightMap* lightMap);
   Tile();
   Tile(Vec& v0, Vec& v1, Vec& v2, Vec& v3, int typ, int zoneTHIS, int zoneOTHER, char* name);
	virtual ~Tile();
 
   void set(Tile& t);
   int  getZoneTHIS();
   int  getZoneOTHER();
   void resetClipList();
   void resetVertices();
   void reverseVertices();
   void clip(Plane& p);
 
   int  getTyp();
   bool intersect(Vec& v0, Vec& v1);
   void transform(Matrix& mat);
   void project(float d);
   void calcUV();
   void calcTexelVertices();

   void triangulate();
   void calcDistances(float d);

   int  getScrollFlag(void);
   void setScrollFlag(int scrollFlag);

   void dump();
   void save(DataOutputStream& dataOut);
   void load(DataInputStream& dataIn);
};
#endif // !defined(TILE_H)
