#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "types.h"

int inpflag = 1; /* 0/1. In case I want to make this an input parameter later */


main(argc, argv)
int argc;
char **argv;
{
  char *base, *infile, *outfile, header[500], *mapfile;
  element ***map;
  imagetype **im;
  int w,h,K,scale, tlen, printcurve, *Xoffset, *Yoffset, *xs,*ys,*ks,*neighs,num;
  int n_active, w2,h2, n_curves;
  double *sals;
  short ***bmap;
  void basename(), write_image(), free_map(), set_xy_offset(), init_image(), top_curves();
  void read_sal_input_file(), read_sal_input_file_wh(), read_sal_input_file_whKs();
  void ifree(), iiifree(), elt_list_to_map(), make_bmap(), init_bmap();
  char **ialloc();

  if(argc == 1) { /* no args given */
    basename(&base,argv[0]);
    fprintf(stderr,"usage: %s infile outfile num_curves tlen printcurve [mapfile]\n",
	    base);
    exit(0);
  }
  infile = argv[1];
  outfile = argv[2];
  n_curves = atoi(argv[3]);
  tlen = atoi(argv[4]);
  printcurve = atoi(argv[5]);
  mapfile = argc > 6 ? argv[6] : (char *) NULL;

  printf(" n_curves=%d tlen=%d printcurve=%d\n", n_curves,tlen,printcurve);
  read_sal_input_file_whKs(infile, &xs,&ys,&ks,&sals,&neighs, &num, &w, &h, &K, &scale);
  set_xy_offset(&Xoffset,&Yoffset, K, scale);
  elt_list_to_map(&map, xs,ys,ks,sals,neighs,num, w,h,K);
  free(xs); free(ys); free(ks); free(sals); free(neighs);

  if(mapfile == (char *) NULL) { /* no mapfile specified */
    make_bmap(&bmap,w,h,K, 1); /* set all elements to active */
    n_active = -1; }
  else {                       /* read active elements from mapfile */
    if(inpflag == 0)
      read_sal_input_file(mapfile, &xs, &ys, &ks, &sals, &neighs, &n_active);
    else {
      read_sal_input_file_wh(mapfile, &xs, &ys, &ks, &sals, &neighs, &n_active, &w2, &h2);
      if(!(w == w2 && h == h2))
	fprintf(stderr, "Warning: Map dimensions (%d %d) different from image (%d %d)\n",
		w2, h2, w, h); }
    init_bmap(&bmap,w,h,K, xs,ys,ks,n_active);
    free(xs); free(ys); free(ks);
    if(sals != (double *) NULL) free(sals); if(neighs != (int *) NULL) free(neighs);
  }

  im = (imagetype **) ialloc(w,h,sizeof(imagetype));
  init_image(im, w,h);
  printf("Finding the most salient curves...\n");
  top_curves(im, map,bmap,w,h,K, tlen, printcurve, n_curves, Xoffset,Yoffset);

  printf("Writing image...\n");
  sprintf(header, "(* infile=%s outfile=%s mapfile=%s num=%d n_active=%d w=%d h=%d K=%d scale=%d n_curves=%d tlen=%d printcurve=%d *)\n", infile, outfile, mapfile, num, n_active, w, h, K, scale, n_curves, tlen, printcurve);
  write_image(im, outfile, w, h, header);

  free_map(map); iiifree((char ***)bmap); ifree((char **)im);
}


void
make_bmap(bmap,w,h,K, initial_val)
short ****bmap, initial_val;
int w,h,K;
{
  int i;
  short *bvec;

  char ***iiialloc();

  *bmap = (short ***) iiialloc(w,h,K,sizeof(short));
  bvec = ***bmap;

  for(i = 0; i < w*h*K; i++)
    *bvec++ = initial_val;
}


/* bmap = 1 for the active elements
 */
void
init_bmap(bmap,w,h,K, xs,ys,ks,n)
short ****bmap;
int w,h,K, *xs,*ys,*ks,n;
{
  int i;
  void make_bmap();

  make_bmap(bmap,w,h,K,0);
  for(i=0; i<n; i++)
    (*bmap)[xs[i]][ys[i]][ks[i]] = 1;
}


/* bmap tells which elements are active
 */
void
most_salient_active_element(mx,my,mk, map,bmap, w,h,K)
int *mx,*my,*mk, w,h,K;
element ***map;
short ***bmap;
{
  int x,y,k;
  real sal;

  sal = -1.; *mx = *my = *mk = -1;
  for(x=0;x<w;x++) for(y=0;y<h;y++) for(k=0;k<K;k++) /* run through elements */
    if(bmap[x][y][k] && map[x][y][k].sal > sal) {
      sal = map[x][y][k].sal; *mx = x; *my = y; *mk = k; }
  printf(" Max saliency=%f  Element=(%d,%d,%d)\n", sal, *mx,*my,*mk);
}


void
top_curves(im, map,bmap,w,h,K, tlen, printcurve, n, Xoffset,Yoffset)
imagetype **im;
element ***map;
int w,h,K, tlen, printcurve, n, *Xoffset,*Yoffset;
short ***bmap;
{
  int mx,my,mk, i;
  void most_salient_active_element(), trace_curve_bmap();

  for(i=0; i<n; i++) {
    most_salient_active_element(&mx,&my,&mk, map,bmap, w,h,K);
    if(mx == -1) break; /* no active elements */
    trace_curve_bmap(im, mx,my,mk, tlen, map,bmap, w,h,K, printcurve, Xoffset,Yoffset);
  }
}
