// cStaticTriangleMesh.h
// 2/27/04
// Forrest Briggs
// The cStaticTriangleMesh holds an array of triangles
// that we do not intend to ever move. It arrays 
// of triangles, faces, vertices and eges and implements
// a draw method that class draw for each of the triangles.
// 3/5/04
// Forrest Briggs
// Changed delete to delete[] in destructor, removing a memory leak.
// 3/12/04
// Completely remove the face class from everything. Working on an
// easy to use add triangle function.
// 3/14/04 added octree
// 3/15/05 optimzed code, added draw lists, added file loading of native ascii text file format : [x y z] * 3 r g b
// 3 / 22 / 04 Forrest Briggs
// Added octree, texture mapping, interface that works with cMS3DLoader to import milkshape 3d texturemapped models



#ifndef cstatictrianglemesh_h
#define cstatictrianglemesh_h

#include "ForwardDeclarations.h"
#include "OGLPlatformspecific.h"
#include "cTriangle.h"
#include "cEdge.h"
#include "cVertex.h"
#include "cVector.h"
#include "cVectorComparator.h"
#include "cEdgeComparator.h"
#include "cColor.h"
#include "cTextureImage.h"
#include "cTextureCoord.h"

#include "cOctree.h"
#include "cBoundingBox.h"

#include <vector>
#include <map>

#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
#include <cctype>

using namespace std;

class cStaticTriangleMesh
{
public:
    cStaticTriangleMesh(string filename, int level);
    ~cStaticTriangleMesh();
    
    void draw();
    void preprocessMesh();
    
    // build a list of possible triangles, edges and vertices that could collide
    // with the ball along its path from start to end
    void buildCollisionLists(cVector start, cVector end, float radius, 
        vector<cTriangle*>& tlist, vector<cVertex*>& vlist, vector<cEdge*>& elist);
    
    // methods used by cMS3DFileLoader to build a model
    
    // add a texture to the textures vector and return its index
    // well be getting the filename from the ms3d loader, so its c style
    int addTexture(char* filename, bool envMap); 
    
    // add a vertex and return its index
    int addVertex(float x, float y, float z, float u, float v);
    
    // add a triangle and return its index. 
    // vertices and texture are specifed by index
    int addTriangle(int v0, int v1, int v2, int materialIndex);
    
    int numTriangles_, numVertices_, numEdges_;
    vector<cTriangle*> 	triangles_;
    vector<cVertex*> 	vertices_;
    vector<cEdge*> 	edges_;
    
    cOctree octree_;

    
    
private:
    
    // add a vertex, but first check if there is already a vertex in exactly the
    // same place. if there is, just return a pointer to the already existing vertex
    // otherwise allocate a new vertex and return a pointer to it
    cVertex* addVertexIfDoesntExist(cVector& pos);
    
    // if the edge doesnt already exists, add it and return a pointer
    // if it does exist, return a pointer to the already existing edge
    cEdge* addEdgeIfDoesntExist(cEdge& edge);
    
    void generateDisplayList();

    vector<cTextureImage*> textures_;
    
    int displayListID_;
    
    // we use this to be able to add triangles only by specifying 
    // the coordinates of their vertices and not duplicate vertices
    // with identical positions.
    map<cVector, cVertex*, cVectorComparator> vertexMap;
    map<cEdge, cEdge*, cEdgeComparator> edgeMap;
};

#endif // end define cstatictrianglemesh_h