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

#include "file.h"
#include "graphics.h"
#include "matched.h"

#ifndef NBIN0
#define NBIN0 15
#endif
#define NBIN (NBIN0*2+1)

void usage(void);
void set_windows(double dmin, double dmax, double dtic, double Nmin, double Nmax, double Ntic);
void make_xyfile(char *input, char *output, int xcol1, int ycol1, int xcol2, int ycol2);
void count_delta(int ndata, double *delta, int *N);
int get_pos(double dx);
void make_xbin(double *xbin);
void make_ybin(int *N, double *ybin);
double get_Nmax(int *dxN,int *dyN);

double binsize ;

int main(int argc, char *argv[]){
   int i, ndata, symbol, dxN[NBIN], dyN[NBIN];
   double *dx, *dy, xbin[NBIN], ybin[NBIN];
   double dmax, dmin, dtic, Nmax, Nmin, Ntic, halfsize;
   float xp, yp;
   matched *data;
   if(argc!=3) usage();
   if((halfsize=atof(argv[2]))<=0) usage();
   binsize=halfsize*(2.0/NBIN);
   for(i=0;i<NBIN;i++){
      dxN[i]=0; dyN[i]=0; xbin[i]=0; ybin[i]=0;
   }
   if((data=load_matched(argv[1],&ndata))==NULL){
      fprintf(stderr,"Failed to load matched from %s\n",argv[1]); exit(1);
   }
   dx=malloc(ndata*sizeof(double));
   dy=malloc(ndata*sizeof(double));
   get_matched_dxdy(ndata,data,dx,dy);
   count_delta(ndata,dx,dxN);
   count_delta(ndata,dy,dyN);
   dmin=-1.1*halfsize; dmax=1.1*halfsize; frametic(3,&dmax,&dmin,&dtic);
   Nmin=0; Nmax=get_Nmax(dxN,dyN);
   frametic(2,&Nmax,&Nmin,&Ntic);
   cpgstart("?",9.0,0.5);
   set_windows(dmin,dmax,dtic,Nmin,Nmax,Ntic);
   window(0);
   for(i=0;i<ndata;i++){
      if(get_matched_flag(data[i])==MATCHED_SINGLE) symbol=17;
      else symbol=5;
      xp=dx[i]; yp=dy[i]; cpgpt(1,&xp,&yp,symbol);
   }
   make_xbin(xbin);
   window(1);
   make_ybin(dxN,ybin);
   plot_histogram(NBIN,xbin,ybin);
   window(2);
   make_ybin(dyN,ybin);
   plot_histogram(NBIN,xbin,ybin);
   free(dx); free(dy);
   cpgfinish() ; 
   return 0 ; 
}

void usage(void){
   fprintf(stderr,"Usage -> plot_dxdy  matched_file  halfsize\n");
   exit(1);
}

void set_windows(double dmin, double dmax, double dtic, double Nmin, double Nmax, double Ntic){
   int nwin;
   double vpx0[3]={ 0.15, 0.48, 0.74 }, vpx1[3]={ 0.40, 0.72, 0.98 };
   double vpy0[3]={ 0.30, 0.20, 0.20 }, vpy1[3]={ 0.80, 0.90, 0.90 };
   char xlabel[3][50]={ "x\\dobj\\u-x\\dref\\u", "x\\dobj\\u-x\\dref\\u", "y\\dobj\\u-y\\dref\\u" };
   char ylabel[3][50]={ "y\\dobj\\u-y\\dref\\u", "N", "" };
   for(nwin=0;nwin<3;nwin++){
      setvp(nwin,vpx0[nwin], vpx1[nwin], vpy0[nwin], vpy1[nwin]);
      if(nwin==0){
         setwin(nwin, dmin, dmax, dmin, dmax);
         set_tic(nwin,AXIS_Y_LEFT,dmin,dmax,dtic,FORMAT_G);
         set_tic(nwin,AXIS_Y_RIGHT,dmin,dmax,dtic,FORMAT_G);
         change_tic_off(nwin,AXIS_X_LOW,-0.07);
         change_tic_off(nwin,AXIS_Y_LEFT,-0.02);
         change_axis_lab_off(nwin,AXIS_X_LOW,-0.14);
         change_axis_lab_off(nwin,AXIS_Y_LEFT,-0.20);
      } else {
         setwin(nwin, dmin, dmax, Nmin, Nmax);
         set_tic(nwin,AXIS_Y_LEFT,Nmin,Nmax,Ntic,FORMAT_G);
         set_tic(nwin,AXIS_Y_RIGHT,Nmin,Nmax,Ntic,FORMAT_G);
         change_tic_off(nwin,AXIS_X_LOW,-0.05);
         change_tic_off(nwin,AXIS_Y_LEFT,-0.02);
         change_axis_lab_off(nwin,AXIS_X_LOW,-0.10);
         change_axis_lab_off(nwin,AXIS_Y_LEFT,-0.24);
         if(nwin==2) change_tic_lab_flag(nwin,AXIS_Y_LEFT,FALSE);
      }
      set_tic(nwin,AXIS_X_LOW,dmin,dmax,dtic,FORMAT_G);
      set_tic(nwin,AXIS_X_UP,dmin,dmax,dtic,FORMAT_G);
      change_tic_lab_flag(nwin,AXIS_X_UP,FALSE);
      set_axis_label(nwin,AXIS_X_LOW,xlabel[nwin]);
      set_axis_label(nwin,AXIS_Y_LEFT,ylabel[nwin]);
      change_tic_lab_flag(nwin,AXIS_Y_RIGHT,FALSE);
      change_tic_ch_lw(nwin,AXIS_X_LOW,1.5,1);
      change_tic_ch_lw(nwin,AXIS_Y_LEFT,1.5,1);
      change_axis_lab_ch_lw(nwin,AXIS_X_LOW,1.5,1);
      change_axis_lab_ch_lw(nwin,AXIS_Y_LEFT,1.5,1);
      mkframe(nwin);
   }
}

void make_xyfile(char *input, char *output, int xcol1, int ycol1, int xcol2, int ycol2){
   char command[3*FILE_LENGTH];
   sprintf(command,"awk '{print $%d,$%d,$%d,$%d}' %s > %s\n",xcol1,ycol1,xcol2,ycol2,input,output);
   system(command);
}

void count_delta(int ndata, double *delta, int *N){
   int i, pos;
   for(i=0;i<ndata;i++){
      if((pos=get_pos(delta[i]))>=0) N[pos]+=1;
   }
}

int get_pos(double dx){
   int xpos;
   //xpos=floor((dx+NBIN0*binsize)/binsize);
   xpos=floor((dx+NBIN0*binsize)/binsize+0.5);
   //fprintf(stderr,"dx=%.2f xpos=%d\n",dx,xpos);
   if(xpos<0||xpos>=NBIN) xpos=-1;
   return xpos;
}

void make_xbin(double *xbin){
   int i;
   for(i=0;i<NBIN;i++) xbin[i]=binsize*(i-NBIN0);
}

void make_ybin(int *N, double *ybin){
   int i;
   for(i=0;i<NBIN;i++) ybin[i]=(double)N[i];
}

double get_Nmax(int *dxN,int *dyN){
   int i;
   double max;
   for(i=0,max=0;i<NBIN;i++){
      if(max<dxN[i]) max=dxN[i];
      if(max<dyN[i]) max=dyN[i];
   }
   return max;
}
