#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
//
#include "proto.h"
#include "main.h"
#include "bucket.h"
#include "parser.h"
#include "preprocess.h"
#include "evaluate.h"
#ifdef __riscos__
#include "os.h"
#endif

S32 debug_print_lines;


void usage() {

  fprintf(stderr, "writeflash 0.22\n");
  fprintf(stderr, "syntax:   writeflash [switches] <infile> [<outfile>]\n");
  fprintf(stderr, "switches:  -pl                       print lines\n");
  fprintf(stderr, "           -define <macro> <value>   defines a macro\n");
  fprintf(stderr, "           -defines <macro> <value>  defines a macro (string)\n");
  exit(-1);
}


S32 main(S32 argc, char *argv[]) {

  U8 *buffer;
  U32 size;
  S32 arg, i, macrocount = 0;
  char *macronames[MAXMACROS], *macrovalues[MAXMACROS];

  if (argc < 2)   usage();

  // default arguments/switches
  debug_print_lines = 0;

  // next unused argument
  arg = 1;
  while (argv[arg][0] == '-') {
    if (strcmp(argv[arg], "-pl") == 0) {
      debug_print_lines = 1;

    } else if (strcmp(argv[arg], "-define") == 0) {
      if (arg+2 >= argc-1) {
        fprintf(stderr, "Too few arguments\n");
        exit(0);
      }
      macronames[macrocount] = argv[arg+1];
      macrovalues[macrocount] = argv[arg+2];
      macrocount++;
      arg += 2;

    } else if (strcmp(argv[arg], "-defines") == 0) {
      if (arg+2 >= argc-1) {
        fprintf(stderr, "Too few arguments\n");
        exit(0);
      }
      macronames[macrocount] = argv[arg+1];
      macrovalues[macrocount] = malloc(strlen(argv[arg+2])+3);
      if (!macrovalues[macrocount]) {
        fprintf(stderr, "No room\n");
        exit(0);
      }
      sprintf(macrovalues[macrocount], "\"%s\"", argv[arg+2]);
      macrocount++;
      arg += 2;
    }
    arg++;
  }

  init_evaluator();

  if (arg == argc) {
    fprintf(stderr, "Too few arguments\n");
    usage();
  }

  for (i = 0; i < macrocount; i++)
    if (define_macro(macronames[i], macrovalues[i])) {
      fprintf(stderr, "Failed to define macro '%s'\n", macronames[i]);
      exit(0);
    }

  // load/preprocess the input file
  if (preprocessor(argv[arg]))   exit(0);
  arg++;

  if (parse_file()) {
    printf("failed to parse file\n");
    exit(0);
  }

  if (init_bucket(NULL, 0)) {
    fprintf(stderr, "Failed to initialise buffer\n");
    exit(0);
  }

  if (write_flash_file()) {
    fprintf(stderr, "Failed to create file\n");
  }

  if (close_bucket(&buffer, &size)) {
    fprintf(stderr, "Failed to read output buffer\n");
    exit(0);
  }

  buffer[4] = size       & 255;
  buffer[5] = (size>> 8) & 255;
  buffer[6] = (size>>16) & 255;
  buffer[7] = (size>>24) & 255;

  if (arg == argc) {
    U32 i;
    for (i = 0; i < size; i++)
#ifdef __riscos__
      xos_writec(buffer[i]);
#else
      printf("%c", buffer[i];
#endif

  } else {
    FILE *fh;

    fh = fopen(argv[arg], "wb");
    if (!fh) {
      fprintf(stderr, "Failed to open file %s\n", argv[arg]);
      exit(0);
    }
    fwrite(buffer, 1, size, fh);
    fclose(fh);
  }
}
