/**
 * This is region handler for a rectangular region.  This can also work
 * for circular regions by making a 0 width/height feature.
 * @author Pinkfish
 * @started Mon Apr  1 12:15:24 PST 2002
 */
inherit "/std/room/inherit/terrain_map/geometry";
class feature_pos {
   int xstart;
   int ystart;
   int width;
   int height;
}
private mixed    *_feature_direcs = ({ ({ "southwest", "south", "southeast" }),
                               ({ "west", "Oops", "east" }),
                               ({ "northwest", "north", "northeast" }) });
private class feature_pos* _positions = ({ });
/**
 * This method sets the position of the feature.
 * @param x the x coordinate of the feature
 * @param y the y coordinate of the feature
 * @param width the width of the feature
 * @param height the height of the feature
 */
void add_feature_position(int x, int y, int width, int height) {
   class feature_pos pos;
   pos = new(class feature_pos, xstart : x, ystart : y,
                                width : width, height : height);
   _positions += ({ pos });
}
/**
 * This is the function that finds the distance and direction to the
 * current region.
 * @param x the x-coordinate
 * @param y the y-coordinate
 * @param z the z-coordinate
 * @return ({ direction, distance })
 */
mapping query_feature_desc_from(int x, int y, int z) {
   int h;
   int v;
   int width;
   int height;
   float distance;
   float min_distance;
   string direc;
   class feature_pos pos;
   float xmod;
   float ymod;
   int xd;
   int yd;
   foreach (pos in _positions) {
      h = pos->xstart;
      v = pos->ystart;
      width = pos->width;
      height = pos->height;
      if (x >= (h + width)) {
         h = h + width - 1;
      } else if (x >= h) {
         h = x;
      }
      if (y >= (v + height)) {
         v = v + height - 1;
      } else if (y >= v) {
         v = y;
      }
      distance = sqrt(pow(x - h, 2) + pow(y - v, 2));
      if (distance > 0.0000001 && (distance < min_distance || !min_distance)) {
         xmod = ((h - x) < 0) ? -0.5 : 0.5;
         ymod = ((v - y) < 0) ? -0.5 : 0.5;
         xd = to_int(xmod + to_float(h - x) / distance) + 1;
         yd = to_int(ymod + to_float(v - y) / distance) + 1;
         direc = _feature_direcs[yd][xd];
         min_distance = distance;
      }
   }
   if (!direc) {
      return ([ ]);
   }
   return ([ direc : to_int(min_distance) ]);
}
/** @ignore yes */
void dest_me() {
   destruct(this_object());
}
/**
 * Find out if this rectangle is inside the region, given the specified range
 * at which it can be seen.  This will work by adding the ranges onto the
 * lines and checking for distance from the points of the polygon to the line
 * bordering the region and also checking for intersection with the bordering
 * line.  It also checks to see if all of the points are inside the region.
 * @param x1 the top x
 * @param y1 the top y
 * @param x2 the bottom x
 * @param y2 the bottom y
 */
int is_inside_region(int x1, int y1, int x2, int y2, int range) {
   class feature_pos position;
   int height;
   int width;
   foreach (position in _positions) {
      height = position->height;
      width = position->width;
      if (position->xstart >= x1 && position->xstart <= x2 &&
          position->ystart >= y1 && position->ystart <= y2) {
         return 1;
      }
      if (position->xstart >= x1 && position->xstart <= x2 &&
          position->ystart + height >= y1 && position->ystart + height <= y2) {
         return 1;
      }
      if (position->xstart +width >= x1 && position->xstart +width <= x2 &&
          position->ystart + height >= y1 && position->ystart + height <= y2) {
         return 1;
      }
      if (position->xstart +width >= x1 && position->xstart +width <= x2 &&
          position->ystart >= y1 && position->ystart <= y2) {
         return 1;
      }
/*
      if (distance_between_two_line_segments(x1, y1, x1, y2,
          position->xstart + width, position->ystart, position->xstart +width, position->ystart + height) < range) {
         return 1;
      }
      if (distance_between_two_line_segments(x1, y1, x2, y1,
          position->xstart, position->ystart + height, position->xstart +width, position->ystart + height) < range) {
         return 1;
      }
      if (distance_between_two_line_segments(x2, y1, x2, y2,
          position->xstart, position->ystart, position->xstart, position->ystart + height) < range) {
         return 1;
      }
      if (distance_between_two_line_segments(x1, y2, x2, y2, 
          position->xstart, position->ystart, position->xstart +width, position->ystart) < range) {
         return 1;
      }
 */
   }
   return 0;
}