#ifndef lint
static char rcsid [] = "$RCSfile$ $Revision$ $State$";
#endif
/****************************************************************************
*   File: rtmp_util.c                                                       *
*                                                                           *
*       Copyright 1993 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: General routemap utilities                                *
*       Created: Mon Aug 15 1994                                            *
*       Author: mlongtin                                                    *
*       Remarks:                                                            *
*                                                                           *
****************************************************************************/

#include <stdio.h>
#include "librtmp_local.h"
#include <stdext.h> /*common/include/global*/
#include <stdstring.h> /*common/include/global*/

static int32 squares_overlap(x_min1, y_min1, x_max1, y_max1,
			     x_min2, y_min2, x_max2, y_max2)
    int32     x_min1, y_min1, x_max1, y_max1;
    int32     x_min2, y_min2, x_max2, y_max2;
{
    if(y_max1 <= y_min2)  return FALSE;
    if(y_max2 <= y_min1)  return FALSE;
    if(x_max1 <= x_min2)  return FALSE;
    if(x_max2 <= x_min1)  return FALSE;

    return TRUE;
}


/* This function returns pointers to the first `n_obstacles' obstacles within
 * the given rectangular area that match the passed obstacle mask.  The
 * number of obstacles found is returned in `n_obstacles'.  The pointers
 * in the `obstacles[]' array don't tell the caller much unless they are
 * converted to a list of vertices by `routemap_obstacle_to_vertices()'.
 * If the number of matching obstacles exceeds `n_obstacles', a non-zero
 * value is returned.  Otherwise, a zero is returned.
 */
int32 routemap_get_obstacles(routemap, obstacle_mask, x_min, y_min,
			     x_max, y_max, n_obstacles, obstacles)
    ROUTEMAP_PTR       routemap;
    uint32             obstacle_mask;
    int32              x_min, y_min;
    int32              x_max, y_max;
    int32             *n_obstacles;
    ADDRESS            obstacles[];
{
    ROUTEMAP_OBSTACLE *i;
    int32 q, r, s, max_obstacles;

    if (!routemap)
    {
	*n_obstacles = 0;
	return 0;
    }

    max_obstacles = *n_obstacles;
    *n_obstacles = 0;

    /* Find the index of the topmost quad which contains this area. */
    q = routemap_select_quad(routemap, 1, 0, x_min, y_min, x_max, y_max);

    /* Get the obstacles in this quad and parent quads. */
    for (r=q;r!=-1;r=routemap->quad_info[r].parent)
      for (i=routemap->quad_info[r].obstacles;i;i=i->next_quad)
      {
	  if((i->type_mask & obstacle_mask) &&
	     squares_overlap(i->center_x - i->width / 2,
			     i->center_y - i->height / 2,
			     i->center_x + i->width / 2,
			     i->center_y + i->height / 2,
			     x_min, y_min, x_max, y_max))
	    obstacles[*n_obstacles] = i;
	  else continue;

	  if(++(*n_obstacles) == max_obstacles)
	    return -1;
      }

    /* Same deal for descendant quads. */
    s = q + routemap->quad_info[q].num_descendants;
    for (r=q+1;r<=s;r++)
      for (i=routemap->quad_info[r].obstacles;i;i=i->next_quad)
      {
	  if(i->type_mask & obstacle_mask &&
	     squares_overlap(i->center_x - i->width / 2,
			     i->center_y - i->height / 2,
			     i->center_x + i->width / 2,
			     i->center_y + i->height / 2,
			     x_min, y_min, x_max, y_max))
	    obstacles[*n_obstacles] = i;
	  else continue;

	  if(++(*n_obstacles) == max_obstacles)
	    return -1;
      }

    return 0;
}


/* Given a pointer to a routemap obstacle, this function returns the type of
 * object, which is one of:
 *
 * ROUTEMAP_RIVERS
 * ROUTEMAP_LAKES
 * ROUTEMAP_BOULDERS
 * ROUTEMAP_CANOPIES
 * ROUTEMAP_STEEP_AREAS
 */
uint32 routemap_obstacle_type(obstacle)
    ADDRESS            obstacle;
{
    return ((ROUTEMAP_OBSTACLE *)obstacle)->type_mask;
}


/* Given a pointer to a routemap obstacle, this function finds the vertices
 * of the object specified by the pointer.  The number of vertices is
 * returned in `n_vertices'.  Upon invocation, `n_vertices' should contain
 * the maximum number of vertices that may be found.  If the object has
 * more than this number of vertices, a nonzero value is returned.  Otherwise,
 * zero is returned.
 */
int32 routemap_obstacle_to_vertices(obstacle, n_vertices, vertices)
    ADDRESS            obstacle;
    int32             *n_vertices;
    float32            vertices[][2];
{
    int32             i, max_vertices;

    max_vertices = *n_vertices;
    *n_vertices = 0;

    for(i = 0; i < ((ROUTEMAP_OBSTACLE *)obstacle)->n_verts; i++)
    {
	vertices[*n_vertices][X] = ((ROUTEMAP_OBSTACLE *)obstacle)->
	                           verts[*n_vertices].seg.x;
	vertices[*n_vertices][Y] = ((ROUTEMAP_OBSTACLE *)obstacle)->
	                           verts[*n_vertices].seg.y;

	if(++(*n_vertices) == max_vertices)
	{
	    *n_vertices = 0;
	    return -1;
	}
    }

    return 0;
}

