/*
   File:        region.c
   Author:      Andrew W. Moore
   Created:     Sat Sep 19 10:44:22 EDT 1992
   Description: K-d region Data Structure

   Copyright (C) 1992, Andrew W. Moore
*/

#include <stdio.h>
#include <math.h>
#include "ambs.h"      /* Very basic operations */
#include "amma.h"      /* Fast, non-fragmenting, memory management */
#include "maxdim.h"    /* The MAX_DIM declaration */
#include "gpro.h"      /* Graphics projections kd->2d space */
#include "hype.h"      /* Hyper-rectangles from ../kdtr */
#include "region.h"    /* K-d region Data Structure */

region *create_hype_region(hy,hype_type)
hype *hy;
int hype_type;
{
  region *new = AM_MALLOC(region);
  new -> region_type = hype_type;
  new -> data = (char *) hy;
  return(new);
}

region *create_in_hype_region(hy)
hype *hy;
{
  return(create_hype_region(hy,IN_HYPE_REGION));
}

region *create_out_hype_region(hy)
hype *hy;
{
  return(create_hype_region(hy,OUT_HYPE_REGION));
}

void gp_draw_region_border(gp,reg)
gproj *gp;
region *reg;
{
  switch ( reg -> region_type )
  {
    case IN_HYPE_REGION:
    case OUT_HYPE_REGION:
    {
      hype *hy = (hype *) reg -> data;
      gp_draw_hype_border(gp,hy);
      break;
    }
    default:
      printf("region_type = %d\n",reg->region_type);
      my_error("region_type unknown");
  }
}

bool is_inside_region(reg,farr)
region *reg;
float *farr;
{
  bool result;
  switch ( reg -> region_type )
  {
    case IN_HYPE_REGION:
    case OUT_HYPE_REGION:
    {
      hype *hy = (hype *) reg -> data;
      bool is_in = is_inside_hype(hy,farr);
      result = (reg->region_type == IN_HYPE_REGION) ? is_in : !is_in;
      break;
    }
    default:
      printf("region_type = %d\n",reg->region_type);
      my_error("region_type unknown");
  }
  return(result);
}

void fprintf_region(s,m1,reg,m2)
FILE *s;
char *m1;
region *reg;
char *m2;
{
  switch ( reg -> region_type )
  {
    case IN_HYPE_REGION:
    case OUT_HYPE_REGION:
    {
      char buff1[100];
      char buff2[100];
      hype *hy = (hype *) reg -> data;
      sprintf(buff1,"%s%s_HYPE(",
              m1,
              (reg->region_type==IN_HYPE_REGION) ? "IN" : "OUT"
             );
      sprintf(buff2,") %s",m2);
      fprintf_hype(s,buff1,hy,buff2);
      break;
    }
    default:
      printf("region_type = %d\n",reg->region_type);
      my_error("region_type unknown");
  }
}

void middle_of_region(reg,mid)
region *reg;
float *mid;
/*
   PRE: Mid contains enough memory (ie dimensionality of region)
*/
{
  switch ( reg -> region_type )
  {
    case IN_HYPE_REGION:
    case OUT_HYPE_REGION:
    {
      float scales[MAX_DIM];
      hype *hy = (hype *) reg -> data;
      m_and_s_from_hype(hy,mid,scales);
      break;
    }
    default:
      printf("region_type = %d\n",reg->region_type);
      my_error("region_type unknown");
  }
}

