#include <stdlib.h>
#include <direct.h>
#include <string.h>

#include <pr.h>
#include <prgui.h>

#if defined (MSGLIDE) || defined (WTGLIDE)
#include <pr3dfx.h>
#include <windows.h>
#endif

/*

       /=========\ /========\ ||        || /========  /=======\
       ||       || ||      || ||        || ||         ||      ||
       ||       || ||      || ||        || ||         ||      ||
       ||       || ||      || ||        || ||         ||      ||
       ||       || ||      || ||   ||   || ||         ||      //
       |=========/ ||      || ||   ||   || |=======   |=====<<
       ||          ||      || ||   ||   || ||         ||      \\
       ||          ||      || ||   ||   || ||         ||       ||
       ||          ||      || ||   ||   || ||         ||       ||
       ||          \========/ \==========/ \========= ||       ||

--------------------------------<===>----------------------------------

    /=======\   /========= |\     || |======\  /========= /=======\
    ||      ||  ||         ||\    || ||    \ \ ||         ||      ||
    ||      ||  ||         || \   || ||     || ||         ||      ||
    ||      ||  ||         ||  \  || ||     || ||         ||      ||
    ||      //  ||         ||   \ || ||     || ||         ||      //
    |======<<   |======    ||\   \|| ||     || |======    |======<<
    ||      \\  ||         || \   || ||     || ||         ||      \\
    ||       || ||         ||  \  || ||     || ||         ||       ||
    ||       || ||         ||   \ || ||    / / ||         ||       ||
    ||       || |========= ||    \|| |======/  |========= ||       ||

Unify Utility

Combines all segments into one.

 Revision History:
 July 18, 1996: Created

*/

char outfile[80];               /* Name of the output file */
PR_OBJECT *object1;
PR_OBJECT *object3;             /* Output object */

void main (int argc, char *argv[])
{
PR_SEGMENT *seg;
PR_DWORD i, f;
PR_DWORD totface, totvert;
PR_DWORD numfaces, numverts;
PR_FACE *facelist;
PR_VERTEX *vertlist;
PR_VERTEX_DATA *vertdata;
PR_DWORD vnum;

  PRGUI_InitPath (argv[0]);

  if (argc < 3)
    {
     PR_FatalError (
                "Unify Utility    version "
                PR_VERSION_NUMBER
                "\nCopyright 1997 Egerter Software\n\n"
		"Usage: \n"
        "Unify file1.PRO outfile.PRO\n", "UNIFY");
    }

  printf ("Unify Utility    version ");
  printf (PR_VERSION_NUMBER);
  printf ("\nCopyright 1997 Egerter Software\n\n");

  PR_Initialize (50);

#if defined (MSGLIDE) || defined (WTGLIDE)
  PR_Detect3Dfx();
  PR_Initialize3Dfx ();
#else
  PR_DetectVGA();
  PR_InitializeVGA ();
#endif

  PR_AllocMaterials (512);
  PR_AllocTextures (255);
  PR_AllocShadeTables (32);

  object1 = PR_LoadPRO (argv[1], LOAD_NORMAL);
  if (object1 == NULL)
    PR_FatalError ("An error has occurred when loading the file.\n", "UNIFY");
    
  object3 = PR_AllocObject ();
  if (object3 == NULL)
    PR_FatalError ("An error has occurred when allocating the combined object.\n", "UNIFY");
    
  /* Make a copy of the first object's name */
  object3->name = strdup (object1->name);

  object3->segment_list = (PR_SEGMENT *)calloc(1, sizeof (PR_SEGMENT));
  object3->num_segments = 1;
  object3->segment_list->segment_number = 0;
  /* Allocate space for the segment structures */

  /* Count the total number of vertices and faces */
  numfaces = numverts = 0;
  for (i = 0; i < object1->num_segments; i++)
    {
     seg = &object1->segment_list[i];
     numfaces += seg->num_faces;
     numverts += seg->num_vertices;
    }

  /* Allocate space for the new lists */
  facelist = (PR_FACE *)calloc (numfaces, sizeof (PR_FACE));
  vertlist = (PR_VERTEX *)calloc (numverts, sizeof (PR_VERTEX));
  vertdata = (PR_VERTEX_DATA *)calloc (numverts, sizeof (PR_VERTEX_DATA));
  totface = totvert = 0;

  for (i = 0; i < object1->num_segments; i++)
    {
     seg = &object1->segment_list[i];
     memcpy (&facelist[totface], seg->face_list, seg->num_faces * sizeof (PR_FACE));

     for (f = 0; f < seg->num_faces; f++)
       {
        vnum = PR_GetVertexNumber (seg->vertex_list, seg->face_list[f].vertex1);
        facelist[f + totface].vertex1 = &vertlist[vnum + totvert];

        vnum = PR_GetVertexNumber (seg->vertex_list, seg->face_list[f].vertex2);
        facelist[f + totface].vertex2 = &vertlist[vnum + totvert];

        vnum = PR_GetVertexNumber (seg->vertex_list, seg->face_list[f].vertex3);
        facelist[f + totface].vertex3 = &vertlist[vnum + totvert];
       }
     totface += seg->num_faces;

     memcpy (&vertlist[totvert], seg->vertex_list, seg->num_vertices * sizeof (PR_VERTEX));
     memcpy (&vertdata[totvert], seg->vertex_data, seg->num_vertices * sizeof (PR_VERTEX_DATA));
     totvert += seg->num_vertices;
    }

  /* Patch in the new lists */
  object3->segment_list->face_list = facelist;
  object3->segment_list->vertex_list = vertlist;
  object3->segment_list->vertex_data = vertdata;
  object3->segment_list->num_faces = numfaces;
  object3->segment_list->num_vertices = numverts;

  PR_SavePRO (argv[2], object3, SAVE_ALL_MATERIALS);
}



