#include "qtools.h"

struct memory bspStatic;
struct memory *bspMem = &bspStatic;

extern char *argv0;
extern char bspfilename[NAMELEN_PATH];
extern char pointfilename[NAMELEN_PATH];
extern char portfilename[NAMELEN_PATH];
extern char hullfilename[NAMELEN_PATH];

extern void CreateHulls(__memBase);
extern void ReadClipHull(__memBase, register int hullnum);
extern void UpdateEntLump(__memBase);

extern bool drawflag;

/*
 * =================
 * ProcessFile
 * 
 * =================
 */
static void ProcessFile(register char *sourcebase, register char *bspfilename1)
{
  char *mapBuf;
  FILE *bspFile;

// create filenames
  strcpy(bspfilename, bspfilename1);
  ReplaceExt(bspfilename, "bsp");

  strcpy(hullfilename, bspfilename1);
  ReplaceExt(hullfilename, "h0");

  strcpy(portfilename, bspfilename1);
  ReplaceExt(portfilename, "prt");

  strcpy(pointfilename, bspfilename1);
  ReplaceExt(pointfilename, "pts");

  if(!(bspMem->bspOptions & QBSP_ONLYENTS)) {
    remove(bspfilename);
    if(!(bspMem->bspOptions & QBSP_USEHULLS)) {
      hullfilename[strlen(hullfilename) - 1] = '1';
      remove(hullfilename);
      hullfilename[strlen(hullfilename) - 1] = '2';
      remove(hullfilename);
    }
    remove(portfilename);
    remove(pointfilename);
  }

// init the tables to be shared by all models
  BeginBSPFile(bspMem);

// load brushes and bspMem->mapentities
  mapBuf = (char *)GetVoid(sourcebase);
  LoadMapFile(bspMem, mapBuf);
  tfree(mapBuf);

  if (bspMem->bspOptions & QBSP_ONLYENTS) {
    UpdateEntLump(bspMem);
    return;
  }

// the clipping hulls will be written out to text files by forked processes
  CreateHulls(bspMem);

  ReadClipHull(bspMem, 1);
  ReadClipHull(bspMem, 2);

  WriteEntitiesToString(bspMem);
  
  bspFile = fopen(bspfilename, "wb");
  FinishBSPFile(bspMem, bspFile);
  fclose(bspFile);

  FreeClusters(bspMem, 0);
}

/*
 * ==================
 * main
 * 
 * ==================
 */
int main(int argc, char **argv)
{
  int i;
  char sourcename[NAMELEN_PATH];
  char destname[NAMELEN_PATH];

  memset(bspMem, 0, sizeof(struct memory));
  if (!setjmp(eabort)) {
    //
    // check command line flags
    //
    for (i = 1; i < argc; i++) {
      if (argv[i][0] != '-')
        break;
      else if (!strcmp(argv[i], "-drawGL")) {
        drawflag = TRUE;
        Draw_Init();
      }
      else if (!strcmp(argv[i], "-watervis"))
        bspMem->bspOptions |= QBSP_WATERVIS;
      else if (!strcmp(argv[i], "-slimevis"))
        bspMem->bspOptions |= QBSP_SLIMEVIS;
      else if (!strcmp(argv[i], "-notjunc"))
        bspMem->bspOptions |= QBSP_NOTJUNC;
      else if (!strcmp(argv[i], "-nofill"))
        bspMem->bspOptions |= QBSP_NOFILL;
      else if (!strcmp(argv[i], "-noclip"))
        bspMem->bspOptions |= QBSP_NOCLIP;
      else if (!strcmp(argv[i], "-onlyents"))
        bspMem->bspOptions |= QBSP_ONLYENTS;
      else if (!strcmp(argv[i], "-usehulls"))
        bspMem->bspOptions |= QBSP_USEHULLS;
      else if (!strcmp(argv[i], "-hullnum")) {
        hullnum = atoi(argv[i + 1]);
        i++;
      }
      else if (!strcmp(argv[i], "-subdivide")) {
        subdivide_size = atoi(argv[i + 1]);
        i++;
      }
      else
        Error("qbsp: Unknown option '%s'", argv[i]);
    }

    if (i != argc - 2 && i != argc - 1)
      Error("usage: qbsp [options] sourcefile [destfile]\noptions: -nojunc -nofill -draw -onlyents -verbose");

    //
    // let forked processes change name for ps status
    //
    argv0 = argv[0];

    //
    // create destination name if not specified
    //
    strcpy(sourcename, argv[i]);
    ReplaceExt(sourcename, "map");

    if (i != argc - 2) {
      strcpy(destname, argv[i]);
      ReplaceExt(destname, "bsp");
      mprintf("    - outputfile: %s\n", destname);
    }
    else
      strcpy(destname, argv[i + 1]);

    ProcessFile(sourcename, destname);
    PrintMemory();
  }

  return 0;
}
