/**
* Copyright 2005-2007 ECMWF
*
* Licensed under the GNU Lesser General Public License which
* incorporates the terms and conditions of version 3 of the GNU
* General Public License.
* See LICENSE and gpl-3.0.txt for details.
*/

/*
 * C Implementation: points
 *
 *
 *
 * Author: Enrico Fucile <enrico.fucile@ecmwf.int>
 *
 *
 */

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

#include "grib_api.h"

void usage(char* prog) {
  printf("Usage: %s latlon_file grib_orography grib_file grib_file ...\n",prog);
  exit(1);
}

int main(int argc, char** argv) {
  FILE* fin=0;
  int ret=0;
  char* fname=0;
  float lat,lon;
  double *vlat,*vlon;
  int npoints=0,i=0,n=0;
  grib_handle* h;
  double *outlats,*outlons,*values,*lsm_values,*distances;
  int* indexes;
  long step=0;
  char time[10]={0,};
  char date[10]={0,};
  long parameter=0;
  size_t len=0;
  long iid=0;
  long *id=NULL;

  if (argc < 2) usage(argv[0]);

  fname=argv[1];
  fin=fopen(fname,"r");
  if(!fin) { perror(fname); exit(1); }
  npoints=0;
  while (fscanf(fin,"%ld %g %g",&iid,&lat,&lon) != EOF) npoints++;
  fclose(fin);

  id=(long*)malloc(npoints*sizeof(long));
  if (!id) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(long)));exit(1);}
  vlat=(double*)malloc(npoints*sizeof(double));
  if (!vlat) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(double)));exit(1);}
  vlon=(double*)malloc(npoints*sizeof(double));
  if (!vlon) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(double)));exit(1);}
  outlats=(double*)malloc(npoints*sizeof(double));
  if (!outlats) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(double)));exit(1);}
  outlons=(double*)malloc(npoints*sizeof(double));
  if (!outlons) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(double)));exit(1);}
  values=(double*)malloc(npoints*sizeof(double));
  if (!values) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(double)));exit(1);}
  lsm_values=(double*)malloc(npoints*sizeof(double));
  if (!lsm_values) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(double)));exit(1);}
  distances=(double*)malloc(npoints*sizeof(double));
  if (!distances) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(double)));exit(1);}
  indexes=(int*)malloc(npoints*sizeof(int));
  if (!indexes) {printf("unable to allocate %ld bytes\n",(long)(npoints*sizeof(double)));exit(1);}

  fname=argv[1];
  fin=fopen(fname,"r");
  if(!fin) { perror(fname); exit(1); }
  i=0;
  while (fscanf(fin,"%ld %g %g",&iid,&lat,&lon) != EOF) {
    id[i]=iid;vlat[i]=lat;
	while(lon < 0) lon+=360;
    vlon[i]=lon;
    i++;
  }
  fclose(fin);

  fname=argv[2];
  fin=fopen(fname,"r");
  if(!fin) { perror(fname); exit(1); }
  h=grib_handle_new_from_file(0,fin,&ret);
  if (!h || ret!=GRIB_SUCCESS) {printf(" unable to create handle\n");exit(1);}

  grib_nearest_find_multiple(h,1,vlat,vlon,npoints,
        outlats,outlons,lsm_values,distances,indexes);

  grib_handle_delete(h);

  fclose(fin);

  for (n=3;n<=argc-1;n++) {
    fname=argv[n];
    fin=fopen(fname,"r");
    if(!fin) { perror(fname); exit(1); }
    while ((h=grib_handle_new_from_file(0,fin,&ret))!=NULL) {
       grib_get_double_elements(h,"values",indexes,npoints,values);

       len=10;
       grib_get_string(h,"date",date,&len);
       len=10;
       grib_get_string(h,"time",time,&len);
       grib_get_long(h,"step",&step);
       grib_get_long(h,"parameter",&parameter);

       printf("# %s %s %ld %ld\n",date,time,step,parameter);
       grib_handle_delete(h);
       for (i=0;i<npoints;i++)
          printf("%ld %g %g %g %g\n",
            id[i],outlats[i],outlons[i],
            lsm_values[i],values[i]);
    }

    fclose(fin);
  }



  return ret;
}