#include "stdio.h"
#include "stdlib.h"
#include "math.h"

/*
   Crappy code to decode a sparce BMF file
   WARNING: minimal checking performed, left as an exercise
   to the reader to clean this up and support strip mesh types.
*/

typedef struct {
   float r,g,b,a;
} RGBA;

typedef struct {
   float u,v;
   float i,j,k;
   float x,y,z;
} VERTEX;

typedef struct {
   unsigned short int p0,p1,p2;
} TRILIST;

int main(int argc,char **argv)
{
   int i,j;
   unsigned short nmat,mtype,namelength,nvert=0,ntri=0;
   FILE *fptr;
   char fname[256];
   RGBA ambient,diffuse,specular;
   VERTEX *vlist;
   TRILIST *trilist;

   /* Should be 32 */
   fprintf(stderr,"Size of float: %d\n",sizeof(float));

   if ((fptr = fopen(argv[1],"r")) == NULL) {
      fprintf(stderr,"Open failed\n");
      exit(-1);
   }

   /* Read the number of materials */
   fread(&nmat,sizeof(unsigned short int),1,fptr);
   fprintf(stderr,"Number of materials: %d\n",nmat);

   /* Read the surface type */
   fread(&mtype,sizeof(unsigned short int),1,fptr);
   fprintf(stderr,"Mesh type: %d\n",mtype);

   for (i=0;i<nmat;i++) {
      fprintf(stderr,"Reading material %d\n",i);
      fread(&namelength,sizeof(unsigned short int),1,fptr);
      fprintf(stderr,"   Name length: %d\n",namelength);
      for (j=0;j<namelength;j++)
         fname[j] = fgetc(fptr);
      fprintf(stderr,"   JPEG name: %s\n",fname);

      /* Read the surface attributes */
      if (fread(&ambient,sizeof(RGBA),1,fptr) != 1) {
         fprintf(stderr,"error reading ambient colour\n");
         exit(-1);
      }
      fprintf(stderr,"   Ambient: %f %f %f %f\n",
         ambient.r,ambient.g,ambient.b,ambient.a);
      fread(&diffuse,sizeof(RGBA),1,fptr);
      fprintf(stderr,"   Diffuse: %f %f %f %f\n",
         diffuse.r,diffuse.g,diffuse.b,diffuse.a);  
      fread(&specular,sizeof(RGBA),1,fptr);
      fprintf(stderr,"   Specular: %f %f %f %f\n",
         specular.r,specular.g,specular.b,specular.a);  

      /* Read the vertices */
      fread(&nvert,sizeof(unsigned short int),1,fptr);
      fprintf(stderr,"   Number of vertices: %d\n",nvert);
      vlist = malloc(sizeof(VERTEX)*nvert);
      if (fread(vlist,sizeof(VERTEX),nvert,fptr) != nvert) {
         fprintf(stderr,"Failed to read vertex list\n");
         exit(-1);
      }
      /*
      for (j=0;j<nvert;j++) {
         fprintf(stderr,"   %f %f    %f %f %f    %f %f %f\n",
            vlist[j].u,vlist[j].v,
            vlist[j].i,vlist[j].j,vlist[j].k,vlist[j].x,vlist[j].y,vlist[j].z);
      }
      */

      /* Read the triangles */
      fread(&ntri,sizeof(unsigned short int),1,fptr); 
      trilist = malloc(sizeof(TRILIST)*ntri); 
      if (fread(trilist,sizeof(TRILIST),ntri,fptr) != ntri) {
         fprintf(stderr,"Failed to read triangle list\n");
         exit(-1);
      }
      /*
        for (j=0;j<ntri;j++) {
           fprintf(stderr,"   %d %d %d\n",
              trilist[j].p0,trilist[j].p1,trilist[j].p2);
        }
      */

      /* Write the triangles in a GEOM file format */
      for (j=0;j<ntri;j++) {
         printf("f3n %f %f %f %f %f %f %f %f %f ",
            vlist[trilist[j].p0].x,vlist[trilist[j].p0].y,vlist[trilist[j].p0].z,
            vlist[trilist[j].p1].x,vlist[trilist[j].p1].y,vlist[trilist[j].p1].z,
            vlist[trilist[j].p2].x,vlist[trilist[j].p2].y,vlist[trilist[j].p2].z);
         printf("%f %f %f %f %f %f %f %f %f ",
            vlist[trilist[j].p0].i,vlist[trilist[j].p0].j,vlist[trilist[j].p0].k,
            vlist[trilist[j].p1].i,vlist[trilist[j].p1].j,vlist[trilist[j].p1].k,
            vlist[trilist[j].p2].i,vlist[trilist[j].p2].j,vlist[trilist[j].p2].k);
         printf(" 0.5 0.5 0.5\n");
      }
   }

   fclose(fptr);
}


