#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "pnmutils.h"

int compressFileOutput=0;
int compressFileInputA=0;
int compressFileInputB=0;

FILE *a;
gzFile inFileA;

FILE *b;
gzFile inFileB;

FILE *dest;
gzFile outFileDest;

void get_image_params(FILE * ifs, struct image_params * params)
{
  int c;
  int dims[3];
  int dims_scanned;

  /* check for file pointers to non existant files */
  if( ifs == NULL )
  {
      fprintf(stderr,"get_image_params: non-existant file\n");
      exit(EXIT_FAILURE);
  }

  if ((c=filegetc(ifs))!='P') /* image must start with P5, P6, P7, or P8 */
  {
      fprintf(stderr, "get_image_params: file not ppm file (doesn't start with ``P'').\n");
      fprintf(stderr, "Began with %c\n",c);
      exit(EXIT_FAILURE);
  }

  c=filegetc(ifs);
  if (c!='5' && c!='6' && c!='7' && c!='8' && c!='9' && c!='A')
  {
      fprintf(stderr, "get_frame_params: input image must begin with\n"
                      "P5 for grey byte, P6 for colour byte,\n"
                      "P7 for grey double, or P8 for colour double\n"
                      "P9 for grey lightspace double, or PA for colour lightspace double\n");
      exit(EXIT_FAILURE);
    }
  params->type=c;
  /* enter a loop
   * skip comments which start with #
   * and look for the dimensions
   */
  dims_scanned = 0;
  do {
      char line[80];
      filegets( line, sizeof(line), ifs );
      if( *line != '#' )
      {
          char *p = strtok(line," \n" );
          while( p && (*p != '#') )
          {
              sscanf(p,"%d", &dims[dims_scanned] );
              dims_scanned++;
              p = strtok( NULL, " \n" );
          }
      }
  } while( dims_scanned < 3 );

  params->width = dims[0];
  params->height = dims[1];
  params->max_val = dims[2];

  if( params->max_val != 255 )
  {
      fprintf(stderr,"get_frame_params: max value must be 255\n");
      exit( EXIT_FAILURE );
  }
  
  if(params->type=='A' || params->type=='9')
  {
      char line[80];

      filegets( line, sizeof(line), ifs );
      if( *line != '#' )
      {
          char *p = strtok(line," \n" );
          while( p && (*p != '#') )
          {
              sscanf(p,"%d", &params->numberOfImages );
              p = strtok( NULL, " \n" );
          }
      }

      filegets( line, sizeof(line), ifs );
      if( *line != '#' )
      {
          char *p = strtok(line," \n" );
          while( p && (*p != '#') )
          {
              sscanf(p,"%f", &params->exponent );
              p = strtok( NULL, " \n" );
          }
      }

      
  }

}

void get_image_type(FILE * ifs, struct image_params * params)
{
  int c;
  if( ifs == NULL ) { /* check for file pointers to non existant files */
    fprintf(stderr,"get_image_type: non-existant file\n");
    exit(EXIT_FAILURE);
  }

  if (filegetc(ifs)!='P') /* image must start with P5, P6, P7, or P8 */
  {
      fprintf(stderr, "get_image_type: file not ppm file (doesn't start with"
              " ``P'').\n");
      exit(EXIT_FAILURE);
  }
  c=filegetc(ifs);
  if (c!='5' && c!='6' && c!='7' && c!='8' && c!='9' && c!='A')
    {
      fprintf(stderr, "get_frame_params: input image must begin with\n"
                      "P5 for grey byte, P6 for colour byte,\n"
                      "P7 for grey double, or P8 for colour double\n"
                      "P9 for grey lightspace double, or PA for colour lightspace double\n");
      exit(EXIT_FAILURE);
    }
  params->type=c;
}

void get_image_params_preserve_comments(FILE * ifs, struct image_params * params, FILE * ofs)
{
  int dims[3];
  int dims_scanned;
  if( ifs == NULL ) { /* check for file pointers to non existant files */
    fprintf(stderr,"get_frame_params_preserve_comments: non-existant input file\n");
    exit(EXIT_FAILURE);
  }

  if( ofs == NULL ) { /* check for file pointers to non existant files */
    fprintf(stderr,"get_frame_params_preserve_comments: non-existant output file\n");
    exit(EXIT_FAILURE);
  }

  dims_scanned = 0;
  do {
      char line[80];
      filegets( line, sizeof(line), ifs );
      if( *line != '#' )
      {
          char *p = strtok(line," \n" );
          while( p && (*p != '#') )
          {
              sscanf(p,"%d", &dims[dims_scanned] );
              dims_scanned++;
              p = strtok( NULL, " \n" );
          }
      }
      else
      {
/*          fprintf(ofs,"%s",line);*/
          filewrite(line,sizeof(unsigned char),strlen(line),ofs);

      }
  } while( dims_scanned < 3 );

  params->width = dims[0];
  params->height = dims[1];
  params->max_val = dims[2];

  if( params->max_val != 255 )
  {
      fprintf(stderr,"get_frame_params: max value must be 255\n");
      exit( EXIT_FAILURE );
  }
  
  if(params->type=='A' || params->type=='9')
  {
      char line[80];

      filegets( line, sizeof(line), ifs );
      if( *line != '#' )
      {
          char *p = strtok(line," \n" );
          while( p && (*p != '#') )
          {
              sscanf(p,"%d", &params->numberOfImages );
              p = strtok( NULL, " \n" );
          }
      }

      filegets( line, sizeof(line), ifs );
      if( *line != '#' )
      {
          char *p = strtok(line," \n" );
          while( p && (*p != '#') )
          {
              sscanf(p,"%f", &params->exponent );
              p = strtok( NULL, " \n" );
          }
      }
  }
}

int fileread( void *ptr, int size, int nmemb, FILE *stream)
{
    if(stream==a && compressFileInputA)
    {
        int len;
        len=gzread(inFileA, ptr, size*nmemb);
        return(len);
    }

    if(stream==b && compressFileInputB)
    {
        int len;
        len=gzread(inFileB, ptr, size*nmemb);
        return(len);
    }

//    if(compressFileInputA || compressFileInputB)
//        printf("ERROR in fileread %d %d\n",compressFileInputA,compressFileInputB),exit(0);

    return(fread(ptr,size,nmemb,stream));
}

int filewrite( const void *ptr, int size, int nmemb, FILE *stream)
{
    if(compressFileOutput)
    {
        int len;
        if ((len=gzwrite(outFileDest, ptr, nmemb*size))!=nmemb*size)
            printf("GZIP Write Error %d %d %d\n",len,nmemb,size),exit(-1);
        return(nmemb*size);
    }

    return(fwrite(ptr,size,nmemb,stream));
}

char *filegets(char *s, int size, FILE *stream)
{
    if(stream==a && compressFileInputA)
        return(gzgets(inFileA, s, size));

    if(stream==b && compressFileInputB)
        return(gzgets(inFileB, s, size));

//    if(compressFileInputA || compressFileInputB)
//        printf("ERROR in filegets\n");
    
    return(fgets(s,size,stream));
}

int filegetc(FILE *stream)
{
    if(stream==a && compressFileInputA)
        return(gzgetc(inFileA));

    if(stream==b && compressFileInputB)
        return(gzgetc(inFileB));

/*    if(compressFileInputA || compressFileInputB)
        printf("ERROR in filegetc %d %d \n",compressFileInputA,compressFileInputB),exit(0);
*/
    return(fgetc(stream));
}

int fileeof(FILE *stream)
{
    if(stream==a && compressFileInputA)
        return(gzeof(inFileA));

    if(stream==b && compressFileInputB)
        return(gzeof(inFileB));

//    if(compressFileInputA || compressFileInputB)
//        printf("ERROR in fileeof\n");

    return(feof(stream));
}


int isGZIPFile(char *fileName)
{
/*    printf("%c%c%c",fileName[strlen(fileName)-3],
       fileName[strlen(fileName)-2],
       fileName[strlen(fileName)-1]);*/

    if(fileName[strlen(fileName)-3]=='.' &&
       fileName[strlen(fileName)-2]=='g' &&
       fileName[strlen(fileName)-1]=='z')
        return(1);
    else
        return(0);

}
