#include "freeglut.h"
#include <tchar.h>
#include <stdio.h>
#include <vector>
#include "Vector.h"
using namespace std;

#ifndef M_PI
#define M_PI 3.14159265f
#endif

#define GLM_NONE     (0)            /* render with only vertices */
#define GLM_FLAT     (1 << 0)       /* render with facet normals */
#define GLM_SMOOTH   (1 << 1)       /* render with vertex normals */
#define GLM_TEXTURE  (1 << 2)       /* render with texture coords */
#define GLM_COLOR    (1 << 3)       /* render with colors */
#define GLM_MATERIAL (1 << 4)       /* render with materials */


typedef struct{/* GLMtriangle: Structure that defines a triangle in a model. */
    
  vector<int> CDtrianglept1;
  vector<int> CDtrianglept2;     


} TrianglePositions;




typedef struct _GLMmaterial /* GLMmaterial: Structure that defines a material in a model.  */
{
  char* name;                   /* name of material */
  GLfloat diffuse[4];           /* diffuse component */
  GLfloat ambient[4];           /* ambient component */
  GLfloat specular[4];          /* specular component */
  GLfloat emmissive[4];         /* emmissive component */
  GLfloat shininess;            /* specular exponent */
} GLMmaterial;


typedef struct _GLMtriangle {/* GLMtriangle: Structure that defines a triangle in a model. */
  GLuint vindices[3];           /* array of triangle vertex indices */
  GLuint nindices[3];           /* array of triangle normal indices */
  GLuint tindices[3];           /* array of triangle texcoord indices*/
  GLuint findex;                /* index of triangle facet normal */
} GLMtriangle;


typedef struct _GLMgroup {/* GLMgroup: Structure that defines a group in a model.*/
  char*             name;           /* name of this group */
  GLuint            numtriangles;   /* number of triangles in this group */
  GLuint*           triangles;      /* array of triangle indices */
  GLuint            material;       /* index to material for group */
  struct _GLMgroup* next;           /* pointer to next group in model */
} GLMgroup;


typedef struct _GLMmodel {/* GLMmodel: Structure that defines a model. */

  GLfloat weight,velocity, appliedForce, directionV, x,y,z, Maxx,Minx,Maxy,Miny,Maxz,Minz;




  char*    pathname;            /* path to this model */
  char*    mtllibname;          /* name of the material library */

  GLuint   numvertices;         /* number of vertices in model */
  GLfloat* vertices;            /* array of vertices  */

  GLuint   numnormals;          /* number of normals in model */
  GLfloat* normals;             /* array of normals */

  GLuint   numtexcoords;        /* number of texcoords in model */
  GLfloat* texcoords;           /* array of texture coordinates */

  GLuint   numfacetnorms;       /* number of facetnorms in model */
  GLfloat* facetnorms;          /* array of facetnorms */

  GLuint       numtriangles;    /* number of triangles in model */
  GLMtriangle* triangles;       /* array of triangles */

  vector<GLMtriangle*> CDtrianglez;

  vector<int> CDtrianglept0;
  vector<int> CDtrianglept1;
  vector<int> CDtrianglept2;
  bool LoadTriangles;

  GLuint       nummaterials;    /* number of materials in model */
  GLMmaterial* materials;       /* array of materials */

  GLuint       numgroups;       /* number of groups in model */
  GLMgroup*    groups;          /* linked list of groups */

  GLfloat position[3];          /* position of the model */

} GLMmodel;






GLfloat glmUnitize(GLMmodel* model);/* glmUnitize: "unitize" a model */
GLvoid glmDimensions(GLMmodel* model, GLfloat* dimensions);/* glmDimensions: Calculates the dimensions (width, height, depth) of  * a model.*/
GLvoid glmScale(GLMmodel* model, GLfloat scale);/* glmScale: Scales a model by a given amount.  */
GLvoid glmSineWave(GLMmodel* model, GLfloat phase,GLfloat t);
GLvoid glmReverseWinding(GLMmodel* model);/* glmReverseWinding: Reverse the polygon winding for all polygons in the model.  Default winding is counter-clockwise.  */
GLvoid glmFacetNormals(GLMmodel* model);/* glmFacetNormals: Generates face texture normals for a model by taking the cross product of the two vectors of each triangle*/
GLvoid glmVertexNormals(GLMmodel* model, GLfloat angle);/* glmVertexNormals: Generates vertex normals for a model. */
GLvoid glmLinearTexture(GLMmodel* model);/* glmLinearTexture: Generates texture coordinates according to a linear projection of the texture map.  */
GLvoid glmSpheremapTexture(GLMmodel* model);/* glmSpheremapTexture: Generates texture coordinates according to a  * spherical projection of the texture map.  */
GLvoid glmDelete(GLMmodel* model);/* glmDelete: Deletes a GLMmodel structure. */
GLMmodel*  glmReadOBJ(char* filename);/* glmWriteOBJ: Writes a model description in Wavefront .OBJ format to* a file. */


GLvoid LoadVectorpos(GLMmodel* model, vector<int> temp0,vector<int> temp1,vector<int> temp2);
GLvoid glmDraw(GLMmodel* model, GLuint mode);/*glmDraw: draws the model*/
GLvoid glmDrawSpecial(GLMmodel* model, GLuint mode,bool DrawVertexPoints,bool DrawShadedObject, bool DrawWireMesh);

GLvoid glmMorph(GLMmodel* model,GLuint mode, GLMmodel* model2, float t);/*glmMorph: Takes two models and LERPs between them to create a morphing effect*/

GLvoid glmKeyFrameMorph(GLMmodel* KeyFrame[10],int FrameSize,float t);/*glmMorph: Takes two models and LERPs between them to create a morphing effect*/


GLuint glmList(GLMmodel* model, GLuint mode);/* glmList: Generates and returns a display list for the model using the mode specified. */
GLvoid glmApplyPhysics(GLMmodel* model);// to be created


GLvoid glmDrawGroundPlaneObj(bool& TriHit, GLMmodel* model, GLuint mode,Vector Origin, Vector Direction,Vector FDerection,float& Ground,bool& FoundFloor, Vector Translation);

GLvoid glmDrawMagnetRoofPlaneObj(bool& TriHit, GLMmodel* model, GLuint mode,Vector Origin, Vector Direction,Vector FDerection,float& Roof,bool& FoundRoof, Vector Translation);
GLvoid glmDrawRoofPlaneObj      (bool& TriHit, GLMmodel* model, GLuint mode,Vector Origin, Vector Direction,Vector FDerection,float& Roof,bool& Jumping, Vector Translation);
GLvoid glmDrawWallPlaneObj(GLMmodel* model, GLuint mode,Vector Origin, Vector WallDect,Vector FDerection, bool& Accelerating,float& Acc,Vector Translation);