#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <fitsio.h>
#include "./qcksort.c"
#include "./qckisort.c"
#include "./getmedf.c"
#include "./getmedi.c"

/*

exslopefz.c
gcc -O2 -o exslopefz exslopefz.c -lcfitsio -lm

*/


int  readfz(short data[], char *fname);
float getdev(float mbox[], int mnum, float *med);
float getmeds(short mbox[], int mnum);

int main (int argc, char**argv)
{
    short   *data1,*data2;
    int     *data3,*mbox;
    float   *ldata,*sdata;
    int     i,xynum=1048576;
    int     j,k;
    char    fname1[80],fname2[80];
    float   midpt,midpt1,midpt2,midpt3,stdev;
    int     onum;
    int     fzstat;


    if (argc < 3){
      fprintf(stderr, "usage : exslopefz frame1 frame2\n");
      return 0;
    }
    sprintf(fname1,argv[1]);
    sprintf(fname2,argv[2]);

    /*
    read the FITS data
    */
    data1=(short*)malloc(xynum*sizeof(short));
    data2=(short*)malloc(xynum*sizeof(short));

    fzstat=readfz(data1,fname1);
    if(fzstat==1){
      return 1;
    }

    fzstat=readfz(data2,fname2);
    if(fzstat==1){
      return 1;
    }

    midpt1=getmeds(data1,xynum);
    midpt2=getmeds(data2,xynum);

    if(midpt2>8000 || midpt1>8000){
       free(data1);
       free(data2);
       return 0;
    }

    data3=(int*)malloc(xynum*sizeof(int));
    if(midpt1<midpt2){
      for (i=0; i<xynum; i++){
	data3[i]=data2[i]-data1[i];
      }
      midpt3=midpt2-midpt1;
    } else {
      for (i=0; i<xynum; i++){
	data3[i]=data1[i]-data2[i];
      }
      midpt3=midpt1-midpt2;
    }
    free(data1);
    free(data2);

    ldata=(float*)malloc(200*sizeof(float));
    sdata=(float*)malloc(200*sizeof(float));
    for (j=412; j<612; j++){
       mbox=(int*)malloc(1024*sizeof(int));
       k=0;
       for (i=0; i<xynum; i++){
         if(i%1024==j){
 	   mbox[k]=data3[i]-data3[i-1];
           k++;
         }
       }
       midpt=getmedi(mbox,1024,-10000,10000);
       ldata[j-412]=midpt/midpt3;
       sdata[j-412]=midpt/midpt3;
       free(mbox);
    }
    free(data3);

    midpt=getmedf(sdata,200,-10000,10000);
    free(sdata);
    stdev=getdev(ldata,200,&midpt);

    /*    printf("%.3f %.3f\n", fabs(ldata[100]-midpt),stdev);  */

    if(fabs(ldata[100]-midpt)<3*stdev || fabs(ldata[100]-midpt)<=0.010){
      onum=1;
    } else {
      onum=0;
    }

    printf("%d\n", onum);

    free(ldata);

    return 0;

}


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

  fitsfile  *fptr;         
  int       status = 0;  /* MUST initialize status */
  long      datanum=1024*1024;
  long      fpixel[2]={1,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 */
    fits_report_error(stderr, status);
  return(status);

}


float getmeds(short obox[], int mnum)
{

  int   i,j,k,cnum;
  float med,rms;
  int   *mbox,*clip,*iclip;

  mbox=(int*)malloc(mnum*sizeof(int));
  for(i=0; i<mnum; i++){
    mbox[i]=obox[i];
  }
  qckisort(mbox,0,mnum-1);
  if(mnum%2==0){
    med=0.5*(mbox[mnum/2-1]+mbox[mnum/2]);
  }else{
    med=mbox[mnum/2];
  }

  rms=0;
  for(i=0; i<mnum; i++){
    rms=rms+(mbox[i]-med)*(mbox[i]-med);
  }
  rms=sqrt(rms/mnum);

  for(k=0; k<5; k++){

    cnum=0;
    iclip=(int*)malloc(mnum*sizeof(int));
    for(i=0; i<mnum; i++){
      if(fabs(mbox[i]-med)<3*rms){
        iclip[i]=1;
        cnum++;
      } else {
	iclip[i]=0;
      }
    }

    if(cnum>0){
      clip=(int*)malloc(cnum*sizeof(int));
      j=0;
      for(i=0; i<mnum; i++){
        if(iclip[i]==1){
          clip[j]=mbox[i];
          j++;
        }  
      }
      if(cnum%2==0){
        med=0.5*(clip[cnum/2-1]+clip[cnum/2]);
      }else{
        med=clip[cnum/2];
      }
      rms=0;
      for(i=0; i<cnum; i++){
        rms=rms+(clip[i]-med)*(clip[i]-med);
      }
      rms=sqrt(rms/cnum);
      free(clip);
      free(iclip);
    } else {
      med=-9999;
      rms=-99;
      free(iclip);
      break;
    }
  }

  free(mbox);

  return med;

}


float getdev(float mbox[], int mnum, float *med)
{
  int i;
  float rrr,aaa;

  aaa=*med;
  rrr=0.0;
  for (i=0; i<mnum; i++){
    rrr=rrr+((mbox[i]-aaa)*(mbox[i]-aaa));
  }
  rrr=sqrt(rrr/mnum);

  return rrr;
  
}

