

#ifndef _rectangle_h_
#define _rectangle_h_





/*
 *
 *          Copyright (C) 1995, M. A. Sridhar
 *  
 *
 *     This software is Copyright M. A. Sridhar, 1995. You are free
 *     to copy, modify or distribute this software  as you see fit,
 *     and to use  it  for  any  purpose, provided   this copyright
 *     notice and the following   disclaimer are included  with all
 *     copies.
 *
 *                        DISCLAIMER
 *
 *     The author makes no warranties, either expressed or implied,
 *     with respect  to  this  software, its  quality, performance,
 *     merchantability, or fitness for any particular purpose. This
 *     software is distributed  AS IS.  The  user of this  software
 *     assumes all risks  as to its quality  and performance. In no
 *     event shall the author be liable for any direct, indirect or
 *     consequential damages, even if the  author has been  advised
 *     as to the possibility of such damages.
 *
 */




#if defined(__GNUC__)
#pragma interface
#endif

#if (defined(__MS_WINDOWS__) || defined(__MS_WIN32__)) && !defined(__WINDOWS_H)
#include <windows.h>
#endif

#include "ui/vector.h"
#include "ui/point.h"
#include "ui/graphic.h"
#include "ui/containr.h"
#include "base/sequence.h"



class YACL_UI UI_DrawingSurface;

// This is an abstraction of a rectangle at a given position in
// two-dimensional space. The sides of the rectangle are parallel to the
// co-ordinate axes.  The Rectangle treats its height and
// width values  as including the lines drawn for its periphery.
//
// Like the other GraphicObjects, the Rectangle views its co-ordinate space as
// an abstract space not tied to any particular device. But its {\tt DrawOn}
// and {\tt Fill} methods view its dimension units as pixels.


class YACL_UI UI_Rectangle: public UI_GraphicObject {

public:

    //
    //-------------------Construction------------------
    //
    UI_Rectangle (const UI_Point& topLeft, long width, long height);
    // Constructor: construct a Rectangle with top left at {\tt topLeft},
    // with the given height and width. If the height or width is negative,
    // the constructor negates them and flips the Rectangle around as
    // necessary.

    UI_Rectangle (long x, long y, long width, long height);
    // Constructor: construct a Rectangle with top left at $(x, y)$
    // with the given height and width. If the height or width is negative,
    // the constructor negates them and flips the Rectangle around as
    // necessary.

    UI_Rectangle (const UI_RectangleStruct&);
    // Convenience constructor.
    
    UI_Rectangle ();
    // Default constructor: create a Rectangle with zero size at the origin.

    UI_Rectangle (const UI_Rectangle& );
    // Copy constructor.

    ~UI_Rectangle ();

    //
    // --------------------Query-------------------------
    //

    UI_Rectangle BoundingRectangle() const {return *this; };
    // Return this Rectangle. This method overrides the inherited one.
    
    UI_PointSequence EndPoints () const;
    // Return the four corners of this Rectangle  in clockwise order,
    // beginning at top left, as a sequence containing four elements.
    
    UI_Point Center () const;
    // Return the center of the Rectangle.
    
    long Top () const {return _origin.YCoord();}
    // Return the $y$ co-ordinate of the top.

    long Left () const {return _origin.XCoord();}
    // Return the $x$ co-ordinate of the left side.

    long Bottom () const {return _origin.YCoord() + _height - 1;}
    // Return the $y$ co-ordinate of the bottom.

    long Right () const {return _origin.XCoord() + _width - 1;}
    // Return the $x$ co-ordinate of the right side.
    
    const UI_Point& Origin ()  const {return _origin;};
    // Return the top left corner.
    
    const UI_Point& TopLeft () const {return _origin;}
    // Return the top left corner.

    UI_Point TopRight () const   {return _origin + UI_Vector (_width-1, 0);};
    // Return the top right corner.
    
    UI_Point BottomLeft () const {return _origin + UI_Vector (0, _height-1);};
    // Return the bottom left corner.
    
    UI_Point BottomRight () const
        {return _origin + UI_Vector (_width-1, _height-1);};
    // Return the bottom right corner.

    long Height () const {return _height;};
    // Return the height.
    
    long Width () const  {return _width;};
    // Return the width.
    
    long Area () const   {return _width * _height;};
    // Return the area.
    
    UI_HitTest HitTest (const UI_Point& p) const;
    // Override inherited virtual method. The return value tells whether
    // {\tt p} is inside, outside or on the periphery of the Rectangle.

    bool OnBoundary (const UI_Point& p) const;
    // Return TRUE if {\tt p} is on the boundary of this rectangle, and
    // FALSE otherwise.

    bool Includes (const UI_Point& p) const;
    // Return TRUE if {\tt p} is inside or on the boundary of this
    // rectangle, and  FALSE otherwise.
    
    bool IntersectsBoundary (const UI_Rectangle& r) const;
    // Return TRUE if {\tt r}'s boundary intersects this Rectangle's.
    
    bool IsContainedIn (const UI_Rectangle& r) const;
    // Return TRUE if this Rectangle is contained entirely inside {\tt r}.

    CL_Sequence<UI_Point> RowMajor (long m, long n) const;
    // Imagine that the surface of this rectangle is ``tiled'' by a matrix
    // of sub-rectangles, each of which is $m$ units wide and $n$ units
    // high, and that the top left corner of the top left rectangle in the
    // matrix coincides with the top left corner of this rectangle. Return
    // the top left corners of the sub-rectangles, in row-major order, as a
    // sequence of points. The width of this rectangle must be divisible by
    // $m$, and the height must be divisible by $n$.
    

    // ------------------------ Geometric operations -----------------


    virtual bool Origin  (const UI_Point& o);
    // Set the origin (i.e., top left corner) to the given point, thus
    // moving the rectangle. Return TRUE on success, FALSE if a pre-change
    // dependent refused permission.

    virtual bool MoveTo  (const UI_Point& p);
    // Move the Rectangle so that the given point is its new center. Return
    // TRUE on success, FALSE if a pre-change dependent refused permission.

    
    virtual bool AddToHeight (long increment);
    // Add this value to the height. The parameter may be negative. This
    // method returns FALSE (refusing the change) if the parameter causes
    // the height to fall below zero. 
    
    virtual bool AddToWidth (long increment);
    // Add this value to the width. The parameter may be negative. This
    // method returns FALSE (refusing the change) if the parameter causes
    // the width to fall below zero. 

    virtual bool SetHeight (long newHeight);
    // Set the height of this rectangle. The return value is TRUE on
    // success, FALSE otherwise (e.g., if a negative height was specified).
    
    virtual bool SetWidth (long newWidth);
    // Set the width of this rectangle.
    
    UI_Rectangle operator+  (const UI_Vector&) const;
    // Return the rectangle obtained by translating this rectangle by the
    // given vector.

    virtual void operator+= (const UI_Vector& p) {*this = *this + p;};
    // Translate this Rectangle by the Vector {\tt p}.

    virtual bool ReshapeTo (const UI_Point& p1, const UI_Point& p2);
    // Reshape this Rectangle so that the two given points are its diagonally
    // opposite corners.
    
    // ------------------------- Drawing -------------------------------
    
    bool DrawOn (UI_DrawingSurface& sfc,
                 const UI_Point& p = UI_Point (0, 0)) const;
    // Override the method inherited from GraphicObject.
    
    bool Fill   (UI_DrawingSurface& s) const;
    // Fill the interior of this Rectangle on the given surface with the
    // current foreground color of the given surface.

        
    // ----------------------- Basic operations ------------------
    
    short Compare (const UI_Rectangle&) const;
    // Compare this Rectangle with the given one. Rectangle A is treated as
    // ``less than'' Rectangle B if B's top left corner occurs below and to
    // the right of A, or if B's top left corner is the same as A's but B is
    // smaller in width or height.
    
    short Compare (const CL_Object&) const;
    // Override the inherited method.
    
    void operator= (const CL_Object& );
    // Cast the parameter down to a Rectangle and assign it to this object.

    virtual UI_Rectangle& operator= (const UI_Rectangle& rect);
    // Assign {\tt rect} to this object.
    
    bool operator== (const CL_Object& r) const;
    // Determine if {\tt r} equals this Rectangle.

    bool operator== (const UI_Rectangle& r) const;
    // Determine if {\tt r} equals this Rectangle.

    CL_String AsString () const;
    // Return a string that looks like \verb|"(23, 15, 2, 3)"| (for x, y,
    // w, h).

    const char* ClassName () const {return "UI_Rectangle";};

    CL_Object* Clone () const {return new UI_Rectangle (*this);}
    
protected:
 
    UI_Point _origin; 
    long     _height;
    long     _width;


public:
#if defined(__MS_WINDOWS__) || defined(__MS_WIN32__)
    RECT AsMSRect () const;
    // [MS-Windows-specific: internal use only]

#endif
};




#endif
