
/* "UNTIL", a graphics editor,
   Copyright (C) 1985, 1990 California Institute of Technology.
   Original authors: Glenn Gribble, port by Steve DeWeerth
   Unix Port Maintainer: John Lazzaro
   Maintainers's address: lazzaro@hobiecat.cs.caltech.edu;
                          CB 425 CU Boulder/Boulder CO 91125. 

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation (Version 1, 1989).

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
USA. */


/*******************************************************************************/
/*                                                                             */ 
/*  file contains stuff to deal with bounding boxes                            */
/*  cleaned up by steve - 7 May 1990                                           */
/*                                                                             */ 
/*******************************************************************************/

#include <p2c/p2c.h>

#include "bb_stuff.h"

#ifndef SYSGLOBALS_H
#include <p2c/sysglobals.h>
#endif


bbrec bbbb;              /* Box-type pen-position */
long bbx, bby;           /* pen-position */
long bbrx, bbry, bbrxy;  /* radius in X, radius in Y, radius^2 in XY */


/* set up current bounding box information */
void makebb(long x, long y, long rx, long ry)
{
  bbx = x;
  bby = y;
  bbrx = labs(rx);
  bbry = labs(ry);
  bbrxy = bbrx * bbrx + bbry * bbry;
  bbbb.xl = bbx - bbrx;
  bbbb.xh = bbx + bbrx;
  bbbb.yl = bby - bbry;
  bbbb.yh = bby + bbry;
}


/* initialize a new BB from scratch */
void newbb(bbrec *bb, long lx, long ly, long hx, long hy)
{
  if (hx > lx) {
    bb->xh = hx;
    bb->xl = lx;
  } else {
    bb->xh = lx;
    bb->xl = hx;
  }
  if (hy > ly) {
    bb->yh = hy;
    bb->yl = ly;
  } else {
    bb->yh = ly;
    bb->yl = hy;
  }
}


/* Create an empty (inside-out) BB */
#define big             (LONG_MAX / 10)
void emptybb(bbrec *bb)
{
  bb->xh = -big;
  bb->xl = big;
  bb->yh = -big;
  bb->yl = big;
}
#undef big


/* make BB large enough to enclose BB and BB2 */
void addbb(bbrec *bb, bbrec *bb2)
{
  if (bb2->xl < bb->xl)
    bb->xl = bb2->xl;
  if (bb2->xh > bb->xh)
    bb->xh = bb2->xh;
  if (bb2->yl < bb->yl)
    bb->yl = bb2->yl;
  if (bb2->yh > bb->yh)
    bb->yh = bb2->yh;
}


/* make BB large enough to enclose BB and the new point */
void addbbpnt(bbrec *bb, long x, long y)
{
  /* Don't do these as else-if's, because of emptyBB's */
  if (x < bb->xl)
    bb->xl = x;
  if (x > bb->xh)
    bb->xh = x;
  if (y < bb->yl)
    bb->yl = y;
  if (y > bb->yh)
    bb->yh = y;
}


/* is X,Y within the current Box pen position */
boolean pntcheck(long x, long y)
{
  return (bbbb.xh >= x && bbbb.xl <= x && bbbb.yh >= y && bbbb.yl <= y);
}


/* does the line (X1,Y1)--(X2,Y2) go through the current Box pen position? */
boolean linecheck(long x1, long y1, long x2, long y2)
{
  long dx, dy, temp;

  dx = x2 - x1;
  dy = y2 - y1;

  /* there used to be a try/recover here to handle large numbers using doubles - steve */

  temp = dy * (x1 - bbx) + dx * (bby - y1);
  return (bbrxy * (dx*dx + dy*dy) >= temp*temp);
}


/* is the current pen position within BB? */
boolean bbcheck(bbrec *bb)
{
  return (bbx >= bb->xl && bbx <= bb->xh && bby >= bb->yl && bby <= bb->yh);
}


/* same as BBCHECK, only bounding box is supplied as separate parts */
boolean bbxcheck(long xl, long yl, long xh, long yh)
{
  long t;

  if (xl > xh) {
    t = xl;
    xl = xh;
    xh = t;
  }

  if (yl <= yh) {
    return (bbx >= xl && bbx <= xh && bby >= yl && bby <= yh);
  }
  else {
    t = yl;
    yl = yh;
    yh = t;

    return (bbx >= xl && bbx <= xh && bby >= yl && bby <= yh);
  }
}


/* does BB overlap the current Box pen position */
boolean bbrcheck(bbrec *bb)
{
  return (bbbb.xh >= bb->xl && bbbb.xl <= bb->xh && bbbb.yh >= bb->yl && bbbb.yl <= bb->yh);
}


/* does BB fit within the current Box pen position? */
boolean bbincheck(bbrec *bb)
{
  return (bbbb.xh >= bb->xh && bbbb.xl <= bb->xl && bbbb.yh >= bb->yh && bbbb.yl <= bb->yl);
}


/* same as BBRCHECK, only bounding box is supplied as separate parts */
boolean bbxrcheck(long xl, long yl, long xh, long yh)
{
  long t;

  if (xl > xh) {
    t = xl;
    xl = xh;
    xh = t;
  }

  if (yl <= yh) {
    return (bbbb.xh >= xl && bbbb.xl <= xh && bbbb.yh >= yl && bbbb.yl <= yh);
  }
  else {
    t = yl;
    yl = yh;
    yh = t;

    return (bbbb.xh >= xl && bbbb.xl <= xh && bbbb.yh >= yl && bbbb.yl <= yh);
  }
}
