

#ifndef _arc_h_ /* Thu Jan  5 09:27:04 1995 */
#define _arc_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.
 *
 */



// This is a GraphicObject representing an arc of an ellipse. The ellipse is
// assumed to have its axes parallel to the co-ordinate axes. An Arc can be
// defined by an ellipse, together with a start angle and a subtended angle.
// Both angles are measured with respect to the 3-o'clock position, i.e.,
// the vector drawn from the center of the ellipse horizontally toward the
// right. An Arc can also be defined by three points, namely the center of
// the ellipse and the two end-points of the arc on the ellipse's periphery.
//
// The Arc class supports all the behavior inherited from GraphicObject, as
// well as the translation {\tt operator+} to move the Arc from one position
// to another.
//
// Like the other GraphicObjects, the Arc 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.



#if defined(__GNUC__)
#pragma interface
#endif

#include "ui/rectangl.h"

class YACL_UI UI_Rectangle;
class YACL_UI UI_Point;
class YACL_UI UI_Ellipse;

class YACL_UI UI_Arc: public UI_GraphicObject {

public:
    UI_Arc (const UI_Rectangle& boundingRect, long startAngleDeg64, long
            subtendedDeg64);
    // Construct an arc of an ellipse. The arc is part of the ellipse whose
    // bounding rectangle is {\tt boundingRect}. Its starting point is at an
    // angle $d$ degrees from the 3-o'clock position of {\tt boundingRect}
    // where $d = {\tt startAngleDeg64} * 64$, and it subtends an angle $s$
    // at the center of the ellipse, where $s = {\tt subtendedDeg64} * 64$,

    UI_Arc (const UI_Point& p1, const UI_Point& p2, const UI_Point& origin);
    // Construct an arc of an ellipse with the points {\tt p1} and {\tt p2}
    // being the start point and the end point and the origin being the
    // center of the ellipse. If {\tt p1 == p2} the arc is just a single
    // point.

    UI_Arc ();
    
    bool DrawOn (UI_DrawingSurface& sfc,
                 const UI_Point& p = UI_Point (0,0)) const;
    // Draw this arc on the given surface {\tt sfc}. This method overrides
    // the inherited virtual method.

    bool ReshapeTo (const UI_Point& p1, const UI_Point& p2);
    // Override method inherited from GraphicObject. The implementation
    // reshapes the arc so that the bounding rectangle of the containing
    // ellipse is the rectangle whose diagonally opposite points are {\tt
    // p1} and {\tt p2}.


    UI_Rectangle BoundingRectangle() const;
    // Return the bounding rectangle of the ellipse of which this arc is
    // part.

    UI_PointPair EndPoints () const;
    // Return the two end-points of the arc.

    bool IntersectsBoundary (const UI_Rectangle& r) const;
    // Return TRUE if the Rectangle {\tt r} intersects the boundary of this
    // Arc. [Not yet correctly implemented]

    UI_HitTest HitTest (const UI_Point& p) const;
    // Hit testing: return an indication of whether {\tt p} hits this Arc.
    // This method overrides the one inherited from GraphicObject. This method
    // always returns either Outside or Boundary, never Inside, because
    // there is no ``inside'' of an arc. The only exception is if this arc
    // is really a complete ellipse, and you cannot construct such an arc.
    
    long StartAngle() const;
    // Return the start angle of the arc, with respect to the 3-o'clock
    // position of the bounding rectangle, in sixty-fourths of a degree.

    long SubtendedAngle() const;
    // Return the subtended angle in sixty-fourths of a degree.

    UI_Ellipse Ellipse () const;
    // Return the Ellipse of which this Arc is part.

    virtual bool StartAngle (long startAngle64);
    // Set the start angle of this Arc. The parameter is in sixty-fourths of
    // a degree. Return TRUE on success, FALSE on failure (e.g., a
    // pre-change dependent refused permission).

    virtual bool SubtendedAngle (long subtAngle64);
    // Set the subtended angle of this Arc. The parameter is in
    // sixty-fourths of a degree. Return TRUE on success, FALSE on failure
    // (e.g., a pre-change dependent refused permission).

    virtual bool MoveTo (const UI_Point& p);
    // Reposition this Arc so that the center of the containing ellipse is
    // the given point. Return TRUE on success, FALSE on failure
    // (e.g., a pre-change dependent refused permission).
    
    UI_Arc operator+  (const UI_Vector&) const;
    // Return the Arc obtained by translating this Arc by the
    // given vector.

    virtual UI_Arc& operator= (const UI_Arc&);

    void operator= (const CL_Object&);
    
    virtual void operator+= (const UI_Vector& p);
    // Translate (i.e., move) this Arc by the given Vector.

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

    CL_Object* Clone () const {return new UI_Arc (*this);}
    
protected:

    UI_Rectangle _boundingRect;
    long         _startAngle  ;
    long         _subtAngle   ;
};




inline long UI_Arc::StartAngle() const
{
    return _startAngle;
}


inline long UI_Arc::SubtendedAngle() const
{
    return _subtAngle;
}


#endif /* _arc_h_ */

