#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#include "boolean.h"
#include "file.h"
#include "matched.h"
#include "thdrad.h"
#include "fitsio.h"


void usage(void);
Boolean check_input(int argc, char *argv[], char *fits, char *input, double *crval);
void coef_sec2deg(double *coef);
void calc_cd_crpix(double *coef,double *cd,double *crpix);
void put_wcs_header(char *fits, double *cd,double *crpix,double *crval);

int main(int argc, char *argv[]){
   double cd[4], crpix[2], crval[2], coef[6];
   char input[FILE_LENGTH], fits[FILE_LENGTH];
   if(check_input(argc,argv,fits,input,crval)!=TRUE) usage();
   if(read_matched_coef(input,coef)!=TRUE){
      fprintf(stderr,"Failed to load transformation coefficients from %s\n",input); exit(1);
   }
   coef_sec2deg(coef);
   calc_cd_crpix(coef,cd,crpix);
   put_wcs_header(fits,cd,crpix,crval);
   return 0;
}

void usage(void){
   fprintf(stderr,"Usage -> make_wcs_header  fitsname  matched_file  RA  Dec\n");
   fprintf(stderr,"   fitsname : the name of input fits file\n");
   fprintf(stderr,"   matched_file : the name of output file of OPM\n");
   fprintf(stderr,"   RA/Dec : the reference equatorial coordinate\n");
   exit(1);
}

Boolean check_input(int argc, char *argv[], char *fits, char *input, double *crval){
   double alpha, delta;
   if(argc!=5) return FALSE;
   strcpy(fits,argv[1]);
   strcpy(input,argv[2]);
   if(file_exist(input)!=TRUE) return FALSE;
   if(strstr(argv[3],":")!=NULL){
      alpha_delta(argv[3],argv[4],&alpha,&delta);
      crval[0]=alpha*(180/M_PI);
      crval[1]=delta*(180/M_PI);
   } else {
      crval[0]=atof(argv[3]);
      crval[1]=atof(argv[4]);
   }
   if(crval[0]<-180||crval[0]>360||crval[1]<-90||crval[1]>90){
      fprintf(stderr,"RA and Dec is out of range! (crval[0]=%.1f crval[1]=%.1f)\n",crval[0],crval[1]);
      return FALSE;
   }
   return TRUE;
}

void coef_sec2deg(double *coef){
   int i;
   for(i=0;i<6;i++) coef[i]/=(60.0*60);
}

void calc_cd_crpix(double *coef,double *cd,double *crpix){
   cd[0]=coef[0];
   cd[1]=coef[1];
   cd[2]=coef[3];
   cd[3]=coef[4];
   crpix[0]=(coef[1]*coef[5]-coef[2]*coef[4])/(coef[0]*coef[4]-coef[1]*coef[3]);
   crpix[1]=(coef[0]*coef[5]-coef[2]*coef[3])/(coef[1]*coef[3]-coef[0]*coef[4]);
}

void put_wcs_header(char *fits, double *cd,double *crpix,double *crval){
   int stat, wcsaxes;
   fitsfile *fptr;
   double lonpole;
   stat=0;
   fits_open_file(&fptr,fits,READWRITE,&stat);
   if(stat) fits_report_error(stderr,stat);
   wcsaxes=2;
   fits_update_key(fptr,TINT,"WCSAXES",&wcsaxes,NULL,&stat);
   lonpole=180;
   fits_update_key(fptr,TSTRING,"CTYPE1","RA---TAN",NULL,&stat);
   fits_update_key(fptr,TSTRING,"CTYPE2","DEC--TAN",NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"CRPIX1",crpix,NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"CRPIX2",crpix+1,NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"CD1_1",cd,NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"CD1_2",cd+1,NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"CD2_1",cd+2,NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"CD2_2",cd+3,NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"LONPOLE",&lonpole,NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"CRVAL1",crval,NULL,&stat);
   fits_update_key(fptr,TDOUBLE,"CRVAL2",crval+1,NULL,&stat);
   fits_update_key(fptr,TSTRING,"CUNIT1","deg     ",NULL,&stat);
   fits_update_key(fptr,TSTRING,"CUNIT2","deg     ",NULL,&stat);
   if(stat) fits_report_error(stderr,stat);
   fits_close_file(fptr,&stat);
   if(stat) fits_report_error(stderr,stat);
}

