#include "objfile.h"

// this file contains some general code for loading polygonal data from 
// .obj files generated by maya/alias.
// Only loads grouping/vertices/face data at present...
// This is only meant as an example of one way to load in 3d objects
// from .obj files and store them into organized data structures.
// Note: Had to cut this out of a project that I am working on, so it 
// might or might not compile right away... FYI: I'm using Visual C++ 5.0
// If anyone else out there is developing a 3-d engine and wants to share 
// code/ideas, feel free to e-mail me at sbritton@netgrp.net.

// globals
FILE *stream;
OBJECT *gameobject[MAX_GAME_OBJECTS];
int numobjects = 0,objectsInFile = 0;

void LoadObj(char *filename)
{
	// open and read obj file
	int i;
	OBJECT *newobject;

	if((stream = fopen( filename, "r+t" )) != NULL ) 
	{
		// load objects,faces, and vertices
		// How many objects in this file ?
		CountObjects();
		for (i=numobjects - objectsInFile;i<numobjects;i++) {
			// need error check here and other mallocs
			newobject = (OBJECT *)malloc(sizeof(OBJECT));
			gameobject[i] = newobject;
			// Load in the faces
			LoadFaces(i - (numobjects - objectsInFile));
			// Load the vertices
			LoadVertices(i - (numobjects - objectsInFile));
		}	
		fclose( stream );
	}
}

void CountObjects()
{
	// determine number of objects in currently open .obj file
	// and update 'numobjects' global

	char s[100];
	char objectname[100];
	char *tok;
	
	
	objectsInFile = 0;
	while ((fgets(s,100,stream)) != NULL)
	{	
		if (s[0] == 'g')
		{
			if (strlen(s) > 2) {
				tok = strtok(s," ");
				tok = strtok(NULL," ");
				if (strcmp(objectname,tok) != 0){
					strcpy(objectname,tok);
					objectname[strlen(tok)-1] = 0;
					objectsInFile++;
				}
			}
			
		}
	}
	if (objectsInFile == 0)
		objectsInFile = 1;
	numobjects += objectsInFile;
}

void LoadVertices(int theobject)
{
	// load vertex data for specified object from .obj
	char s[100];
	char *tok;
	char temp[100];
	float coor[3];
	int vertcount = 0,i;
	VERTEX *newvert;
	
	if (ObjFileQue(theobject,'v')){
		while ((fgets(s,100,stream)) != NULL && (s[0] == 'v' && s[1] == ' '))			
		{
			tok = strtok(s," ");
			for (i=0;i<3;i++) {
				tok = strtok(NULL," ");
				strcpy(temp,tok);
				temp[strcspn(temp," ")] = 0;
				coor[i] = (float)atof(temp);
			}
			newvert = (VERTEX *)malloc(sizeof(VERTEX));
			gameobject[theobject + (numobjects - objectsInFile)]->vertices[vertcount] = newvert;
			gameobject[theobject + (numobjects - objectsInFile)]->vertices[vertcount]->x = coor[0];
			gameobject[theobject + (numobjects - objectsInFile)]->vertices[vertcount]->y = coor[1];
			gameobject[theobject + (numobjects - objectsInFile)]->vertices[vertcount]->z = coor[2];
			vertcount++;
		}
		gameobject[theobject + (numobjects - objectsInFile)]->numverts = vertcount;
	}
}

void LoadFaces(int theobject)
{
	// load face data for specified object from .obj
	char s[100];
	int numsides,vert[4];
	char *tok;
	char temp[100];
	int i,facecount = 0;
	FACE *newface;

	if(ObjFileQue(theobject,'f')){
		while ((fgets(s,100,stream)) != NULL && s[0] == 'f')
		{
			numsides = 4;
			tok = strtok(s," ");
			i = 0;
			while ((tok = strtok(NULL," ")) != NULL){
				strcpy(temp,tok);
				temp[strcspn(temp,"/")] = 0;
				vert[i] = (int)strtol(temp,NULL,10);
				i++;
			}
			newface = (FACE *)malloc(sizeof(FACE));
			gameobject[theobject + (numobjects - objectsInFile)]->faces[facecount] = newface;
			gameobject[theobject + (numobjects - objectsInFile)]->faces[facecount]->numsides = numsides;
			for(i=0;i<4;i++)
				gameobject[theobject + (numobjects - objectsInFile)]->faces[facecount]->vert[i] = vert[i];
			facecount++;
		}
		gameobject[theobject + (numobjects - objectsInFile)]->numfaces = facecount;
		
	}
	
}

int ObjFileQue(int whichobject,char whatdata)
{
	// Positions file pointer at line in .obj file
	// in prep for sequential data parsing
	// whatdata can be 'f' for 'faces' or 'v' for 'vertices'

	char s[100],objectname[100];
	char *tok;
	int numobj = 0;
	int linecount = 0,i;

	// reposition at start of file...
	rewind(stream);
	// Find the object
	while ((fgets(s,100,stream)) != NULL)
	{	
		linecount++;
		if (s[0] == 'g' || objectsInFile == 1)
		{
			if (strlen(s) > 2) {
				tok = strtok(s," ");
				tok = strtok(NULL," ");
				if (strcmp(objectname,tok) != 0 || objectsInFile == 1){
					strcpy(objectname,tok);
					objectname[strlen(tok)-1] = 0;
					numobj++;
					if ((numobj-1) == whichobject){
						if (objectsInFile == 1){
							rewind(stream);
							linecount = 0;
						}
						while ((fgets(s,100,stream)) != NULL)
						{	
							if (s[0] == whatdata)
							{
								// we are here... reposition file pointer
								// so that calling function will begin reading
								// in correct place.
								// must use linecount because of screwy
								// things that happen with 'fseek' in text mode
								rewind(stream);
								for (i=0;i<linecount;i++)
									fgets(s,100,stream);
								return 1;
							}
							linecount++;
						}
					}
				}
			}
			
		}
	}
	return 0;
}