#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include "/usr/local/include/fitsio.h"
#include "./gethead.c"
#include "./gethead2.c"
#include "./swapfloat.c"

/*
darkflatfz.c
(rawdata[short] - dark[float]) / flat[float] = newframe[float]
*/

void swapfloat(float *f);
int gethead(char *fname);
int gethead2(char *fname);
void mkheader(char *header, char *fname);
int readfz(short data[], char *fname, char *header);

int main (int argc, char**argv)
{

  short     *data1;
  float     *data2, *data3;
  float     *data4={0};
  char      fname1[50], fname4[30];
  char      line[100];
  FILE      *fp, *fp4;
  int       i, j, xynum = 1048576;
  int       datanum = ((int)(xynum*sizeof(float)/2880)+1)*2880/sizeof(float);
  int       lnum, fnum;
  int       hfact;
  int       headsize1 = 2880, headsize2, headsize3;
  char      *header1;
  char      **fits1arr, **fits4arr;
  int       fzstat;

  if (argc < 4){
    fprintf(stderr, "usage : darkflatfz rawdata-list dark(float) flat(float)\n");
    return 0;
  }

  hfact = gethead(argv[2]);
  if (hfact == 0){
    fprintf(stderr, "The header size was not obtained.\n");
    return 0;
  }
  headsize2 = hfact * 2880;

  hfact = gethead(argv[3]);
  if (hfact == 0){
    fprintf(stderr, "The header size was not obtained.\n");
    return 0;
  }
  headsize3 = hfact * 2880;


/*
read the data2, dark
*/
  data2 = (float*)malloc(xynum*sizeof(float));
  if(NULL == (fp = fopen(argv[2], "rb"))){
      printf("%s can not be opened.\n",argv[2]);
      exit(1);
  }
  fseek(fp, headsize2, SEEK_SET);
  fread(data2, sizeof(float), xynum, fp);
  fclose(fp);

  for (i=0; i<xynum; i++){
    swapfloat(&data2[i]);
  }


/*
read the data3, flat
*/
  data3 = (float*)malloc(xynum*sizeof(float));
  if(NULL == (fp = fopen(argv[3], "rb"))){
      printf("%s can not be opened.\n", argv[3]);
      exit(1);
  }
  fseek(fp, headsize3, SEEK_SET);
  fread(data3, sizeof(float), xynum, fp);
  fclose(fp);

  for (i=0; i<xynum; i++){
    swapfloat(&data3[i]);
  }


/*
read the list
*/

  if(NULL == (fp = fopen(argv[1], "r"))){
    printf("%s can not be opened.\n", argv[1]);
    exit(1);
  }
  lnum = 0;
  while(fgets(line, sizeof(line), fp) != NULL){
    lnum ++;
  }
  fclose(fp);

  fits1arr = (char**)malloc(lnum*sizeof(char)*50);
  fits4arr = (char**)malloc(lnum*sizeof(char)*30);
  fp = fopen(argv[1], "r");
  fnum = 0;
  while(fgets(line, sizeof(line), fp) !=NULL){
    sscanf(line, "%s %s", fname1, fname4);
    fits1arr[fnum] = (char*)malloc(50);
    fits4arr[fnum] = (char*)malloc(30);
    strcpy(fits1arr[fnum], fname1);
    strcpy(fits4arr[fnum], fname4);
    fnum++;
  }
  fclose(fp);


  for(j=0; j<lnum; j++){

    data1 = (short*)malloc(xynum*sizeof(short));
    /* header1=(char*)malloc(headsize1*sizeof(char)+1); */
    header1 = (char*)malloc(headsize1*sizeof(char));
    mkheader(header1, fits1arr[j]);
    fzstat=readfz(data1, fits1arr[j], header1);
    if(fzstat == 1){
      printf("fzstat == 1\n");
    }

    /*
     dark subtraction and flat division
    */
    data4 = (float*)malloc(datanum*sizeof(float));
    for (i=0; i<xynum; i++){
      if (data3[i] != 0.0){
        data4[i] = (data1[i] - data2[i]) / data3[i];
      } else {
        data4[i] = -1000.0;
      }
    }
  
    for (i=0; i<datanum; i++){
      swapfloat(&data4[i]);
    }

    fp4=fopen(fits4arr[j], "wb");
    fwrite(header1, sizeof(char), headsize1, fp4);
    fwrite(data4, sizeof(float), datanum, fp4);
    fclose(fp4);

    free(fits1arr[j]);
    free(fits4arr[j]);
    free(data4);
    free(data1);
    free(header1);
  }

  free(data2);
  free(data3);
  free(fits1arr);
  free(fits4arr);

  return 0;

}


void mkheader(char *header, char *fname)
{

  int       ih;
  char      nheader[2881] = "SIMPLE  =                    T / Fits standard                                  BITPIX  =                  -32 / Bits per pixel                                 NAXIS   =                    2 / Number of axes                                 NAXIS1  =                 1024 / Axis length                                    NAXIS2  =                 1024 / Axis length                                    EXTEND  =                    F / File may contain extensions                    ";
  char      endheader[81] = "END                                                                             ";
  char      *nn;
  char      suffix[6];
  int       slen, hfact, headsize, lnum, i;
  int       keynum;
  char      *oheader;
  FILE      *fp;
  char      card[81], keyword[10];

  nn = " ";
  keynum = 7;

  slen = strlen(fname);
  slen = slen - 5;

  memcpy(suffix, fname+slen, 5);  suffix[5] = '\0';  

  if(strcmp(suffix, ".fits") == 0){
      hfact = gethead(fname);
  } else if(strcmp(suffix, "ts.fz") == 0 || strcmp(suffix, "ts.ic") == 0){
      hfact = gethead2(fname);
  } else {
    printf("%s : filename is wrong.\n", fname);
      exit(1);
  }

  hfact = hfact + 1;

  headsize = hfact * 2880;
  lnum = headsize / 80;

  oheader = (char*)malloc(headsize*sizeof(char)+1);
  fp = fopen(fname, "rb");
  fread(oheader, sizeof(char), headsize, fp);
  fclose(fp);

  for(i=0; i<lnum; i++){
    memcpy(card, oheader+i*80, 80);   card[80] = '\0';
    memcpy(keyword, card, 9);    keyword[9] = '\0';

    if(strcmp(keyword, "OBJECT  =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "FILTER  =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "EXPOS   =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "DATE_UTC=") == 0){ 
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "TIME_UTC=") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "DATE_LT =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "TIME_LT =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "JD      =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "MJD     =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "EPOCH   =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "EQUINOX =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "RA      =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "DEC     =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "RA_OFF  =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "DEC_OFF =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "AIRMASS =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "ALTITUDE=") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "AZIMUTH =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "ROTATOR =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "ROTATER =") == 0){
      card[5]='O'; card[38]='o';  strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "FOCUS_A =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "FOCUS_B =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "FOCUS_AB=") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "TEMP    =") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "HUMIDITY=") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "POL-AGL1=") == 0){
      strncat(nheader, card, 80); keynum++;
    }
    if(strcmp(keyword, "POL-AGL2=") == 0){
      strncat(nheader, card, 80); keynum++;
    }
  }

  free(oheader);

  strncat(nheader, endheader, 80);

  keynum = keynum * 80;

  for(ih=0; ih<keynum; ih++){
    header[ih] = nheader[ih];
  }
  for(ih=keynum; ih<2880; ih++){
    header[ih] = nn[0];
  }

}


int readfz(short data[], char *fname, char *header)
{

  fitsfile  *fptr;         
  int       status = 0;  /* MUST initialize status */
  int       datanum = 1024*1024;
  long      fpixel[2] = {1, 1};
  int       slen;
  char      suffix[4];

  slen = strlen(fname);
  slen = slen - 3;
  memcpy(suffix, fname+slen, 3);  suffix[3]='\0';
  if(strcmp(suffix, ".fz") == 0 || strcmp(suffix, ".ic") == 0){
    strcat(fname, "[1]");
  }

  fits_open_file(&fptr, fname, READONLY, &status);
  fits_read_pix(fptr, TSHORT, fpixel, datanum, NULL, data, NULL, &status); 
  fits_close_file(fptr, &status);

  if (status)          /* print any error messages */
    printf("%s\n", fname);
    fits_report_error(stderr, status);
  return(status);
  
}



