//
// .SUMMARY:
// Defines the Box class.
//
// .DESCRIPTION
// The Box class is used to store retangular entities like windows, viewports,
// clipping and extend rectangles, among others.
//
// .SEE ALSO
// Point
//
//

#ifndef	Box_H
#define Box_H

#include <gdefines.h>

#ifndef Point_H
#include <Point.hpp>
#endif

class SProjection;

class Box
{
	Point _bll, _bur;
//		Lower-left and upper-right coordinates that defines the rectangle.

public:

	Box () {}
//		Empty constructor.

	Box (const Point& o, const Point& c);
//		Normal constructor.
//		Input :
//			o : point (lower-left)
//			c : point (upper-right)

	~Box () {}
//		Normal destructor.

	Box (const Box&);
//		Copy initializer.

	short contains (const Point& p) const;
//		Check if Box contains Point p.
//		Input :
//			p : point
//		Return :
//			TRUE  : box contains point p
//			FALSE : box not contains point p

	short contains (const Box& b) const;
//		Check if Box contains Box b.
//		Input :
//			b : box
//		Return :
//			TRUE  : box contains b
//			FALSE : box not contains b

	short intersects (const Box& b) const;
//		Check if Box intersects Box b.
//		Input :
//			b : box
//		Return :
//			TRUE  : box intersects b
//			FALSE : box not intersects b

	Box intersection (const Box& b) const;
//		Perform the intersection between Box and Box b. Return the new box.

	Box unionx (const Box& b) const;
//		Perform the union between Box and Box b. Return the new box.

	Point& lowerLeft () { return _bll; }
//		Return the lower-left corner of the rectangle.

	Point& upperRight () { return _bur; }
//		Return the upper-right corner of the rectangle.

	void lowerLeft (const Point& pp){ _bll = pp; }
//		Initialize the lower-left corner of the rectangle.
//		Input :
//			pp : point

	void upperRight (const Point& pp){ _bur = pp; }
//		Initialize the upper-right corner of the rectangle.
//		Input :
//			pp : point

	float upperRightX ()const { return _bur.x(); }
//		Return the X coordinate from the upper-right corner of the rectangle.

	float upperRightY ()const { return _bur.y(); }
//		Return the Y coordinate from the upper-right corner of the rectangle.

	float lowerLeftX ()const { return _bll.x(); }
//		Return the X coordinate from the lower-left corner of the rectangle.

	float lowerLeftY ()const { return _bll.y(); }
//		Return the Y coordinate from the lower-left corner of the rectangle.

	void upperRightX (float f) { _bur.x(f); }
//		Set the X coordinate from the upper-right corner of the rectangle.
//		Input :
//			f : float variable

	void upperRightY (float f) { _bur.y(f); }
//		Set the Y coordinate from the upper-right corner of the rectangle.
//		Input :
//			f : float variable

	void lowerLeftX (float f) { _bll.x(f); }
//		Set the X coordinate from the lower-left corner of the rectangle.
//		Input :
//			f : float variable

	void lowerLeftY (float f) { _bll.y(f); }
//		Set the Y coordinate from the lower-left corner of the rectangle.
//		Input :
//			f : float variable


	void print ();
//		Print box coordinates on the console.

	void init (Point& l, Point& r) { _bll = l; _bur = r; }
//		Store the first (or a new) rectangle.
//		Input:
//			l : lower-left corner coordinate
//			r : upper-right corner coordinate

	float width () { return mv_abs(_bur.x() - _bll.x()); }
//		Return the width of the rectangle.

	float height () { return mv_abs(_bur.y() - _bll.y()); }
//		Return the height of the rectangle.

	Box operator= (Box& b);
//		Assignment capability for class Box instances.

	void remap (SProjection* in, SProjection* out);
//		Remap box in projection "in" to box in projection "out".
//		Input :
//			in  : input projection
//			out : output projection

	void remap (SProjection* out);
//		Remap box defined in latitude and longitude to
//		projection "out". This method does not just remap the
//		two points that define the box. It searches for
//		the minimum and maximum projection coordinates
//		values along the edges of the box.
//		Input :
//			out : desired projection

	short load (FILE *fp);
	short save (FILE *fp);
};

#endif
