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

#ifndef _WIN32
#include <sys/time.h>
#else
#include <sys/timeb.h>
#endif

#include <PointSet.h>
#include <PointPair.h>

static void usage (char* prog)
{
  ::fprintf (stderr, "Usage: %s [-f filename -n elements -m maxnum -h]\n",
	     prog);
  ::fprintf (stderr, "       filename: a file containing 2 column integers representing points\n");
  ::fprintf (stderr, "       elements: number of random points this program generates\n");
  ::fprintf (stderr, "       maxnum  : maximum number of random points this program handles\n");  
  ::exit (1);
}  

int
main (int argc, char** argv)
{
  PointSet      newset;
  int           elems = 10000;
  int           maxnum = 10000;
  int           i;
  char*         filename = 0;

  i = 1;
  while (i < argc) {
    if (strcmp (argv[i], "-f") == 0) {
      i++;
      if (argv[i][0] == '-')
	usage (argv[0]);
      else {
	filename = new char[strlen (argv[i]) + 1];
	::strcpy (filename, argv[i]);
      }
    }
    else if (strcmp (argv[i], "-n") == 0) {
      i++;
      if (sscanf (argv[i], "%d", &elems) < 1)
	usage (argv[0]);
    }
    else if (strcmp (argv[i], "-m") == 0) {
      i++;
      if (sscanf (argv[i], "%d", &maxnum) < 1)
	usage (argv[0]);
    }
    else {
      i++;
      usage (argv[0]);
    }
    i++;
  }

  if (elems > maxnum) {
    ::fprintf (stderr, "Error: Number of random points (%d) > maximum points (%d)this program allows\n",
	       elems, maxnum);
    usage (argv[0]);
  }

  /* Now everthing is ok */
  if (filename) {
    ::fprintf (stderr, "Creating a point set from %s file\n", filename);
    newset = PointSet::create (filename);
    delete []filename;
  }
  else {
    ::fprintf (stderr, "Creating a point set with %d elements and maximum element value %d\n", 
	       elems, maxnum);
    newset = PointSet::create (maxnum, maxnum, elems);
  }

#ifndef _WIN32
  struct timeval it, ft;
  gettimeofday (&it, 0);
#else
  struct _timeb it, ft;
  _ftime (&it);
#endif

  printf ("Find closest points using brute force\n");
  PointPairSet cset0 = newset.closestPointBF ();

#ifndef _WIN32
  gettimeofday (&ft, 0);
  double dt = ft.tv_sec - it.tv_sec + (ft.tv_usec - it.tv_usec)/1000000.0;
#else
  _ftime (&ft);
  double dt =  ft.time - it.time + (ft.millitm - it.millitm)/1000000.0;
#endif
  printf ("Time spent by brute-force is %lf\n", dt);

  cout << cset0;

  printf ("Find closest points by divide and conquer\n");
  PointPairSet cset1;

#ifndef _WIN32
  gettimeofday (&it, 0);
#else
  _ftime (&it);
#endif
  cset1 = newset.closestPointDC ();

#ifndef _WIN32
  gettimeofday (&ft, 0);
  dt = ft.tv_sec - it.tv_sec + (ft.tv_usec - it.tv_usec)/1000000.0;
#else
  _ftime (&ft);
  dt = ft.time - it.time + (ft.millitm - it.millitm)/1000000.0;
#endif
  ::printf ("Time spent by divide and conquer is %lf\n", dt);

  cout << cset1;

  if (cset0 == cset1) 
    fprintf (stderr, "Two methods produced the same result\n");
  else
    fprintf (stderr, "Error: results are different\n");
  return 0;
}

  

  
