/*
   CMSC 427 - Term Project Candidate
   ---------------------------------

   Beth Weinstein - bweinste@wam.umd.edu
   Ben Stewart - stewartb@wam.umd.edu
   Nawfel Tricha - Topaz@endorproductions.com

   Minimal OpenGL project using Microsoft Visual C++.
   This project is a premilinary candidate for the term 
   project required by CMSC 427.

   ABSTRACT:
      In this project, we will develop several fast 
      rendering and collision routines which would 
      require C/C++ speed and accuracy and then 
      implement a VisualJ++ interface.

   MODULE:
      Luxor (our own) file I/O module.

   
*/

#include "global.h"

// Luxor file format header:
typedef struct lux_header_s
   {
   char     tag[6];
   char     version[3];
   int      number_of_parts;
   } lux_header_t;

/*
   NT:
   Read Luxor file format into entity.
*/
int LuxorRead(char *filename, edict_t *ent)
{
	FILE	*f;
   lux_header_t   header;
   mdl_t *mdl;
   part_t *p;
   int i, j; 
   char x[256];
   int k, l, m;
   vec3_t v1, v2, v3;
   unsigned char stl;
	
   f = fopen (filename, "rb");
	if (!f)
      return 0;
  
   fread(&header, sizeof(header), 1, f);

   if (strcmp(header.tag, "LuXOR"))
      return 0;
   if (strcmp(header.version, "0A"))
      return 0;
   for (i = 0; i < header.number_of_parts; i++)
      {
      // Read Tag Name:
         p = PartSpawn();
         fread(&stl, 1, 1, f);
         p->tag_name = new char[stl + 1];
         fread(p->tag_name, stl, 1, f);
         p->tag_name[stl] = 0;

      // Read Father:
         fread(&stl, 1, 1, f);
         if (stl == 'N')
            {
            fread(&stl, 1, 1, f);
            fread(x, stl, 1, f);
            x[stl] = 0;
            PartSetFather(p->tag_name, x);
            }
         else if (stl == 'R')
            {
            ent->body = p;
            p->father = NULL;
            }

      // Read Brother:
         fread(&stl, 1, 1, f);
         if (stl == 'S')
            {
            fread(&stl, 1, 1, f);
            fread(x, stl, 1, f);
            x[stl] = 0;
            PartSetBrother(p->tag_name, x);
            }
      
      // Read Origin, Min_Angle, Max_Angle:  
         fread(p->origin, sizeof(p->origin), 1, f);
         fread(p->min_angle, sizeof(p->min_angle), 1, f);
         fread(p->max_angle, sizeof(p->max_angle), 1, f);

      // Read Model:
         fread(&stl, 1, 1, f);
         if (stl == 'M')
            {
            // Get model tag:
            fread(&stl, 1, 1, f);
            fread(x, stl, 1, f);
            x[stl] = 0;
            p->model_index = ModelExist(x);
            // Add new model to library:
            if (p->model_index == NOT_FOUND)
               {
               mdl = new mdl_t;
               fread(&mdl->num_triangles, sizeof (mdl->num_triangles), 1, f);
               mdl->tri = new triangle_t[mdl->num_triangles];
               for (j = 0; j < mdl->num_triangles; j++)
                  {
                  vec3_t ab, ac;
                  fread(&mdl->tri[j].a, sizeof(vec3_t), 1, f);
                  fread(&mdl->tri[j].b, sizeof(vec3_t), 1, f);
                  fread(&mdl->tri[j].c, sizeof(vec3_t), 1, f);
                  fread(&mdl->tri[j].a_s, sizeof(float), 1, f);
                  fread(&mdl->tri[j].a_t, sizeof(float), 1, f);
                  fread(&mdl->tri[j].b_s, sizeof(float), 1, f);
                  fread(&mdl->tri[j].b_t, sizeof(float), 1, f);
                  fread(&mdl->tri[j].c_s, sizeof(float), 1, f);
                  fread(&mdl->tri[j].c_t, sizeof(float), 1, f);
                  VectorSubtract(mdl->tri[j].b, mdl->tri[j].a, ab);
                  VectorSubtract(mdl->tri[j].c, mdl->tri[j].a, ac);
                  CrossProduct(ab, ac, mdl->tri[j].normal);
                  //fread(&mdl->tri[j], sizeof(mdl->tri[j]) - sizeof(vec3_t), 1, f);
                  }
               p->model_index = ModelSpawn(x, mdl);
               }
            // Skip model info on file:
            else
               {
               triangle_t  tri;
               int num_tri;
               fread(&num_tri, sizeof (num_tri), 1, f);
               for (j = 0; j < num_tri; j++)
                  fread(&tri, sizeof(tri)-sizeof(vec3_t), 1, f);                  
               }
            }
         // Make sure there is an empty model
         else if (stl != 'E')
            {            
            return 0;
            }

      // Read number of actions:
      fread(&stl, 1, 1, f);
      if (stl)
         {
         k = stl;      
         // Read actions:
         for (j = 0; j < k; j++)
            {
            // Read number of frames in action:
            fread(&stl, 1, 1, f);
            m = stl;
            // Read frames in action:
            for (l = 0; l < m; l++)
               {
               fread (v1, sizeof(v1), 1, f);
               fread (v2, sizeof(v2), 1, f);
               fread (v3, sizeof(v3), 1, f);
               FrameAdd(p, j, v1, v2, v3);
               }
            }
         }
      }
    
   fclose(f);
   return 1;
}