/*	File: Quadrang.cpp
 *
 *	Design and Implementation Description:
 *		For i = 0 .. 3: delta [i] == point [(i + 1) % 4] - point [i].
 *	History:
 *		Date:		 Author:	 Change:
 *		97-05-07	 KHU		 Creation.
 */

#include "Quadrang.h"

#include <assert.h>
#include <graphics.h>
#include <iostream.h>
#include <math.h>							// For sqrt ().

#include "Arith.h"						// For Sqr ().
#include "Triangle.h"					// Used by Area ().

	void Quadrangle::Draw ()
	{
		moveto (refPoint.x, refPoint.y);
		for (int i = 0; i < quadrangleNbrOfPoints; i++)
		{
			linerel (delta [i].x, delta [i].y);
		};
	}; // Draw

	Float Quadrangle::Extent () const
	{
		Float result = 0.0;
		for (int i = 0; i < quadrangleNbrOfPoints; i++)
		{
			result += sqrt (Sqr (delta [i].x) + Sqr (delta [i].y));
		};
		assert(result >= 0.0);
		return result;
	}; // Extent

	Float Quadrangle::Area () const
	{
		Float result =
			Triangle (refPoint, Point (1), Point (2)).Area () +
			Triangle (refPoint, Point (2), Point (3)).Area ();
		assert(result >= 0.0);
		return result;
	}; // Area

	CoordinatePair Quadrangle::Point (int nbr) const
	{
		assert(nbr >= 0);
		assert(nbr < quadrangleNbrOfPoints);
		CoordinatePair point = refPoint;
		for (int i = 0; i < nbr; i++)
		{
			point.x += delta [i].x;
			point.y += delta [i].y;
		};
		return point;
	}; // Point

	void Quadrangle::Stretch (const CoordinatePair & factor)
	{
		FigureState s = state;
		if (s == shown)
		{
			Hide ();
		};
		refPoint.x *= factor.x;
		refPoint.y *= factor.y;
		for (int i = 0; i < quadrangleNbrOfPoints; i++)
		{
			delta [i].x *= factor.x;
			delta [i].y *= factor.y;
		};
		if (s == shown)
		{
			Show ();
		};
		CheckInvariant ();
		assert(s == state);
	}; // Stretch

	Quadrangle::Quadrangle
		(const CoordinatePair & point0,
		 const CoordinatePair & point1,
		 const CoordinatePair & point2,
		 const CoordinatePair & point3)
	{
		refPoint    = point0;
		delta [0].x = point1.x - point0.x;
		delta [0].y = point1.y - point0.y;
		delta [1].x = point2.x - point1.x;
		delta [1].y = point2.y - point1.y;
		delta [2].x = point3.x - point2.x;
		delta [2].y = point3.y - point2.y;
		delta [3].x = point0.x - point3.x;
		delta [3].y = point0.y - point3.y;
		CheckInvariant ();
	}; // Quadrangle

	void Quadrangle::CheckInvariant ()
	{
		ClosedStretchableFigure::CheckInvariant ();
		for (int i = 0; i < quadrangleNbrOfPoints; i++)
		{
			assert(coordinateMin <= delta [i].x);
			assert(delta [i].x <= coordinateMax);
			assert(coordinateMin <= delta [i].y);
			assert(delta [i].y <= coordinateMax);
		}
	}; // CheckInvariant

// End of Quadrang.

