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

struct vertexStruct {
  float x, y, z;
  float nx,ny,nz;
};

struct patchStruct {
  int point1,point2,point3;
  float nx,ny,nz;
};

struct partStruct {
  int partNum, numOfVertices, numOfPatches;
  vertexStruct *vertexList;
  patchStruct  *patchList;
  partStruct   *next;
};
partStruct *partList, *headOfParts;

int partNum=0, vertex, vertexNum=0, patch, patchNum=0;
int totVert=0, totPtch=0, frame=0;

char ASEName[100];
char partName[100];
GLuint theObject;

void *xalloc(unsigned size)
{
  void *p = malloc(size);

  if (p == NULL) {
    //Application->ShowMessage("insufficient memory\n");
    //Application->Terminate();
  }
  return p;
}

void addPart(char *name, int size1, int size2)
{
  partStruct *tmp= (partStruct *) xalloc(sizeof(partStruct));

  partNum++;
  vertexNum=0;
  patchNum =0;
  totVert+=size1;
  totPtch+=size2;
  tmp->partNum      =partNum;
  tmp->numOfVertices=size1;
  tmp->numOfPatches =size2;
  tmp->vertexList   =new vertexStruct[size1];
  tmp->patchList    =new patchStruct [size2];
  tmp->next         =NULL;

  if (headOfParts==NULL)
	  headOfParts=tmp;
  else
    partList->next=tmp;
  partList=tmp;
  printf("Loading part-%d (%s) : %d vertices, %d patches.\n",
	partNum,name,size1,size2);
}

void LoadASE(char *fileName)
{
  FILE *input;
  char item[100];
  bool in_entities=false;
  float p1,p2,p3,n1,n2,n3;

  // start a new array :
  headOfParts=NULL;

  partNum=0;
  input = fopen(fileName, "r");
  if (input!=NULL)
  {
    in_entities=false;
	do {
	   fscanf(input, "%s", &item);
       if (strcmp(item,"*GEOMOBJECT")==0)
	      in_entities=true;
	  } while (in_entities==false && !feof(input));

    p1=0; p2=0; p3=0;
    if (in_entities) {
		while (!feof(input)) {
			fscanf(input, "%s", &item);

			if (strcmp(item,"*NODE_NAME")==0) {
				fscanf(input, "%s", &item);				
				strcpy(partName,item);
			}
            else if (strcmp(item,"*MESH_NUMVERTEX")==0) {
				fscanf(input, "%s", &item);				
				vertexNum=atoi(item);
				fscanf(input, "%s", &item);				
				fscanf(input, "%s", &item);				
				patchNum=atoi(item);

				addPart(partName, vertexNum, patchNum);
			}
            else if (strcmp(item,"*MESH_VERTEX")==0) {
				fscanf(input, "%s", &item);				
				vertex=atoi(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].x = atof(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].y = atof(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].z = atof(item);
			}
            else if (strcmp(item,"*MESH_FACENORMAL")==0) {
				fscanf(input, "%s", &item);				
				patch=atoi(item);

				/* Skip 4 reads for face normal */
				fscanf(input, "%s", &item);				
				n1 = atof(item);
				fscanf(input, "%s", &item);
				n2 = atof(item);
				fscanf(input, "%s", &item);
				n3 = atof(item);

				fscanf(input, "%s", &item);
				fscanf(input, "%s", &item);				
				vertex=atoi(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].nx = atof(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].ny = atof(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].nz = atof(item);
				p1=vertex;

				fscanf(input, "%s", &item);
				fscanf(input, "%s", &item);				
				vertex=atoi(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].nx = atof(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].ny = atof(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].nz = atof(item);
				p2=vertex;

				fscanf(input, "%s", &item);
				fscanf(input, "%s", &item);				
				vertex=atoi(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].nx = atof(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].ny = atof(item);
				fscanf(input, "%s", &item);
				partList->vertexList[vertex].nz = atof(item);
				p3=vertex;

				partList->patchList[patch].point1 = p1;
				partList->patchList[patch].point2 = p2;
				partList->patchList[patch].point3 = p3;

				partList->patchList[patch].nx = n1;
				partList->patchList[patch].ny = n2;
				partList->patchList[patch].nz = n3;
			}
	    } // while
    } // if
    fclose( input );
  } // file read

  printf("Success...\n");
  if (partNum>1)
  {
    printf("--------------------------------\n");
    printf("Total : %d vertices, %d patches.\n",totVert,totPtch);
  }
}

