//****************************************************************************
// File: Rinsert.cc
//****************************************************************************

#include <std.h>
#include <math.h>
#include <sys/file.h>

extern "C" {
#include <sys/mman.h>

int munmap(char *, long);
}

#include "rtree.h"

void insert_objects(r_tree *t, char *data, long datasize);

int	fl= 0;

main(int argc, char **argv)
{
   r_tree *t;
   // object_util *obj_util;

   int fdata, M, m = -1;
   char mapname[NAMELEN], mapdata[NAMELEN];
   char mapdir[NAMELEN];
   char *data;
   long datasize;

   if ((argc < 2) || (argc > 5)) {
      fprintf(stderr, "Usage: %s mapname [M [m]]\n", argv[0]);
      exit(1);
   } else {
      if (strcmp(argv[1], "-f") == 0) {
	fl= 1;
	argc--;
	argv++;
      }
      strcpy(mapdir, getenv("map") ? getenv("map"): ".");
      strcpy(mapname, mapdir);
      strcat(mapname, "/");
      strcat(mapname, argv[1]);

      switch (argc) {
      case 2:
	 M = MAX;
	 break;
      case 3:
	 if (sscanf(argv[2], "%d", &M) == 0) {
	    fprintf(stderr, "argument 2 : no integer\n");
	    exit(1);
	 }
	 break;
      case 4:
	 if (sscanf(argv[2], "%d", &M) == 0) {
	    fprintf(stderr, "argument 2 : no integer\n");
	    exit(1);
	 }
	 if (sscanf(argv[3], "%d", &m) == 0) {
	    fprintf(stderr, "argument 3 : no integer\n");
	    exit(1);
	 }
	 break;
      }
      if (m == -1)
	 m = (int) ceil((double) ((double) M / (double) 2.0));
   }
   strcpy(mapdata, mapname);
   strcat(mapdata, ".bin");
   if ((fdata = open(mapdata, O_RDONLY)) == -1) {
      fprintf(stderr, "Map data file can't be opened.\n");
      exit(1);
   }
   datasize=lseek(fdata,0L,L_XTND);
   if ((data =(char *)mmap(0,datasize, PROT_READ, MAP_SHARED, fdata, 0))
           == (char *)-1) {
      fprintf(stderr, "Map data file can't be mapped.\n");
      exit(1);
   }

   if ((t = new r_tree(mapname, m, M)) == NULL) {
      fprintf(stderr, "main: Out of memory.\n");
      exit(1);
   }
   t->print_rtree_info();
   t->printstat();
   // obj_util = new object_util(data, datasize);
   // obj_util->insert_objects(t);
   insert_objects(t, data, datasize);
   munmap(data, datasize);
   close(fdata);
   t->print_rtree_info();
   t->printstat();
   delete t;
   // delete obj_util;
}


const int	MAX_POLY= 10000;

void insert_objects(r_tree *t, char *data, long datasize)
{
  char			*end= data+datasize;
  short			*p= (short*) data;
  register int		x, y;
  int			npoint;
  int			i;
  point			points[MAX_POLY];
  object_type		obj;
  r_entry		temp;
  geometr		geom;

  obj.pts= points;
  obj.type= area;

  for (; ((char*)p) <end;) {
	temp.id= (long) ((char*)p-data);
	if (fl) {
	  p++; p++; npoint= *(long*)p; p++; p++;
	} else {
	  p++; npoint= *(short*)p; p++;
	}
// printf("npoint: %d\n", npoint);
	if ((obj.nrofpoints= npoint) >= MAX_POLY) {
		fprintf(stderr, "Too may points\n");
		exit(1);
	}
	for (i= 0; i < npoint; i++) {
	  if (fl) {
	    obj.pts[i][1]= *(float*)p; p++; p++;
	    obj.pts[i][0]= *(float*)p; p++; p++;
	  } else {
	    obj.pts[i][1]= *p / 100.0; p++;
	    obj.pts[i][0]= *p / 100.0; p++;
	  }
	}
	geom.to_rectangle( obj.pts, obj.nrofpoints, temp.mbr);
	t->add_object(temp);
  }
}
