#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "original_data.h"
#include "file.h"
#include "treematch.h"
#include "matched.h"
#include "verification.h"

static original_data read_new_original(char *line);
static void print_matched_original(FILE *fp, matched match, original_data q2);

original_data *load_original_data(char *file, int *num){
   FILE *fp;
   int nline,  iline, ndata;
   char line[LINE_LENGTH];
   original_data *data;
   if((nline=file_nline(file))<1){
      *num=0; return NULL;
   }
   data=malloc(nline*sizeof(xym));
   fp=fileopen(file,"r");
   ndata=0; iline=0;
   while(!feof(fp)){
      fgets(line,sizeof(line),fp);
      ++iline;
      if(comment_line(line)==TRUE||feof(fp)) continue;
      if((data[ndata]=read_new_original(line))!=NULL) ++ndata;
   }
   fclose(fp);
   *num=ndata;
   return data;
   
}

static original_data read_new_original(char *line){
   int i;
   original_data p;
   char id[30], flag[3];
   double x, y, mag[3], merr[3];
   if(sscanf(line,"%s %lf %lf %lf %lf %lf %lf %lf %lf %c%c%c",id,&x,&y,mag,merr,mag+1,merr+1,mag+2,merr+2,flag,flag+1,flag+2)!=12) return NULL;
   p=malloc(sizeof(struct _original_data));
   strcpy(p->id,id);
   p->x=x; p->y=y;
   for(i=0;i<3;i++){
      p->mag[i]=mag[i]; p->merr[i]=merr[i]; p->flag[i]=flag[i];
   }
   return p;
}

void destroy_original_data(int ndata, original_data *data){
   int i;
   for(i=0;i<ndata;i++) free(data[i]);
   free(data); data=NULL;
}

xym *set_original_xym(int ndata, original_data *data){
   int i;
   double x, y, m;
   xym *array;
   array=malloc(ndata*sizeof(xym));
   for(i=0;i<ndata;i++){
      array[i]=malloc_xym();
      x=data[i]->x; y=data[i]->y; m=data[i]->mag[2];
      set_xym(array[i],i,x,y,m,(void *)data[i]);
   }
   return array;
}

original_data get_xym_original_data(xym p){
   return ((original_data)get_xym_data(p));
}

int output_matched_result_original(FILE *flog, char *output, int nobj, xym *data_obj, int nref, xym *data_ref, double *coef, opm_param *setting){
   FILE *fp;
   int i, num, num1, flag;
   double radius, xcen, ycen, size;
   Leaf *ref, *obj, target;
   matched match;
   xym p, q;
   original_data p2;
   fp=fileopen(output,"w");
   radius=get_opm_radius(setting);
   xcen=get_opm_xcen(setting);
   ycen=get_opm_ycen(setting);
   size=get_opm_size(setting);
   print_opm_param(fp,setting);
   print_output_coef(fp,coef);
   obj=make_leaf(nobj,data_obj);
   ref=make_leaf(nref,data_ref);
   make_treematch(nobj,obj,nref,ref,xcen,ycen,size,radius);
   match=malloc_matched();
   for(i=0,num=0,num1=0;i<nref;i++){
      if((target=ref[i]->adopted)==NULL) continue;
      p=(xym)(ref[i]->data);
      q=(xym)((ref[i]->match[0])->data);
      p2=get_xym_original_data(p);
      if(ref[i]->nmatch==1&&ref[i]->match[0]->nmatch==1) flag=MATCHED_SINGLE;
      else { flag=MATCHED_MULTI; ++num1; }
      xym_to_matched(q,p,flag,match);
      print_matched_original(fp,match,p2);
      ++num;
   }
   if(flog!=NULL){
      fprintf(flog,"# %d matches found (nobj=%d nref=%d).\n",num,nobj,nref);
      fprintf(flog,"#     flag=%d: %d,   flag=%d: %d\n",MATCHED_SINGLE,(num-num1),MATCHED_MULTI,num1);
   }
   fclose(fp);
   free(match);
   for(i=0;i<nobj;i++) free(obj[i]);
   for(i=0;i<nref;i++) free(ref[i]);
   free(obj); free(ref);
   return num;
}

static void print_matched_original(FILE *fp, matched match, original_data q2){
   fprintf(fp,"%6d %10.3f %10.3f %7.3f %7.3f %7.3f %10.3f  %d\n",get_matched_id2(match),q2->x,q2->y,q2->mag[0],q2->mag[1],q2->mag[2],get_matched_m1(match),get_matched_flag(match));
}
