// OBJModel.h: interface for the COBJModel class.
//
//////////////////////////////////////////////////////////////////////

#ifndef __OBJMODEL_H__
#define __OBJMODEL_H__

#if _MSC_VER > 1000
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif // _MSC_VER > 1000

#include <GL/gl.h>
#include <GL/glu.h>
//#include "glext.h"
#include <string.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <fstream>
#include <corona.h>

#ifndef TRANSPARENT //something used by Windows
#define TRANSPARENT 1
#endif

#ifndef MAX_PATH //something else used by Windows
#define MAX_PATH 260
#endif

#ifdef VJ_API_OPENGL
#define USING_VRJUGGLER
#include <vrj/Draw/OGL/GlContextData.h>
#endif

#define TEX_NONE		0x0001 // 1
#define TEX_DEFAULT		0x0002 // 2
#define TEX_S3TC		0x0004 // 4
#define TEX_PALETTED	0x0008 // 8
#define TEX_LOWRES		0x0010 // 16

// Holds info on a Material
// sizeof(tagOBJMaterial) = 80 bytes
typedef struct tagOBJMaterial{
	char Name[32];
	GLuint map_Kd;		// Diffuse Map (normal Texture)
	GLuint map_Ks;		// Specular Map
	GLuint map_Ka;		// Ambient Map
	GLuint map_Bump;	// Bump Map
	GLuint map_d;		// Opacity Map
	float Ambient[4];	// Ambient Color
	float Diffuse[4];	// Diffuse Color
	float Specular[4];	// Specular Color
	char  illum;		// Lighting Model (0 = None, 1 = Amb & Diff, 2 = Full Lighting) 
	short Ns;			// Phong Specular Component (0 - 1000)
	short Ni;			// Refraction Index (1+ )
	char  padding;
} OBJMaterial;

class COBJModel
{
public:
	void NukeData();

	void LockPosition();
	unsigned char TranzColor[3]; // Colour which is to be seen as Transparent
	void SetOBJPos(float xPos,float yPos,float zPos);
	void SetOBJHeading(float Pitch,float Yaw,float Roll);
	unsigned char LOCKED; // Boolean 1/0 Position Pre-Transformed?
	float Pos[3];
	float Heading[3];
	int texsUsed;
	int ModelNumber;
	// Filenames
	char* ObjectFilename;
	char* OBJDirName;
	char* MaterialFilename;
	//Texture 
	int UseTextures;
	int TexturesLoaded;
	int Transparent;
	// BoundingBox {xmin,xmax,ymin,ymax,zmin,zmax}
	float Box[6];
	
	// Vertices
	int numVertices;
	float *xVertex;
	float *yVertex;
	float *zVertex;
	// Faces
	int numFaces;
	int (*Faces)[9]; // vx/vt/vn vx/vt/vn vx/vt/vn
	// Methods

	//New - Tyler Streeter
	int GetNumVertices();
	void GetVertexArrays(float*& xCoords, float*& yCoords, float*& zCoords); //shallow copy only
	int GetNumFaces();
	void GetFaceArray(int (*&faceArray)[9]);

	void SetVertexArrays();
	int VTX;
	GLfloat *VertexArray;
	GLfloat *NormalArray;
	GLfloat *TexCoordArray;

	int ReadMTL(int Flags=0x0002);
	int ReadMTL2(int Flags=0x0002);
	void DrawModel();
	void BuildList();
	COBJModel();
	void LoadCOBJModel(char *dirname,char *filename);
	void LoadCOBJModel2(std::string dirname,std::string filename);
	virtual ~COBJModel();

//TEMP
float Facing[3];
//END_TEMP
	
	// Texture Coords
	int numTextureCoords;
	float *uCoord, *vCoord;
	// Normals
	int numNormals;
	float *iNormal, *jNormal, *kNormal;
protected:
	void DrawModel2(); 

	//Tyler Streeter's stuff...
	GLuint CreateTexture(std::string filename);
	//void SetFogCoord(float depth, float height);
	
	// Context-Specific Data -> handle differently in VRJuggler
#ifdef USING_VRJUGGLER //using Juggler's special context-specific data types
	vrj::GlContextData<GLuint> OBJList; //this model's display list ID
	vrj::GlContextData<GLuint*> texture; //this model's texture IDs
#else //using normal data types
	GLuint OBJList; //this model's display list ID
	GLuint *texture; //this model's texture IDs
#endif

	int* FaceTexNum;
	unsigned char PALLETEDEXT;		// Boolean 1/0 Pal Ext Available?
	unsigned char S3TCEXT;			// Boolean 1/0 S3TC Ext Available?
	unsigned char LOWRES;			// Boolean 1/0 
	unsigned char LISTUSED;			// Boolean 1/0 Display List Created?
	OBJMaterial *Materials; // List of Material Structs
};

#endif // __OBJMODEL_H__
