#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "tif.h"

const char * ERROR_IN = "\nError: ";
const char * ERROR_NO_ARG = "No arguments supplied.";
const char * ERROR_NO_INPUTFILE = "No inputfile supplied.";

void write_error(const char *s) {
  fwrite(ERROR_IN, strlen(ERROR_IN), 1, stderr);
  fwrite(s, strlen(s), 1, stderr);
  fwrite("\n\n", 2, 1, stderr);
  return;
}


/* structure telling how to read and process data file */
struct arguments {
  int inputfile;
  int outputfile;
  bool raw_output;
  int silent;
} a;


/* Open inputfile */
FILE *open_read(const char *s) {
  FILE *t;
  t = fopen (s, "rb");
  if (t==NULL) {
    write_error(strerror(errno));
  }
  return t;
}

/* open outputfile */
FILE *open_write(const char *s) {
  FILE *t;
  t = fopen (s, "wb");
  if (t==NULL) {
    write_error(strerror(errno));
  }
  return t;
}







int main(int argc, char *argv[]) {
  int tmp;

  long buffer_len;
  char *buffer = NULL;

  FILE *infile = NULL;
  FILE *outfile = NULL;

  if (argc < 2) {
    write_error(ERROR_NO_ARG);
    exit(1);
  }

  a.inputfile = 0;
  a.outputfile = 0;
  a.raw_output = true;
  a.silent = -1;

  tmp = 0;

  // les argumenter
  for (int x = 1; x<argc; x++) {
    if (argv[x][0] == '-') {
      switch (argv[x][1]) {
        case '?':
	case 'h':
	case 'H':
          // Display help screen and leave program
          printf("\n TIFREAD - Help");
	  printf("\n\n  Convert file:                    ./tifread inputfile");
	  printf("\n\n  Convert and save to disk         ./tifread inputfile -o outputfile");
	  printf("\n\n  Convert and save to disk silent  ./tifread inputfile -o outputfile -s");
          printf("\n");
	  printf("\n Made by Kristian Hiim\n\n");
	  exit(0);
	break;

	case 'o':
	case 'O':
	  tmp = 1;
	break;

	case 's':
	case 'S':
	  a.silent = 1;
	break;
      }
    } else if (tmp==1) {
      a.outputfile = x;
      tmp = 0;
      a.raw_output = false;
      if (a.silent < 0)
        a.silent = 0;
    } else if (a.inputfile==0)
      a.inputfile = x;
  }


  // Check for inputfile, and open file
  if (a.inputfile==0) {
    write_error(ERROR_NO_INPUTFILE);
    exit(1);
  } else {
    infile = open_read(argv[a.inputfile]);
    if (infile==NULL) {
      exit(1);
    }
  }

  // Check for outputfile
  if (a.outputfile>0) {
    outfile = open_write(argv[a.outputfile]);
    if (outfile==NULL) {
      if (infile!=NULL) {
        fclose(infile);
	infile=NULL;
      }
      exit(1);
    }
  } else if (a.raw_output) {
    outfile = stdout;
  }


  /* Simple write direct routine */


  while (!feof(infile)) {

    buffer = tif_read_block(infile, buffer_len);

    if (buffer!=NULL) {
      switch (buffer_len) {
        case TIF_TAPE_HEADER_LENGTH:
          /* ignore tape header */
        break;
        case TIF_HEADER_BLOCK_LENGTH_18:
        case TIF_HEADER_BLOCK_LENGTH_19:
        case TIF_HEADER_BLOCK_LENGTH_20:
        case TIF_HEADER_BLOCK_LENGTH_21:
        case TIF_HEADER_BLOCK_LENGTH_22:
        case TIF_DATA_BLOCK_LENGTH:
          if (fwrite(buffer, buffer_len, 1, outfile) != 1) {
            write_error(strerror(errno));
	    fclose(infile);
	    if (outfile != stdout)
	      fclose(outfile);
	    exit(1);
	  }
        break;
      }
    } else {
      if (buffer_len<0) {
        if (!feof(infile)) {
	  write_error("Reading input file");
	  exit(1);
	}
      }
    }

    if (buffer!=NULL) {
      free(buffer);
      buffer = NULL;
    }
  }


  // Close input & output file
  if (infile != NULL)
    fclose(infile);
  if ((outfile != NULL) && (outfile != stdout))
    fclose(outfile);



  return 0;
}