

#ifndef _point_h_
#define _point_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


#include "base/map.h"
#include "base/binding.h"

#include "ui/vector.h"
#include "ui/graphic.h"

// Point is a class representing a point in an abstract two-dimensional
// coordinate system.
//
// Like the other GraphicObjects, the Point views its co-ordinate space as
// an abstract space not tied to any particular device. But its {\tt DrawOn}
// method views its dimension units as pixels.



class YACL_UI UI_Point: public UI_GraphicObject {

public:
   
    UI_Point (long x = 0, long y = 0);
    // Constructor. Create a Point at $(x, y)$.
    
    UI_Point (const UI_Point& );
    // Copy constructor.

    ~UI_Point () {};
    // Destructor: does nothing. Provided because Object's destructor is
    // pure virtual.
    
    long  XCoord() const {return x;};
    // Return the $x$ co-ordinate of this Point.

    long  YCoord() const {return y;};
    // Return the $y$ co-ordinate of this Point.

    double DistanceFrom (const UI_Point& p) const;
    // Return the Euclidean distance between this point and {\tt p}.
    
    void  AddToX (long value);
    // Add {\tt value} to  the $x$ co-ordinate. Thus if {\tt p} is a Point,
    // then {\tt p.AddToX (5)} has the same as {\tt p += UI_Vector (5, 0)}.
    
    void  AddToY (long value);
    // Add {\tt value} to  the $y$ co-ordinate. Thus if {\tt p} is a Point,
    // then {\tt p.AddToY (5)} has the same as {\tt p += UI_Vector (0, 5)}.

    bool DrawOn (UI_DrawingSurface& sfc, const UI_Point& p) const;
    // Draw this Point on {\tt sfc}, translated with respect to {\tt p}
    // (i.e., treating {\tt p} as the origin), using {\tt sfc}'s current brush.
    
    UI_Rectangle BoundingRectangle () const;
    // Return the bounding rectangle for this point. The rectangle has
    // height and width 1.

    short Compare (const UI_Point&) const;
    // Compare this Point with the given one. Point A is treated as ``less
    // than'' point B if A occurs above or to the left of B.
    
    short Compare (const CL_Object&) const;
    // Override the inherited method.
    
    UI_Point operator+ (const UI_Vector& v) const;
    // Return a Point obtained by translating this one by {\tt v}.

    void operator+=    (const UI_Vector& v) {*this = *this + v;};
    // Translate this Point by {\tt v}.
    
    UI_Point operator- (const UI_Vector&) const;
    // Return a Point obtained by translating this one by the negation of
    // {\tt v}.

    void operator-=    (const UI_Vector& v) {*this = *this - v;};
    // Translate this Point by the negation of {\tt v}.

    bool MoveTo (const UI_Point& p)
        {*this = p; /* The assignment does the notification */ return TRUE;};
    // Move this Point to {\tt p}. This is the same as assigning {\tt p} to
    // this Point. The return value is TRUE on success, FALSE if a
    // pre-change dependent refused permission.
    
    void operator= (const CL_Object&);
    // Cast the parameter down to a Point and assign it to this object.

    void operator= (const UI_Point&);
    // Assign the parameter to this Point.

    bool operator== (const CL_Object& p) const;
    // Cast the parameter down to a Point and return TRUE if it is the same
    // as this Point.

    bool operator== (const UI_Point& p) const;
    // Return TRUE if {\tt p} is the same as this Point.

    CL_String AsString() const;
    // Return a String representation of this Point, with co-ordinates
    // enclosed in parenthesis and separated by a comma. For instance the
    // String might look like \verb|"(23, 15)"|. 

    const char* ClassName () const {return "UI_Point";};
    
    CL_Object* Clone () const {return new UI_Point (*this);}
    

 

protected:
   
    long x;
    long y;
};


//[ Global
struct UI_PointPair {
    UI_PointPair (const UI_Point& p, const UI_Point& q) : p1 (p), p2(q) {};
    UI_PointPair () {};
    UI_Point p1, p2;
};
// This is a simple encapsulation of a pair of Points.
//] Global





inline bool UI_Point::operator== (const UI_Point& q) const
{
    return (q.x == x && q.y == y) ? TRUE : FALSE;
}



#endif
