#ifndef lint
static char rcsid [] = "$RCSfile$ $Revision$ $State$";
#endif
/****************************************************************************
*   File: test.c                                                            *
*                                                                           *
*       Copyright 1994 by Loral Advanced Distributed Simulation, Inc.       *
*                                                                           *
*               Loral Advanced Distributed Simulation, Inc.                 *
*               10 Moulton Street                                           *
*               Cambridge, MA 02238                                         *
*               617-873-1850                                                *
*                                                                           *
*       This software was developed by Loral under U. S. Government contracts*
*       and may be reproduced by or for the U. S. Government pursuant to    *
*       the copyright license under the clause at DFARS 252.227-7013        *
*       (OCT 1988).                                                         *
*                                                                           *
*       Contents: Test program for libroutemap                              *
*       Created: Mon Feb 28 1994                                            *
*       Author: jesmith                                                     *
*       Remarks:                                                            *
*                                                                           *
****************************************************************************/

#include "librtmp_local.h"

#include "/usr/modsaf/common/libsrc/libtactmap/libtactmap.h"
#include "/usr/modsaf/common/libsrc/libctdb/libctdb.h"
#include "/usr/modsaf/common/libsrc/libsensitive/libsensitive.h"
#include "/usr/modsaf/common/libsrc/libcoordinates/libcoordinates.h"
#include "/usr/modsaf/common/libsrc/librandom/librandom.h"
#include "/usr/modsaf/common/libsrc/libreader/libreader.h"
#include "/usr/modsaf/common/libsrc/librdrconst/librdrconst.h"
#include "/usr/modsaf/common/libsrc/libbgr/libbgr.h"
#include <unit_type.h>
#include <veh_type.h>
#include <math.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <stdext.h> /*common/include/global*/

/* These indicate whether to draw various information */
#define SHOW_CONNECTIVITY 0
#define SHOW_OBSTACLES    1
#define SHOW_BYPASSES     0
#define SHOW_LABELS       0
#define SHOW_INDICES      0
#define SHOW_CORRIDORS    0

/* Indicates what to draw vis-a-vis trees (CANOPIES, LINES, INDIVIDUAL) */
#define TREE_MASK TACTMAP_TREE_CANOPIES;

static CTDB ctdb;
static Widget toplevel;
static TACTMAP_PTR tactmap;
static float64 scale;
static ROUTEMAP_PTR routemap;
static ROUTEMAP_BOUNDARY_PTR left_bound;
static ROUTEMAP_BOUNDARY_PTR right_bound;

static void load_terrain();

static TACTMAP_OBJECT_DFN routedfn;
static TACTMAP_OBJECT_DFN routeboxdfn[200];
static TACTMAP_OBJECT_PTR routeobj;
static TACTMAP_OBJECT_PTR routeboxobj[200];
static float64 routeverts[200];
static float64 routeboxverts[200][10];
static float64 start_x, start_y, end_x, end_y;

#define BOUND_VERTS 4
static struct bound_tmap_data
{
    TACTMAP_OBJECT_DFN dfn;
    TACTMAP_OBJECT_PTR obj;
    float64 verts[2*BOUND_VERTS];
} lb, rb;

static void replan()
{
    ROUTE_POINTS goal, plan;
    ROUTE_POINT  points[2];
    int32 i;
    list *ptr;
    int32 temp;

    goal.num_pts = 2;
    goal.points  = points;
    points[0].point[X] = start_x;
    points[0].point[Y] = start_y;
    points[1].point[X] = end_x;
    points[1].point[Y] = end_y;

    if (!routemap_preplan_constrained(routemap, -1, &goal, 300,
				      0, NULL, left_bound, right_bound,
				      &plan))
      printf("Failed\n");

#if 0
    printf("the points connected to 0 are\n");
    i=0;
    for(ptr=routemap_my_visib_graph->adj[0];ptr!=NULL;ptr=ptr->next)
      {
	printf("%d: %f,%f\n",ptr->element,routemap_my_visib_graph->v[ptr->element].x,routemap_my_visib_graph->v[ptr->element].y);
	routedfn.linear.vertices[i*2] = routemap_my_visib_graph->v[ptr->element].x;
	routedfn.linear.vertices[i*2+1] = routemap_my_visib_graph->v[ptr->element].y;
	i++;
/*	routedfn.linear.vertices[i*2] = routemap_my_visib_graph->v[0].x;
	routedfn.linear.vertices[i*2+1] = routemap_my_visib_graph->v[0].y;
	i++;
*/
      }
    temp=i;

    for (;i<plan.num_pts+temp;i++)
      routedfn.linear.vertices[i*2] = plan.points[i].point[X],
      routedfn.linear.vertices[i*2+1] = plan.points[i].point[Y];

    printf("the points connected to 1 are\n");
    for(ptr=routemap_my_visib_graph->adj[1];ptr!=NULL;ptr=ptr->next)
      {
	printf("%d: %f,%f\n",ptr->element,routemap_my_visib_graph->v[ptr->element].x,routemap_my_visib_graph->v[ptr->element].y);
	routedfn.linear.vertices[i*2] = routemap_my_visib_graph->v[ptr->element].x;
	routedfn.linear.vertices[i*2+1] = routemap_my_visib_graph->v[ptr->element].y;
	i++;
/*	routedfn.linear.vertices[i*2] = routemap_my_visib_graph->v[1].x;
	routedfn.linear.vertices[i*2+1] = routemap_my_visib_graph->v[1].y;
	i++;
*/
      }
    printf("that is all\n\n");
    routedfn.linear.n_vertices = i;

#endif

    /* DRAW ROUTE */
    for (i=0;i<plan.num_pts;i++)
      routedfn.linear.vertices[i*2] = plan.points[i].point[X],
      routedfn.linear.vertices[i*2+1] = plan.points[i].point[Y];
    routedfn.linear.n_vertices = plan.num_pts;
    tactmap_update_object(tactmap, routeobj, &routedfn);
    
    /* DRAW BOXES */
    for (i=0;i<plan.num_pts;i++)
      {
	routeboxdfn[i].linear.vertices[0] = 
	  plan.points[i].point[X] - routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[1] = 
	  plan.points[i].point[Y] - routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[2] = 
	  plan.points[i].point[X] + routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[3] = 
	  plan.points[i].point[Y] - routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[4] = 
	  plan.points[i].point[X] + routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[5] = 
	  plan.points[i].point[Y] + routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[6] = 
	  plan.points[i].point[X] - routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[7] = 
	  plan.points[i].point[Y] + routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[8] = 
	  plan.points[i].point[X] - routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.vertices[9] = 
	  plan.points[i].point[Y] - routemap->extra_width[(int32)(plan.points[i].point[Z])];
	routeboxdfn[i].linear.n_vertices = 5;
	tactmap_update_object(tactmap, routeboxobj[i], &(routeboxdfn[i]));
      }
    for ( ; i<200 ; i++)
      {
	routeboxdfn[i].linear.n_vertices = 0;
	tactmap_update_object(tactmap, routeboxobj[i], &(routeboxdfn[i]));
      }

    STDDEALLOC(plan.points);
}

static void click(window, action, call_data)
    SNSTVE_WINDOW_PTR window;
    SNSTVE_ACTION action;
    SNSTVE_CALL_DATA *call_data;
{
    float64 x, y;
    int32 i;

    if (call_data->button == 1)
    {
	tactmap_screen_to_map(tactmap,
			      call_data->screen_x, call_data->screen_y,
			      &x, &y);

	if (action == SNSTVE_PRESS)
	{
	    start_x = x;
	    start_y = y;
	}
	else
	{
	    end_x = x;
	    end_y = y;
	    replan();
	}

	return;
    }

    if (action == SNSTVE_PRESS)
    {
	tactmap_screen_to_map(tactmap,
			      call_data->screen_x, call_data->screen_y,
			      &x, &y);
	tactmap_set_center(tactmap, (int32)x, (int32)y);
	if (call_data->button == 2)
	  tactmap_set_scale(tactmap, scale*=0.5);
	else if (call_data->button == 3)
	  tactmap_set_scale(tactmap, scale*=2.0);
    }
}

static void bound_gesture(action, call_data, tmap_data, bound)
    SNSTVE_ACTION           action;
    SNSTVE_CALL_DATA       *call_data;
    struct bound_tmap_data *tmap_data;
    ROUTEMAP_BOUNDARY_PTR  *bound;
{
    int32 v;
    float64 dx, dy;
    ROUTE_POINTS pts;
    ROUTE_POINT buf[BOUND_VERTS];
    list *ptr;

    if ((action == SNSTVE_RELEASE) && (call_data->button == 1))
    {
	if (*bound)
	  routemap_free_boundary(*bound);

	v = TACTMAP_INDEX(call_data->instance);
	tactmap_pixel_offset(tactmap,
			     call_data->xoff,
			     call_data->yoff,
			     &dx, &dy);
	if (TACTMAP_IS_VERTEX(call_data->instance))
	{
	    tmap_data->dfn.linear.vertices[v*2] += dx;
	    tmap_data->dfn.linear.vertices[v*2+1] += dy;
	}
	else
	{
	    for(v=0;v<tmap_data->dfn.linear.n_vertices;v++)
	    {
		tmap_data->dfn.linear.vertices[v*2] += dx;
		tmap_data->dfn.linear.vertices[v*2+1] += dy;
	    }
	}
	tactmap_update_object(tactmap, tmap_data->obj, &tmap_data->dfn);

	pts.num_pts = BOUND_VERTS;
	pts.points = buf;
	for (v=0;v<BOUND_VERTS;v++)
	{
	    buf[v].point[X] = tmap_data->verts[2*v];
	    buf[v].point[Y] = tmap_data->verts[2*v+1];
	}
	*bound = routemap_create_boundary(&pts);

	replan();
/*
	printf("the points connected to 0 are\n");
	for(ptr=routemap_my_visib_graph->adj[0];ptr!=NULL;ptr=ptr->next)
	  printf("%d: %f,%f\n",ptr->element,routemap_my_visib_graph->v[ptr->element].x,routemap_my_visib_graph->v[ptr->element].y);
	printf("the points connected to 1 are\n");
	for(ptr=routemap_my_visib_graph->adj[1];ptr!=NULL;ptr=ptr->next)
	  printf("%d: %f,%f\n",ptr->element,routemap_my_visib_graph->v[ptr->element].x,routemap_my_visib_graph->v[ptr->element].y);
	printf("that is all folks\n\n");
*/
    }
}

static void left_gesture(sensitive, action, call_data)
    SNSTVE_WINDOW_PTR sensitive;
    SNSTVE_ACTION action;
    SNSTVE_CALL_DATA *call_data;
{
    bound_gesture(action, call_data, &lb, &left_bound);
}


static void right_gesture(sensitive, action, call_data)
    SNSTVE_WINDOW_PTR sensitive;
    SNSTVE_ACTION action;
    SNSTVE_CALL_DATA *call_data;
{
    bound_gesture(action, call_data, &rb, &right_bound);
}

static void create_bypass(tactmap, dfn, seg, to_obst)
    TACTMAP_PTR         tactmap;
    TACTMAP_OBJECT_DFN *dfn;
    ROUTEMAP_PSEG      *seg;
    ROUTEMAP_OBSTACLE  *to_obst;
{
    TACTMAP_OBJECT_PTR obj;

    if (!to_obst)
      return;

    dfn->linear.n_vertices = 2;
    dfn->linear.vertices[0] = seg->x + 0.5 * seg->dx;
    dfn->linear.vertices[1] = seg->y + 0.5 * seg->dy;
    dfn->linear.vertices[2] = to_obst->center_x;
    dfn->linear.vertices[3] = to_obst->center_y;

    obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, dfn);
    tactmap_add_object(tactmap, obj);
}

/* I added this - oded */
static void draw_visib_graph(routemap, tactmap)
    ROUTEMAP_PTR routemap;
    TACTMAP_PTR  tactmap;
{
  ROUTEMAP_OBSTACLE *obst;
  ROUTEMAP_CORRIDOR *corr, *conn;
  int32 i,j;
  float64 buf[1024][2];
  char charbuf[100];
  TACTMAP_OBJECT_DFN dfn, tdfn;
  TACTMAP_OBJECT_PTR obj;
  SNSTVE_CLASS null_class;
    XGCValues gcv;
  int32 sum;
  GC black, white, red;
  list *ptr2;
  ROUTEMAP_VERT_LIST *ptr;

  gcv.foreground = BlackPixelOfScreen(XtScreen(toplevel));
  black = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
                    GCForeground, &gcv);
  gcv.foreground = WhitePixelOfScreen(XtScreen(toplevel));
  white = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
                    GCForeground, &gcv);

  SNSTVE_INIT_CLASS(null_class);

  bzero(&dfn, sizeof(TACTMAP_OBJECT_DFN));
  dfn.linear.style = LSplain;
  dfn.linear.forward_arrow = 0;
  dfn.linear.thickness = 2;
  dfn.linear.width = 100;
  dfn.linear.gc = white;
  dfn.linear.vertices = (float64 *)buf;
  dfn.sensitive.class = &null_class;
  
  bzero(&tdfn, sizeof(TACTMAP_OBJECT_DFN));
  tdfn.text.gc = black;
  tdfn.text.see_through = 1;
  tdfn.text.string = charbuf;
  tdfn.sensitive.class = &null_class;
  
#if 0
  for (i=2;i<routemap_my_visib_graph->num;i++)
    for (ptr2=routemap_my_visib_graph->adj[i];ptr2!=NULL;ptr2=ptr2->next)
      if (routemap_my_visib_graph->v[i].which_poly!=-1) 
      if ((routemap_my_visib_graph->v[i].radius_num==routemap->num_widths-1) &&
	  (routemap_my_visib_graph->v[ptr2->element].radius_num==routemap->num_widths-1))
      {
	dfn.linear.thickness = 1;
	buf[0][0] = routemap_my_visib_graph->v[i].x;
	buf[0][1] = routemap_my_visib_graph->v[i].y;
	buf[1][0] = routemap_my_visib_graph->v[ptr2->element].x;
	buf[1][1] = routemap_my_visib_graph->v[ptr2->element].y;
	dfn.linear.n_vertices = 2;
	
	obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &dfn);
	tactmap_add_object(tactmap, obj);
      }
#endif
#if 0
  for (j=0;j<routemap->num_y_squares;j+=1)
    for (i=0;i<routemap->num_x_squares;i+=1)
      {
	for (ptr=routemap->squares[i][j].local_points;ptr!=NULL;ptr=ptr->next)
	  {
	    buf[0][0]=ptr->p->x;
	    buf[0][1]=ptr->p->y;
	    buf[1][0]=ptr->p->x;
	    buf[1][1]=ptr->p->y;
	    dfn.linear.thickness=6;
	    dfn.linear.gc = black;
	    obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &dfn);
	    tactmap_add_object(tactmap, obj); 
#if 0
	    if (1) /* (ptr->p->which_poly!=-1) */
	      {
		sprintf(charbuf, "%f,%f", ptr->p->x,ptr->p->y);
		tdfn.text.x = ptr->p->x;
		tdfn.text.y = ptr->p->y;
		obj = tactmap_create_object(tactmap, TACTMAP_TEXT, &tdfn);
		tactmap_add_object(tactmap, obj);  
	      }
#endif
	    
	  }
      }

#endif




  dfn.linear.gc = white;

  dfn.linear.thickness = 1;
  dfn.linear.gc = white;
  /* draw grid */

  for (i=0;i<routemap->num_x_squares;i++)
    {
      buf[0][0]=routemap->x_min + ((float32)i*routemap->size_square_x);
      buf[0][1]=routemap->y_min;
      buf[1][0]=routemap->x_min + ((float32)i*routemap->size_square_x);
      buf[1][1]=routemap->y_max;
      dfn.linear.n_vertices = 2;
      obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &dfn);
      tactmap_add_object(tactmap, obj);
    }
  for (i=0;i<routemap->num_y_squares;i++)
    {
      buf[0][1]=routemap->y_min + ((float32)i*routemap->size_square_y);
      buf[0][0]=routemap->x_min;
      buf[1][1]=routemap->y_min + ((float32)i*routemap->size_square_y);
      buf[1][0]=routemap->x_max;
      dfn.linear.n_vertices = 2;
      obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &dfn);
      tactmap_add_object(tactmap, obj);
    }

}



static void draw_routemap(routemap, tactmap)
    ROUTEMAP_PTR routemap;
    TACTMAP_PTR  tactmap;
{
    ROUTEMAP_OBSTACLE *obst;
    ROUTEMAP_CORRIDOR *corr, *conn;
    int32 i;
    float64 buf[1024][2];
    char charbuf[100];
    TACTMAP_OBJECT_DFN dfn, tdfn;
    TACTMAP_OBJECT_PTR obj;
    SNSTVE_CLASS null_class;
    XGCValues gcv;
    int32 sum;
    GC black, white;

    gcv.foreground = BlackPixelOfScreen(XtScreen(toplevel));
    black = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
		      GCForeground, &gcv);
    gcv.foreground = WhitePixelOfScreen(XtScreen(toplevel));
    white = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
		      GCForeground, &gcv);

    SNSTVE_INIT_CLASS(null_class);

    bzero(&dfn, sizeof(TACTMAP_OBJECT_DFN));
    dfn.linear.style = LSplain;
    dfn.linear.forward_arrow = 1;
    dfn.linear.thickness = 1;
    dfn.linear.width = 100;
    dfn.linear.gc = black;
    dfn.linear.vertices = (float64 *)buf;
    dfn.sensitive.class = &null_class;

    bzero(&tdfn, sizeof(TACTMAP_OBJECT_DFN));
    tdfn.text.gc = black;
    tdfn.text.see_through = 1;
    tdfn.text.string = charbuf;
    tdfn.sensitive.class = &null_class;

    sum = 0;
    for (obst=routemap->obstacles;obst;obst=obst->next)
    {
	for (i=0;i<obst->n_verts;i++)
	{
	    buf[i][0] = obst->verts[i].seg.x;
	    buf[i][1] = obst->verts[i].seg.y;
	}

	dfn.linear.n_vertices = obst->n_verts;

#if SHOW_OBSTACLES
	obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &dfn);
	tactmap_add_object(tactmap, obj);
#endif
#if SHOW_BYPASSES
	if (obst->bypass)
	{
	    dfn.linear.thickness = 2;
	    dfn.linear.gc = white;
	    create_bypass(tactmap, &dfn, &obst->verts[0].seg,
			  obst->bypass->positive_start);
	    create_bypass(tactmap, &dfn, &obst->verts[obst->n_verts-2].seg,
			  obst->bypass->positive_end);
	    dfn.linear.thickness = 3;
	    dfn.linear.gc = black;
	    create_bypass(tactmap, &dfn, &obst->verts[0].seg,
			  obst->bypass->negative_start);
	    create_bypass(tactmap, &dfn, &obst->verts[obst->n_verts-2].seg,
			  obst->bypass->negative_end);
	    dfn.linear.thickness = 1;
	}
#endif
#if SHOW_LABELS
	sprintf(charbuf, "%x", obst);
	tdfn.text.x = obst->verts[0].seg.x;
	tdfn.text.y = obst->verts[0].seg.y;
	obj = tactmap_create_object(tactmap, TACTMAP_TEXT, &tdfn);
	tactmap_add_object(tactmap, obj);
#endif

	sum++;
    }
    printf("%d obstacles\n", sum);

    dfn.linear.forward_arrow = 0;
    dfn.linear.thickness = 2;
    dfn.linear.style = LSplain;
    dfn.linear.n_vertices = 2;
    dfn.linear.gc = white;

    sum = 0;
#if SHOW_CORRIDORS
    for (corr=routemap->corridors;corr;corr=corr->next)
    {
	buf[0][0] = corr->seg.x;
	buf[0][1] = corr->seg.y;
	buf[1][0] = corr->seg.x+corr->seg.dx;
	buf[1][1] = corr->seg.y+corr->seg.dy;

	obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &dfn);
	tactmap_add_object(tactmap, obj);
#if SHOW_INDICES
	if (/*corr->begin_obst->linear*/1)
	{
	    for(i=0;i<corr->begin_obst->n_corridors;i++)
	      if (corr->begin_obst->corridors[i] == corr)
		break;
	    sprintf(charbuf, "%1.1f:%d", corr->begin_index, i);
	    tdfn.text.x = corr->seg.x + 0.25 * corr->seg.dx;
	    tdfn.text.y = corr->seg.y + 0.25 * corr->seg.dy;
	    obj = tactmap_create_object(tactmap, TACTMAP_TEXT, &tdfn);
	    tactmap_add_object(tactmap, obj);
	}

	if (/*corr->end_obst->linear*/1)
	{
	    for(i=0;i<corr->end_obst->n_corridors;i++)
	      if (corr->end_obst->corridors[i] == corr)
		break;
	    sprintf(charbuf, "%1.1f:%d", corr->end_index, i);
	    tdfn.text.x = corr->seg.x + 0.75 * corr->seg.dx;
	    tdfn.text.y = corr->seg.y + 0.75 * corr->seg.dy;
	    obj = tactmap_create_object(tactmap, TACTMAP_TEXT, &tdfn);
	    tactmap_add_object(tactmap, obj);
	}
#endif
	sum++;
    }
    printf("%d corridors\n", sum);

    dfn.linear.forward_arrow = 1;
    dfn.linear.thickness = 0;
    dfn.linear.dashed = 1;
    dfn.linear.gc = black;

    for (corr=routemap->corridors;corr;corr=corr->next)
    {
	buf[0][0] = corr->seg.x+corr->seg.dx*0.5;
	buf[0][1] = corr->seg.y+corr->seg.dy*0.5;

	for (i=0;i<corr->n_connect;i++)
	{
	    conn = corr->connect[i];
	    buf[1][0] = conn->seg.x+conn->seg.dx*0.5;
	    buf[1][1] = conn->seg.y+conn->seg.dy*0.5;

#if SHOW_CONNECTIVITY
	    obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &dfn);
	    tactmap_add_object(tactmap, obj);
#endif

	}
    }
#endif

}

static void tick_X(context)
    XtAppContext context;
{
    XEvent event;
    int pend;

    while (pend = XtAppPending(context))
    {
	if (pend & (XtIMXEvent  | XtIMTimer))
	{
	    XtAppProcessEvent(context, pend);
	}
	else
	  break;
    }
}

main(argc,argv)
    int32 argc;
    char *argv[];
{
    int32 hold_argc = argc;
    COORD_TCC_PTR tcc;
    XGCValues gcv;
    GC draw_gc, erase_gc;
    TACTMAP_OBJECT_DFN dfn[20];
    TACTMAP_OBJECT_PTR feature[20];
    SNSTVE_WINDOW_PTR sensitive;
    int32 i;
    SNSTVE_CLASS terrain_classes[20], null_class, left_class, right_class;
    int32 c=0, buildings, rails, roads, trees;
    Arg                     wargs[10];
    int n;

    /* reader */
    reader_init(0);

    /* Fake some soil constants */
    {
	READER_UNION ru[2];
#undef SOIL_DEEP_WATER
#undef SOIL_BOULDERS
	ru[0].integer = 2;
	ru[1].integer = 4;
	reader_set_symbol_value(reader_get_symbol("SOIL_DEEP_WATER"), ru);
	ru[2].integer = 14;
	reader_set_symbol_value(reader_get_symbol("SOIL_BOULDERS"), ru);
    }

    /* rdrconst */
    if (rdc_init("../../data", READER_OVERRIDE))
      printf("Error initializing librdrconst\n"), exit(0);

    /* Initialize libtime */
    time_init(1000);

    /* Initailize libsched */
    sched_init(1, 67);

    /* Initialize librandom */
    rnd_srandom(0);

/* to eliminate graphics, put if 0 here */

    toplevel = XtInitialize(argv[0], "RouteMap",
			    NULL, 0, &hold_argc, argv);

    if (hold_argc != 4)
    {
	printf("Usage %s: <terrain directory> <num_squares> <num_glue_points>\n", argv[0]);
	exit(0);
    }
    /* set the initial size of the window frame */
    n = 0;
    XtSetArg(wargs[n], XtNwidth,  1000); n++;
    XtSetArg(wargs[n], XtNheight, 1000); n++;
    XtSetValues(toplevel, wargs, n);

    XtRealizeWidget(toplevel);

    /* Initialize libbgr */
    BgrInit(XtDisplay(toplevel));

    /* Make the sensitivity GCs */
    gcv.foreground = WhitePixelOfScreen(XtScreen(toplevel));
    gcv.line_width = 1;
    draw_gc = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
			GCForeground | GCLineWidth, &gcv);
    erase_gc = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
			 GCLineWidth, &gcv);


/* to eliminate graphics put endif here */

    /* Read the terrain databases */
    load_terrain(argv[1], &ctdb, &tcc);

    /* Create the route map */
    routemap = routemap_create(&ctdb, ".", 0,argv[2],argv[3]);

    /* Make the sensitive window */
    snstve_init();
    sensitive = snstve_create(toplevel, draw_gc, erase_gc);
    callback_register_handler(snstve_miss_callback(sensitive), click, NULL);

    /* Make the tactical map */
    tactmap_init(".", 0);
    tactmap = tactmap_create(toplevel, sensitive, erase_gc, NULL,
			     tcc, &ctdb);
    tactmap_set_scale(tactmap, scale=200000.0);
    tactmap_set_center(tactmap,
		       (ctdb.min_x+ctdb.max_x)/2, (ctdb.min_y+ctdb.max_y)/2);

    bzero(&routedfn, sizeof(TACTMAP_OBJECT_DFN));
    routedfn.linear.style = LSplain;
    routedfn.linear.dashed = 0;
    routedfn.linear.width = 0;
    routedfn.linear.thickness = 2;
    gcv.foreground = BlackPixelOfScreen(XtScreen(toplevel));
    routedfn.linear.gc = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
				   GCForeground, &gcv);
    routedfn.linear.n_vertices = 0;
    routedfn.linear.vertices = routeverts;
    SNSTVE_INIT_CLASS(null_class);
    routedfn.sensitive.class = &null_class;
    routeobj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &routedfn);
    tactmap_add_transient_object(tactmap, routeobj);

    for (i=0;i<200;i++)
      {
	bzero(&routeboxdfn[i], sizeof(TACTMAP_OBJECT_DFN));
	routeboxdfn[i].linear.style = LSplain;
	routeboxdfn[i].linear.dashed = 0;
	routeboxdfn[i].linear.width = 0;
	routeboxdfn[i].linear.thickness = 1;
	gcv.foreground = BlackPixelOfScreen(XtScreen(toplevel));
	routeboxdfn[i].linear.gc = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
					  GCForeground, &gcv);
	routeboxdfn[i].linear.n_vertices = 0;
	routeboxdfn[i].linear.vertices = routeboxverts[i];
	SNSTVE_INIT_CLASS(null_class);
	routeboxdfn[i].sensitive.class = &null_class;
	routeboxobj[i] = tactmap_create_object(tactmap, TACTMAP_LINEAR, &(routeboxdfn[i]));
	tactmap_add_transient_object(tactmap, routeboxobj[i]);
      }

    bzero(&lb.dfn, sizeof(TACTMAP_OBJECT_DFN));
    lb.dfn.linear.style = LSfrontA;
    lb.dfn.linear.dashed = 0;
    lb.dfn.linear.width = 0;
    lb.dfn.linear.thickness = 5;
    gcv.foreground = BlackPixelOfScreen(XtScreen(toplevel));
    lb.dfn.linear.gc = XCreateGC(XtDisplay(toplevel), XtWindow(toplevel),
				   GCForeground, &gcv);
    lb.dfn.linear.n_vertices = 4;
    lb.dfn.linear.vertices = lb.verts;
    lb.verts[0] = lb.verts[2] = lb.verts[4] = lb.verts[6] = 
      (ctdb.min_x + ctdb.max_x) / 2;
    lb.verts[1] = (ctdb.min_y + ctdb.max_y) / 2;
    lb.verts[3] = lb.verts[1] + 1000;
    lb.verts[5] = lb.verts[3] + 1000;
    lb.verts[7] = lb.verts[5] + 1000;
    SNSTVE_INIT_CLASS(left_class);
    callback_register_handler(left_class.gesture, left_gesture);
    left_class.buttons = (1 << 1);
    left_class.sensitive = left_class.hot = 1;
    left_class.dragable = 1;
    left_class.drag_thresh = 10;
    lb.dfn.sensitive.class = &left_class;
    lb.obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &lb.dfn);
    tactmap_add_object(tactmap, lb.obj);

    rb = lb;
    rb.dfn.linear.style = LSfrontB;
    rb.dfn.linear.vertices = rb.verts;
    rb.verts[0] = rb.verts[2] = rb.verts[4] = rb.verts[6] = rb.verts[0] + 1000;
    SNSTVE_INIT_CLASS(right_class);
    callback_register_handler(right_class.gesture, right_gesture);
    right_class.buttons = (1 << 1);
    right_class.sensitive = right_class.hot = 1;
    right_class.dragable = 1;
    right_class.drag_thresh = 10;
    rb.dfn.sensitive.class = &right_class;
    rb.obj = tactmap_create_object(tactmap, TACTMAP_LINEAR, &rb.dfn);
    tactmap_add_object(tactmap, rb.obj);

    /* Make some features */
    bzero(dfn, sizeof(dfn));

    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_WATER, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    roads = c;
    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_ROADS, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    buildings = c;
    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_BUILDINGS, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_PIPELINES, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_POLITICAL, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    rails = c;
    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_RAILROADS, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_POWERLINES, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_TOWNS, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    trees = c;
    dfn[c].trees.mask = TREE_MASK;
    SNSTVE_INIT_CLASS(terrain_classes[c]);
    dfn[c].sensitive.class = &terrain_classes[c];
    feature[c] = tactmap_create_object(tactmap, TACTMAP_TREES, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    bzero(dfn+c, sizeof(TACTMAP_OBJECT_DFN));
    dfn[c].grids.interval = 1000;
    dfn[c].grids.label_mask = COORD_LABEL_ALL;
    feature[c] = tactmap_create_object(tactmap, TACTMAP_GRIDS, dfn+c);
    tactmap_add_object(tactmap, feature[c]); c++;

    /* Draw the routemap */
    draw_routemap(routemap, tactmap);

    /* draw visibility graph */

    draw_visib_graph(routemap,tactmap);

    /* Post the map tick */
    sched_periodic_fncl(tactmap_tick, 1000, 67, 0,
			A_PTR, tactmap,
			A_INT, 67,
			A_END);

    /* Post the X tick */
    sched_periodic_fncl(tick_X, 0, 67, 0,
			A_PTR, XtWidgetToApplicationContext(toplevel),
			A_END);

    /* Start the scheduler */
    sched_invoke_functions_until(0xFFFFFFFF);
}

static void load_terrain(name, ctdb, tccp)
    char          *name;
    CTDB          *ctdb;
    COORD_TCC_PTR *tccp;
{
    char path_name[256];

    if (name)
    {
	if ((name[0] == '/') || (name[0] == '.'))
	  strcpy(path_name, name);
	else
	  sprintf(path_name, "../../terrain/%s/%s.ctdb", name, name);

	ctdb_read(path_name, ctdb, 10*1024*1024);
    }
    else
      ctdb_read(NULL, ctdb, 0);

    coord_init("../../data", 0);
    *tccp = coord_define_tcc(ctdb->is_curved ? COORD_GCC : COORD_UTM_NE,
			     ctdb->origin_northing,
			     ctdb->origin_easting,
			     ctdb->origin_zone_number,
			     ctdb->origin_zone_letter,
			     ctdb->datum,
			     ctdb->max_x, ctdb->max_y);
}
 
