/*****************************************************************************

 shape.cc:  Implementation of shape example.

 ----------------------------------------------------------------------
 This file is part of ILOG Talk.
 Inquiries to ILOG S.A.
              9 rue de Verdun, BP 85,
              94253 Gentilly Cedex, France.

 Copyright (c) 1994-1996 by ILOG
 $Header: /nfs/talk/work/talk/contrib/shape/src/RCS/shape.cc,v 1.3 1996/07/15 16:09:46 v16admin Exp $
 ----------------------------------------------------------------------
******************************************************************************/

#include <shape.h>
#include <iostream.h>

Boolean Rect::intersects(Rect& r)
{
  int l1 = upper_left.x();
  int t1 = upper_left.y();
  int b1 = lower_right.y();
  int r1 = lower_right.x();
  int l2 = r.upperLeft().x();
  int t2 = r.upperLeft().y();
  int b2 = r.lowerRight().y();
  int r2 = r.lowerRight().x();

  return ((l1 <= r2) &&
	  (r1 >= l2) &&
	  (t1 <= b2) &&
	  (b1 >= t2));
}

Rect::Rect(Point& ul, Point& lr)
{
  upper_left = ul;
  lower_right = lr;
}

Rect::Rect(int ulx, int uly, int lrx, int lry)
{
  upper_left.x(ulx);
  upper_left.y(uly);
  lower_right.x(lrx);
  lower_right.y(lry);
}

void prin_move(int cx, int cy, int dx, int dy, const char* type)
{
  cout << "Moving a " << type
       << " from (" << cx << "," << cy << ")"
       << " to (" << cx+dx << "," << cy+dy << ")" << endl;
}

void Shape::move(short dx, short dy)
{
  int cx = center->x();
  int cy = center->y();
  prin_move(cx, cy, dx, dy, typeOf());
  center->x(cx+dx);
  center->y(cy+dy);
}

void Shape::move(const Point& p)
{
  int cx = center->x();
  int cy = center->y();
  int dx = p.x();
  int dy = p.y();
  prin_move(cx, cy, dx, dy, typeOf());
  center->x(cx+dx);
  center->y(cy+dy);
}

void Shape::draw()
{
  cout << "Drawing a " << typeOf()
       << " at (" << center->x() << "," << center->y() << ")";
}


// Squares

void Square::draw()
{
  Shape::draw();
  cout << " with side length " << sideLen << endl;
}

Rect* Square::findBBox(Boolean& exact)
{
  int cx = center->x();
  int cy = center->y();
  int sl2 = sideLen/2;
  exact = True;
  return new Rect(cx-sl2, cy-sl2, cx+sl2, cy+sl2);
}

void Square::scale(double factor)
{
  sideLen = (int)(((double)sideLen)*factor);
}

// Circles

void Circle::draw()
{
  Shape::draw();
  cout << " with diameter " << diameter << endl;
}

Rect* Circle::findBBox(Boolean& exact)
{
  int cx = center->x();
  int cy = center->y();
  int radius = diameter/2;
  exact = False;
  return new Rect(cx-radius, cy-radius, cx+radius, cy+radius);
}

void Circle::scale(double factor)
{
  diameter = (int)(((double)diameter)*factor);
}

// global fns

Shape *hilightedShape = 0;

void initSystem(char* display, char* title)
{
  cout << "Initializing display " << display;
  if (title) cout << " with title " << title;
  cout << endl;
}
