//////////////////////.celu C Parser///////////////////////////////
//==================================================================
//Copyright (C) 2007  Celambarasan Ramsamy
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation.
//
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//===================================================================




# include <stdio.h>
# include <stdlib.h>

typedef struct point
{
	float x;
	float y;
	float z;
} point;

typedef struct UVSet
{
	float u;
	float v;
} UVSet;

typedef struct
{
	unsigned int tVertexCount;
	unsigned int *tVerticesIndexArray;
	unsigned int *tNormalsIndicesArray;
	unsigned int *tUVIndicesArray;
	float *tVertexColorArray;	//	Contains vertex colors in RGBA format
} PolygonalFace;

typedef struct
{
	char *tName;
	unsigned int tNumberOfVertices;
	unsigned int tNumberOfNormals;
	unsigned int tNumberOfUVSets;
	float *tVerticesArray;
	float *tNormalsArray;
	float **tUVArray;
	int tIsTextureInformationPresent;
	unsigned int tPolygonalFaceCount;
	PolygonalFace *tPolygonalFaceArray;

} Mesh;


void mLoadSceneIntoOpenGL();


//	Global Variables

Mesh* tMeshList;
unsigned int tTotalInstanceCount;




//	Reads tNuberOfElementsToBeRead number of elements from the comma seperated values array pointed by the source pointer and stores them at the destination pointer and returns Char * to the next element after the last that was read

char* ReadItemsAsFloat(unsigned int tNumberOfElementsToBeRead,char *tSourcePointer,float *tDestinationPointerForStoringValues)
{
	unsigned int i;

	//	Assumes the tSource pointer never points to , initially 

	if(*tSourcePointer == ',')
	{
		printf("Error Parsing File in ReadItemAsFloat()");
		exit(0);
	}

	i=0;

	for(i=0;i<tNumberOfElementsToBeRead;i++)
	{
		
		char tTempArray[1000];
		char *tTempPointer;
		unsigned int j;
		tTempPointer=tTempArray;

		//	Reset the contents of the temp array back to zero

		//	C bizzareness!! stack variable tTempArray is not getting cleaned up automatically in each for loop itreation
		j=0;
		for(j=0;j<1000;j++)
		tTempArray[j]=' ';

		
		
		while(*tSourcePointer != ',')
		{
			*tTempPointer=*tSourcePointer;
			tTempPointer++;
			tSourcePointer++;
		}

		//	converts the just read string to float

		*(tDestinationPointerForStoringValues)=atof(tTempArray);


		// Update the pointers to be ready to get the next value

		tDestinationPointerForStoringValues++;

		//	Skip the comma

		tSourcePointer++;
		
	}

	return tSourcePointer;
}


//	Reads tNuberOfElementsToBeRead number of elements from the comma seperated values array pointed by the source pointer and stores them at the destination pointer and returns Char * to the next element after the last that was read

char* ReadItemsAsInt(unsigned int tNumberOfElementsToBeRead,char *tSourcePointer,unsigned int *tDestinationPointerForStoringValues)
{
	unsigned int i;

	//	Assumes the tSource pointer never points to , initially 

	if(*tSourcePointer == ',')
	{
		printf("Error Parsing File in ReadItemAsFloat()");
		exit(0);
	}

	i=0;

	for(i=0;i<tNumberOfElementsToBeRead;i++)
	{
		
		char tTempArray[1000];
		char *tTempPointer;
		unsigned int j;
		tTempPointer=tTempArray;

		//	Reset the contents of the temp array back to zero

		//	C bizzareness!! stack variable tTempArray is not getting cleaned up automatically in each for loop itreation
		j=0;
		for(j=0;j<1000;j++)
		tTempArray[j]=' ';

		
		
		while(*tSourcePointer != ',')
		{
			*tTempPointer=*tSourcePointer;
			tTempPointer++;
			tSourcePointer++;
		}

		//	converts the just read string to float

		*(tDestinationPointerForStoringValues)=atoi(tTempArray);


		// Update the pointers to be ready to get the next value

		tDestinationPointerForStoringValues++;

		//	Skip the comma

		tSourcePointer++;
		
	}

	return tSourcePointer;
}




//	Reads tNuberOfTripleFloatsToBeRead(each n or v element is considered a triple float) number of elements from the comma seperated values array pointed by the source pointer and stores them at the destination pointer and returns Char * to the next element after the last that was read
//	The returned updated character pointer is after the comma

char* ReadItemsAsTripleFloats(unsigned int tNumberOfTripleFloatsToBeRead,char *tSourcePointer,float *tDestinationPointerForStoringValues)
{
	unsigned int i;
	char *tCurrentInputStreamPointer;

	//	Assumes the tSource pointer never points to , initially 

	if(*tSourcePointer == ',')
	{
		printf("Error Parsing File in ReadItemAsFloat()");
		exit(0);
	}

	i=0;
	

	tCurrentInputStreamPointer=tSourcePointer;

	for(i=0;i<tNumberOfTripleFloatsToBeRead;i++)
	{

		//	For each triple float skip the first character and the comma in the input stream

		tSourcePointer=tSourcePointer+2;

		tSourcePointer=ReadItemsAsFloat(3,tSourcePointer,tDestinationPointerForStoringValues);


		//	Increment the destination by three positions to store the next three values

		tDestinationPointerForStoringValues=tDestinationPointerForStoringValues + 3;


	}

	return tSourcePointer;
}


char* ParseUVSet(char *tFileDataPointer,float *tDestinationData,unsigned int tUVCoordinatesCount)
{

	unsigned int i,j;
	char tTempStorageArray[100];
	char *tTempStorageArrayPointer;
	tTempStorageArrayPointer=tTempStorageArray;


	//	Parse each set of U and V coordinate values into consecutive positions in the destination array

	for(i=0;i<tUVCoordinatesCount;i++)
	{

		//	Parse and store the U value

		while(*tFileDataPointer != ',')
		{
			*tTempStorageArrayPointer=*tFileDataPointer;
			tTempStorageArrayPointer++;
			tFileDataPointer++;
		}


		//	Get the parsed instance count value

		tDestinationData[2* i]=atof(tTempStorageArray);


		//	Reset the temp storage array and it's pointer

		for(j=0;j<100;j++)
		tTempStorageArray[j]=' ';

		tTempStorageArrayPointer=tTempStorageArray;


		//	Skip the comma

		tFileDataPointer++;


		//	Parse and store the V value

		
		while(*tFileDataPointer != ',')
		{
			*tTempStorageArrayPointer=*tFileDataPointer;
			tTempStorageArrayPointer++;
			tFileDataPointer++;
		}


		//	Get the parsed instance count value

		tDestinationData[(2 * i)+1]=atof(tTempStorageArray);


		//	Reset the temp storage array and it's pointer

		for(j=0;j<100;j++)
		tTempStorageArray[j]=' ';

		tTempStorageArrayPointer=tTempStorageArray;


		//	Skip the comma

		tFileDataPointer++;
	}

	return tFileDataPointer;
}


char* ParsePolygonalFace(char* tFileDataPointer,PolygonalFace* tPolygonalFaceArray,int tUVSetCount)
{

	char tTempString_UVi[]={'u','v','i'};
	char tTempString_Ni[]={'n','i'};
	char tTempString_Vi[]={'v','i'};
	char tTempString_Vc[]={'v','c'};
	char *tTempStorageArrayPointer;
	char tTempStorageArray[100];
	char *tTempString_Vi_Pointer;
	char *tTempString_UVi_Pointer;
	char *tTempString_Ni_Pointer;
	char *tTempString_Vc_Pointer;
	float *tUVIndexPointer;
	unsigned int i,j;
	unsigned int tCurrentUVSetCount;
	tTempString_UVi_Pointer=tTempString_UVi;
	tTempString_Ni_Pointer=tTempString_Ni;
	tTempString_Vi_Pointer=tTempString_Vi;
	tTempStorageArrayPointer=tTempStorageArray;
	tTempString_Vc_Pointer=tTempString_Vc;

	//	Make sure the first character is 'f' else return a parse error

	if(*tFileDataPointer != 'f')
	{
		printf("Error while parsing polygonal face, 'f' marker not found");
			exit(0);
	}


	//	Parse the 'f' character

	tFileDataPointer=tFileDataPointer+2;


	//	Retreive the number of polygons for this current polygonal face

	while(*tFileDataPointer != ',')
	{
		*tTempStorageArrayPointer=*tFileDataPointer;
		tTempStorageArrayPointer++;
		tFileDataPointer++;
	}


	//	Get the vertex count for the current polygon

	tPolygonalFaceArray->tVertexCount=atof(tTempStorageArray);


	//	Reset the temp storage array and it's pointer

	for(i=0;i<100;i++)
	tTempStorageArray[i]=' ';

	tTempStorageArrayPointer=tTempStorageArray;


	//	Skip the comma

	tFileDataPointer++;


	//	Allocate memory to store vertex,normal,color and texture indices

	tPolygonalFaceArray->tVerticesIndexArray=malloc(sizeof(unsigned int) * tPolygonalFaceArray->tVertexCount);

	tPolygonalFaceArray->tNormalsIndicesArray=malloc(sizeof(unsigned int) * tPolygonalFaceArray->tVertexCount);

	tPolygonalFaceArray->tVertexColorArray=malloc(sizeof(float) * tPolygonalFaceArray->tVertexCount * 4);


	//	Allocate UV array only if texture information is present

	if(tUVSetCount > 0)

		tPolygonalFaceArray->tUVIndicesArray=malloc(sizeof(unsigned int) * tPolygonalFaceArray->tVertexCount * tUVSetCount);

	else

		tPolygonalFaceArray->tUVIndicesArray=NULL;	



	//	Check if vi token is found

	
	while(*tFileDataPointer != ',')
	{
		if((*tFileDataPointer)==(*tTempString_Vi_Pointer))
		{
			
			tTempString_Vi_Pointer++;
			tFileDataPointer++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the polygonal face...The keyword 'vi' not found");

			exit(0);

		}

	}


	//	Skip the comma

	tFileDataPointer++;


	////	Move the file pointer two places to include the 'vi' keyword

	//tFileDataPointer=tFileDataPointer-2;


	//	Read the vertex indices

	tFileDataPointer=ReadItemsAsInt(tPolygonalFaceArray->tVertexCount,tFileDataPointer,tPolygonalFaceArray->tVerticesIndexArray);

	//	Pointer is automatically incremented in the ReadItemsAsFloat() function



	//	Check if ni token is found

	
	while(*tFileDataPointer != ',')
	{
		if((*tFileDataPointer)==(*tTempString_Ni_Pointer))
		{
			
			tTempString_Ni_Pointer++;
			tFileDataPointer++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the polygonal face...The keyword 'ni' not found");

			exit(0);

		}

	}


	//	Skip the comma

	tFileDataPointer++;


	//	Read the vertex indices

	tFileDataPointer=ReadItemsAsInt(tPolygonalFaceArray->tVertexCount,tFileDataPointer,tPolygonalFaceArray->tNormalsIndicesArray);

	//	Pointer is automatically incremented in the ReadItemsAsFloat() function



	//	Read in the  UV indices only if the texture data is available

	if(tUVSetCount > 0)
	{

		//	For each UV set retreive the index into the corresponding UV array

		for(j=0;j<tUVSetCount;j++)
		{


		//	Check if uvi token is found
		
		while(*tFileDataPointer != ',')
		{
			if((*tFileDataPointer)==(*tTempString_UVi_Pointer))
			{
				
				tTempString_UVi_Pointer++;
				tFileDataPointer++;

			}
			else
			{
				//	Else report a parsing error and quit

				printf("Error parsing the polygonal face...The keyword 'uvi' not found");

				exit(0);

			}

		}


		//	Skip the comma

		tFileDataPointer++;


		
		//	Retreive and check the current UV count

		while(*tFileDataPointer != ',')
		{
			*tTempStorageArrayPointer=*tFileDataPointer;
			tTempStorageArrayPointer++;
			tFileDataPointer++;
		}


		//	Get the vertex count for the current polygon

		tCurrentUVSetCount=atoi(tTempStorageArray);


		//	Reset the temp storage array and it's pointer

		for(i=0;i<100;i++)
		tTempStorageArray[i]=' ';

		tTempStorageArrayPointer=tTempStorageArray;


		//	Verify the UV set count

		if(tCurrentUVSetCount != (j+1))
		{
		
			printf("Error parsing UVSetCount in polygonal face...The uvsetcount does not match");

			exit(0);
		}



		//	Skip the comma

		tFileDataPointer++;


		//	Update the pointer for the storing the current UV set Values

		tUVIndexPointer=tPolygonalFaceArray->tUVIndicesArray+(tPolygonalFaceArray->tVertexCount*j);


		//	Read the vertex indices

		tFileDataPointer=ReadItemsAsInt(tPolygonalFaceArray->tVertexCount,tFileDataPointer,tUVIndexPointer);

		//	Pointer is automatically incremented in the ReadItemsAsInt() function
		}

	}


	//	Read the Vertex Color information


	//	First verify the keyword 'vc'

	while(*tFileDataPointer != ',')
	{
		if((*tFileDataPointer)==(*tTempString_Vc_Pointer))
		{
			
			tTempString_Vc_Pointer++;
			tFileDataPointer++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the polygonal face...The keyword 'vc' not found");

			exit(0);

		}

	}


	//	Skip the comma

	tFileDataPointer++;



	tFileDataPointer=ReadItemsAsFloat(tPolygonalFaceArray->tVertexCount*4,tFileDataPointer,tPolygonalFaceArray->tVertexColorArray);
	
	//	Pointer is automatically incremented in the ReadItemsAsFloat() function


	return tFileDataPointer;
}


char* ParseInstance(Mesh *tMesh,char* tFileDataPointer,char* tMeshNamePointer,unsigned int tMeshNameLength,unsigned int tMeshInstanceCount)
{
	char tTempString_Instance[]={'i','n','s','t','a','n','c','e'};
	char tTempString_Vertices[]={'v','e','r','t','i','c','e','s'};
	char tTempString_Normals[]={'n','o','r','m','a','l','s'};
	char tTempString_UVSetCount[]={'u','v','s','e','t','c','o','u','n','t'};
	char tTempString_FaceCount[]={'f','a','c','e','c','o','u','n','t'};
	char *tTempString_Instance_Pointer;
	char *tTempString_Normals_Pointer;
	char *tTempString_UVSetCount_Pointer;
	char *tTempString_FaceCount_Pointer;
	char *tTempString_Vertices_Pointer;
	char tTempStorageArray[100];
	char* tTempStorageArrayPointer;
	unsigned int tRetreivedInstanceCount,tRetreivedNumberOfUVCoordinates;//tRetreivedVerticesCount,tRetreivedNormalsCount,tRetreivedUVSetCount;
	unsigned int i,j,tInstanceNumberCount;

	tTempString_Instance_Pointer=tTempString_Instance;
	tTempString_Normals_Pointer=tTempString_Normals;
	tTempString_UVSetCount_Pointer=tTempString_UVSetCount;
	tTempString_FaceCount_Pointer=tTempString_FaceCount;
	tTempString_Vertices_Pointer=tTempString_Vertices;
	tTempStorageArrayPointer=tTempStorageArray;
	tInstanceNumberCount=0;


	//	Make sure that the first item is the string 'instance'

	while(*tFileDataPointer != ',')
	{
		if((*tFileDataPointer)==(*tTempString_Instance_Pointer))
		{
			//	Verify that the first item is the word 'instance'

			tTempString_Instance_Pointer++;
			tFileDataPointer++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the mesh instance...The keyword 'instance' does not match");

			exit(0);

		}

	}


	//	Skip the comma

	tFileDataPointer++;


	//	After the 'instance' keyword is parsed retreive the current instance count and verify it

	while(*tFileDataPointer != ',')
	{
		*tTempStorageArrayPointer=*tFileDataPointer;
		tTempStorageArrayPointer++;
		tFileDataPointer++;
		tInstanceNumberCount++;
	}


	//	Get the parsed instance count value

	tRetreivedInstanceCount=atof(tTempStorageArray);


	//	Verify if the instance count matches

	if(tRetreivedInstanceCount != tMeshInstanceCount)
	{
		printf("Error Parsing Instance...Retreived instance count does not match");

		exit(0);
	}


	//	Update the name of the mesh

	//	Allocate the necessary memory needed to store the name

	tMesh->tName=malloc(sizeof(char) * (tMeshNameLength+tInstanceNumberCount));


	//	First read in the mesh name

	for(i=0;i<tMeshNameLength;i++)
	tMesh->tName[i]=tMeshNamePointer[i];


	//	Append the Instance Count to the mesh name

	for(i=tMeshNameLength;i < (tMeshNameLength+tInstanceNumberCount);i++)
	tMesh->tName[i]=tTempStorageArray[i-tMeshNameLength];


	//	Make the name string null terminated

	tMesh->tName[i]='\0';



	//	Reset the temp storage array and it's pointer

	for(i=0;i<100;i++)
	tTempStorageArray[i]=' ';

	tTempStorageArrayPointer=tTempStorageArray;


	//	Skip the comma

	tFileDataPointer++;


	
	//	Next Parse and retreive the keyword 'vertices'
	
	while(*tFileDataPointer != ',')
	{
		if((*tFileDataPointer)==(*tTempString_Vertices_Pointer))
		{
			//	Verify that the first item is the word 'instance'

			tTempString_Vertices_Pointer++;
			tFileDataPointer++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the mesh instance...The keyword 'vertices' does not match");

			exit(0);

		}

	}

	//	Skip the comma

	tFileDataPointer++;



	//	After the 'vertices' keyword is parsed retreive the total vertices count

	while(*tFileDataPointer != ',')
	{
		*tTempStorageArrayPointer=*tFileDataPointer;
		tTempStorageArrayPointer++;
		tFileDataPointer++;
	}


	//	Get the parsed instance count value

	tMesh->tNumberOfVertices=atof(tTempStorageArray);


	//	Reset the temp storage array and it's pointer

	for(i=0;i<100;i++)
	tTempStorageArray[i]=' ';

	tTempStorageArrayPointer=tTempStorageArray;


	//	Skip the comma

	tFileDataPointer++;


	//	Allocate the memory needed to store the vertices

	tMesh->tVerticesArray=malloc(sizeof(float) * 3 * tMesh->tNumberOfVertices);


	//	Read all the vertex positions into the mesh pointer

	tFileDataPointer=ReadItemsAsTripleFloats(tMesh->tNumberOfVertices,tFileDataPointer,tMesh->tVerticesArray);

	//	Don't update the pointer here it's already updated by the ReadItemsAsTripleFloats() function


	//	Next Parse and retreive the keyword 'normals'
	
	while(*tFileDataPointer != ',')
	{
		if((*tFileDataPointer)==(*tTempString_Normals_Pointer))
		{
			//	Verify that the first item is the word 'normals'

			tTempString_Normals_Pointer++;
			tFileDataPointer++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the mesh instance...The keyword 'normals' does not match");

			exit(0);

		}

	}


	//	Skip the comma

	tFileDataPointer++;


	//	After the 'normals' keyword is parsed retreive the total normals count

	while(*tFileDataPointer != ',')
	{
		*tTempStorageArrayPointer=*tFileDataPointer;
		tTempStorageArrayPointer++;
		tFileDataPointer++;
	}


	//	Get the parsed instance count value

	tMesh->tNumberOfNormals=atof(tTempStorageArray);


	//	Reset the temp storage array and it's pointer

	for(i=0;i<100;i++)
	tTempStorageArray[i]=' ';

	tTempStorageArrayPointer=tTempStorageArray;


	//	Skip the comma

	tFileDataPointer++;


	//	Allocate the memory needed to read in all the normals data

	tMesh->tNormalsArray=malloc(sizeof(float) * 3 * tMesh->tNumberOfNormals);


	//	Read all the vertex positions into the mesh pointer

	tFileDataPointer=ReadItemsAsTripleFloats(tMesh->tNumberOfNormals,tFileDataPointer,tMesh->tNormalsArray);


	//	Don't update the pointer here it's already updated by the ReadItemsAsTripleFloats() function


	//	Next Parse and retreive the keyword 'uvsetcount'
	
	while(*tFileDataPointer != ',')
	{
		if((*tFileDataPointer)==(*tTempString_UVSetCount_Pointer))
		{
			//	Verify that the first item is the word 'uvsetcount'

			tTempString_UVSetCount_Pointer++;
			tFileDataPointer++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the mesh instance...The keyword 'uvsetcount' does not match");

			exit(0);

		}

	}


	//	Skip the comma

	tFileDataPointer++;



	//	After the 'uvsetcount' keyword is parsed retreive the total uvset count

	while(*tFileDataPointer != ',')
	{
		*tTempStorageArrayPointer=*tFileDataPointer;
		tTempStorageArrayPointer++;
		tFileDataPointer++;
	}


	//	Get the parsed uvsets count value

	tMesh->tNumberOfUVSets=atof(tTempStorageArray);


	//	Reset the temp storage array and it's pointer

	for(i=0;i<100;i++)
	tTempStorageArray[i]=' ';

	tTempStorageArrayPointer=tTempStorageArray;


	//	Skip the comma

	tFileDataPointer++;


	//	Identify if the texturing information is present

	if(!tMesh->tNumberOfUVSets)

	tMesh->tIsTextureInformationPresent=0;

	else

	tMesh->tIsTextureInformationPresent=1;



	//	Retreive the UV information if texturing information is present

	if(tMesh->tIsTextureInformationPresent)
	{

		//	Allocate one array pointer for each UV set

		tMesh->tUVArray=malloc(sizeof(float*) * tMesh->tNumberOfUVSets);


		//	Retreive the UV data for each UV set

		for(j=0;j<tMesh->tNumberOfUVSets;j++)
		{

			//	Make sure that the file pointer is currently not pointing to a comma

			if((*tFileDataPointer)==',')
			{
				printf("Illegal Comma found while parsing UVSetData");
				exit(0);
			}


			//	Skip the UV set name

			while((*tFileDataPointer) != ',')
			tFileDataPointer++;


			//	Skip the comma

			tFileDataPointer++;


			//	Get the number of UV Coordinates for this set

			while(*tFileDataPointer != ',')
			{
				*tTempStorageArrayPointer=*tFileDataPointer;
				tTempStorageArrayPointer++;
				tFileDataPointer++;
			}


			//	Get the parsed UV Coordinates count value

			tRetreivedNumberOfUVCoordinates=atof(tTempStorageArray);


			//	Reset the temp storage array and it's pointer

			for(i=0;i<100;i++)
			tTempStorageArray[i]=' ';

			tTempStorageArrayPointer=tTempStorageArray;


			//	Skip the comma

			tFileDataPointer++;


			//	Allocate the space needed to store all the UV coordinates for the current UV set

			tMesh->tUVArray[j]=malloc(sizeof(float) * 2 * tRetreivedNumberOfUVCoordinates);


			//	Call the function to parse the Uv coordinates for the current set

			tFileDataPointer=ParseUVSet(tFileDataPointer,tMesh->tUVArray[j],tRetreivedNumberOfUVCoordinates);

		}
	}
	else
	{

		//	No texture coordinates for this polygon

		tMesh->tUVArray=NULL;
	}


	//	Next Parse and retreive the keyword 'facecount'
	
	while(*tFileDataPointer != ',')
	{
		if((*tFileDataPointer)==(*tTempString_FaceCount_Pointer))
		{
			//	Verify that the first item is the word 'facecount'

			tTempString_FaceCount_Pointer++;
			tFileDataPointer++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the mesh instance...The keyword 'facecount' does not match");

			exit(0);

		}

	}


	//	Skip the comma

	tFileDataPointer++;


	//	After the 'facecount' keyword is parsed retreive the total normals count

	while(*tFileDataPointer != ',')
	{
		*tTempStorageArrayPointer=*tFileDataPointer;
		tTempStorageArrayPointer++;
		tFileDataPointer++;
	}


	//	Get the parsed instance count value

	tMesh->tPolygonalFaceCount=atof(tTempStorageArray);


	//	Reset the temp storage array and it's pointer

	for(i=0;i<100;i++)
	tTempStorageArray[i]=' ';

	tTempStorageArrayPointer=tTempStorageArray;


	//	Skip the comma

	tFileDataPointer++;


	//	Allocate the space needed to store the polygonal faces

	tMesh->tPolygonalFaceArray=malloc(sizeof(PolygonalFace) * tMesh->tPolygonalFaceCount);


	//	Go into a for loop and read each polygonal face

	for(j=0;j<tMesh->tPolygonalFaceCount;j++)
	{
		tFileDataPointer=ParsePolygonalFace(tFileDataPointer,&tMesh->tPolygonalFaceArray[j],tMesh->tNumberOfUVSets);
	}


	//	return, file sucessfully parsed

	return tFileDataPointer;

	}




void main()
{

	FILE* tInputFile=fopen("vrfinalprojectscene_data.celu","r");
	FILE* tInputHeaderFile=fopen("vrfinalprojectscene_header.celu","r");

	

	//	Read the entire data from the file to a character array

	char tTempString_Mesh[]={'m','e','s','h'};
	char *tTempString_Mesh_Pointer;
	char tTempStorageArray[100];
	char *tTempStorageArrayPointer;
	long tFileSize=0;
	char *tHeaderFileData;
	char *tFileData;
	char *tFileDataParser;
	char *tHeaderFileDataParser;
	//unsigned int tTotalInstanceCount;
	unsigned int tNumberOfMeshInstancesParsedSoFar;
	unsigned int tMeshCount;
	unsigned int *tPerMeshInstanceCountArray;
	//Mesh *tMeshList;
	unsigned int i,j;
	tTempString_Mesh_Pointer=tTempString_Mesh;
	tTempStorageArrayPointer=tTempStorageArray;
	tTotalInstanceCount=0;
	tNumberOfMeshInstancesParsedSoFar=0;



	//	Parse the header file and get the total number of mesh count in the scene

	//	Move file pointer to the end of the file

	fseek(tInputHeaderFile,0,SEEK_END);

	tFileSize=ftell(tInputHeaderFile);


	//	Move the pointer back to the beginning of the file

	rewind(tInputHeaderFile);


	//	Create a character array to read in the entire file

	tHeaderFileData=malloc(tFileSize);

	tHeaderFileDataParser=tHeaderFileData;


	//	Loop until the end of file is reached

	while(!feof(tInputHeaderFile))
	{
		*tHeaderFileDataParser=(char)getc(tInputHeaderFile);
		tHeaderFileDataParser++;
	}
	

	//	Reset the file data pointer to the beginning of the array 

	tHeaderFileDataParser=tHeaderFileData;


	//	Parse and make sure the first keyword is 'mesh'

	while(*tHeaderFileDataParser != ',')
	{
		if((*tHeaderFileDataParser)==(*tTempString_Mesh_Pointer))
		{
			//	Verify that the first item is the word 'facecount'

			tTempString_Mesh_Pointer++;
			tHeaderFileDataParser++;

		}
		else
		{
			//	Else report a parsing error and quit

			printf("Error parsing the header file...The keyword 'mesh' not found");

			exit(0);

		}

	}


	//	Skip the comma

	tHeaderFileDataParser++;


	//	Retreive the mesh count from the scene header file

	while(*tHeaderFileDataParser != ',')
	{
		*tTempStorageArrayPointer=*tHeaderFileDataParser;
		tTempStorageArrayPointer++;
		tHeaderFileDataParser++;
	}


	//	Get the parsed mesh count value

	tMeshCount=atof(tTempStorageArray);


	//	Reset the temp storage array and it's pointer

	for(i=0;i<100;i++)
	tTempStorageArray[i]=' ';

	tTempStorageArrayPointer=tTempStorageArray;


	//	Skip the comma

	tHeaderFileDataParser++;


	//	Allocate the space needed to retrieve the number of instances for each mesh

	tPerMeshInstanceCountArray=malloc(tMeshCount * sizeof(unsigned int));


	//	Read in the Instance Count for each mesh

	for(i=0;i<tMeshCount;i++)
	{

		while(*tHeaderFileDataParser != ',')
		{
			*tTempStorageArrayPointer=*tHeaderFileDataParser;
			tTempStorageArrayPointer++;
			tHeaderFileDataParser++;
		}


		//	Get the parsed mesh count value

		tPerMeshInstanceCountArray[i]=atof(tTempStorageArray);


		//	Reset the temp storage array and it's pointer

		for(j=0;j<100;j++)
		tTempStorageArray[j]=' ';

		tTempStorageArrayPointer=tTempStorageArray;


		//	Skip the comma

		tHeaderFileDataParser++;


		//	Update the total number of mesh instance count

		tTotalInstanceCount += tPerMeshInstanceCountArray[i];

	}


	//	Allocate the total memory needed to store all the mesh instance

    tMeshList=malloc(sizeof(Mesh) * tTotalInstanceCount);



	//	Now begin parsing the scene data file


	//	Move file pointer to the end of the file

	fseek(tInputFile,0,SEEK_END);

	tFileSize=ftell(tInputFile);


	//	Move the pointer back to the beginning of the file

	rewind(tInputFile);


	//	Create a character array to read in the entire file

	tFileData=malloc(tFileSize);

	tFileDataParser=tFileData;


	//	Loop until the end of file is reached

	while(!feof(tInputFile))
	{
		*tFileDataParser=(char)getc(tInputFile);
		tFileDataParser++;
	}
	

	//	Reset the file data pointer to the beginning of the array 

	tFileDataParser=tFileData;



	//	Loop through all the meshes in the scene and retreive each of their instance

	for(i=0;i<tMeshCount;i++)
	{

		//	Assumes the name is not more than 200 characters long(or reads only the first 200 characters of the name)

		char tTempNameArray[200];
		unsigned int tNameLength;


		//	Assumes the first character is a letter 'm' indicating the starting of a new mesh node

		if(*tFileDataParser != 'm')
		{
			printf("Parsing error...Letter m indicating the starting of a mesh not found");

			return;
		}

		tNameLength=0;


		//	If found move the pointer to the next item

		tFileDataParser=tFileDataParser+2;


		//	Read in the name into the temp name array

		while(*tFileDataParser != ',')
		{
			tTempNameArray[tNameLength]=*tFileDataParser;
			tFileDataParser++;
			tNameLength++;
		}


		//	Skip the comma

		tFileDataParser++;


		//	Read in each instance of the mesh

		for(j=0;j<tPerMeshInstanceCountArray[i];j++)
		{

			//	Parser each instance of the mesh into a separate mesh structure
			
			tFileDataParser=ParseInstance((tMeshList+tNumberOfMeshInstancesParsedSoFar),tFileDataParser,tTempNameArray,tNameLength,(j+1));


			//	Keep track of the number of mesh instances parsed so far

			tNumberOfMeshInstancesParsedSoFar++;
		}
		


	}


	//	Close the file pointers

	fclose(tInputFile);

	fclose(tInputHeaderFile);


	//	The .celu files are success fully parsed at this point
	

	
}


				




