/**
 * This file describes IMGraph2D, a graphic object to manipulate basic geometrics.
 * Classes described here are:
 *  IMDrawable, IMGraphic, IMGraphic manipulation, and geometry manipulation.
 *
 *  IMGraphic manipulation:
 *        IGraphicHierarchy
 *        IGraphicIterator
 *        IGraphicGroup
 *        IGraphicGroupIterator
 *  Geometry manipulation:
 *        ILine
 *        IPolyline
 *        ICurve
 *        IEllipse
 *        IPolygon
 *        ILoop
 *        IArea
 *
 *   IBM Open Class Library
 *   (C) Copyright International Business Machines Corporation,  1997
 *   Licensed Material - Program-Property of IBM - All Rights Reserved.
 */

// Revision: 88 1.30.1.7 source/albert/graph2d/igraph2d.hpp, 2d, ioc.v400, 980918 

#ifndef _IGRAPH2D_
#define _IGRAPH2D_

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

class IGArea;
class IGCurve2D;
class IGEllipse2D;
class IGLine2D;
class IGPoint2D;

class IGrafPort;

class IGPolygon2D;
class IGPolyline2D;
class IGrafBundle;
class IGRect2D;
class IImageSamplingControl;
class IGrafMatrix;
class IPaint;
class ITransferMode;
class IMGraphic;

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#include <igarea2d.hpp>
#include <ibundles.hpp>
#include <igcurv2d.hpp>
#include <igloop2d.hpp>
#include <igarea2d.hpp>
#include <igline2d.hpp>
#include <imatrix.hpp>
#include <ideque2.h>
#include <imstrmbl.hpp>
#include <iprimtyp.hpp>

#if __IBMCPP__ >= 400
#pragma namemangling(compat)
#endif

#pragma pack(push,4)
#pragma enum(4)


/**
 * IMDrawable is an abstract base which allows a graphic object to draw itself.
 */

class IMDrawable : public IMSTREAMABLE {
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );
public:
  virtual   ~IMDrawable();

  /**
   * Draws the graphic to the specific IGrafPort. This is a pure virtual function.
   */
  virtual void  draw(IGrafPort& port) const = 0;

  /**
   * Tests two IMDrawables for equality, by determining whether the geometries are equal and the bundles are equal.
   */
  virtual bool operator==(const IMDrawable&) const;

  /**
   * Tests two IMDrawables for inequality, by seeing whether their geometries and bundles are different.
   */
 bool operator!=(const IMDrawable&) const;


protected:
  // Protected constructors for Abstract class

  /**
   * Protected default constructor.
   */
  IMDrawable ();

  /**
   * Protected copy constructor.
   */
  IMDrawable ( const IMDrawable& );

  /**
   * Protected assignment operator for Abstract class.
   */
  IMDrawable&   operator= ( const IMDrawable& source );

};

class IGraphicGroup;

/**
 * IMGraphic is an abstract base class derived from IMDrawable.
 * IMGraphic is an abstract base class derived from IMDrawable.
 * IMGraphic provides the protocols for constructing and deleting a 2-D graphic,
 * obtaining attribute information, transforming the graphic, finding the bounds of the
 * graphic, and detecting whether the graphic has been selected by the user (hit detection).
 */

class IMGraphic: public IMDrawable
{
protected :
  virtual void writeToStream( IDataStream& toWhere ) const;
  virtual void readFromStream( IDataStream& toWhere );

public:
  virtual ~IMGraphic();

  /**
   * Draws the graphic to the specific IGrafPort.
   */
  virtual void draw (IGrafPort& port) const = 0;

  /**
   * Gets the bounding rectangle of the geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const = 0;

  /**
   * Gets the entire graphic's bounding rectangle, taking into account the bundle information.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;

  /**
   * Transforms the graphic's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&) = 0;

  // PVM: Should we keep these convenience functions?

  /**
   * Changes the graphic's size according to the specified horizontal and vertical scalars.
   * Changes the graphic's size according to the specified horizontal and vertical scalars.
   * Calls transformBy by default.
   */
  virtual void scaleBy(
               const IGPoint2D&,
               const IGPoint2D& centerOfScale=
               IGPoint2D::origin());

  /**
   * Rotates the graphic by the given number of degrees, using the specified center of rotation.
   * Rotates the graphic by the given number of degrees, using the specified center of rotation.
   * Calls tranformBy by default.
   */
  virtual void rotateBy(
                GDegrees,
                const IGPoint2D& centerOfRotation=
                IGPoint2D::origin());

  /**
   * Moves the graphic's position by the specified vector.
   */
  virtual void translateBy(const IGPoint2D&);

  /**
   * Adopts the specified bundle to determine the graphic's attributes.
   */
  virtual void adoptBundle(IGrafBundle* adoptedBundle );

  /**
   * Relinquishes knowledge of, and responsibility for, the IMGraphic's bundle, returning it to the caller.
   */
  virtual IGrafBundle* orphanBundle();

  /**
   * Gets the bundle, keeping it available for the IMGraphic.
   */
  virtual const IGrafBundle* bundle( ) const;

  /**
   * Adopts the specified attribute bundle to determine the graphic's attributes.
   */
  virtual void adoptAttributeState( IAttributeState* adoptedAttributeState);

  /**
   * Relinquishes knowledge of, and responsibility for, the IMGraphic's attribute bundle, returning it to the caller.
   */
  virtual IAttributeState* orphanAttributeState();

  /**
   * Gets the attribute bundle, keeping it available for the IMGraphic.
   */
  virtual const IAttributeState*  attributeState() const;

  /**
   * Tests the IMGraphic and the IMDrawable for equality. The base class only tests whether the two bundles have equal contents.
   */
  virtual bool operator==(const IMDrawable&) const;

public:
	/**
	 * Hit flag is set to false and hit detection is enabled.
	 * Moved from protected for streaming.
	 */
    IMGraphic();

protected:

  /**
   */
  IMGraphic (IGrafBundle* adoptedBundle);

  /**
   */
  IMGraphic ( const IMGraphic& ); // Copy constructor

  /**
   * Assignment operator.
   */
  IMGraphic&   operator= ( const IMGraphic& source );

  /**
   * Updates the object's time stamp.
   */
  virtual void updateTimeStamp();

  /**
   * Sets the time stamp to zero.
   */
  virtual void resetTimeStamp();

  /**
   * Sets the time stamp to the specified value.
   */
  virtual void setTimeStamp(const unsigned long&);

  /**
   * Gets the object's time stamp.
   */
  virtual unsigned long timeStamp() const;


private:

friend class IGraphicGroup;
friend class ILine;
friend class IPolyline;
friend class ICurve;
friend class IEllipse;
friend class IPolygon;
friend class ILoop;
friend class IArea;
friend class IHitGraphicGroupIterator;
 // IHitGraphicGroupIterator::first
 // IHitGraphicGroupIterator::last
 // IHitGraphicGroupIterator::next
 // IHitGraphicGroupIterator::previous
  /**
   * Tests if this geometry intersects with the specified rectangle.
   * It also handles any de-generated rectangle which encloses zero area.
   * If this object is not "hitEnabled", the function returns false.
   *                    encloses the rectangle.
   */
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Returns true if this geometry is hitEnabled.
   */
  bool              isHitEnabled () const;

friend class IProgressIndicator; // IProgressIndicator::setTickText
friend class IProgressIndicatorData; // IProgressIndicatorData::createNativeSlider
  /**
   * Sets the hitEnabled flag of this geometry.
   */
  void              setHitEnabled (bool  flag = true);

protected:
  //
  // This is used to cache/set the 'hit' state in the base class and is
  // intended to be used only by sub-classes.
  //

  void              setHit (bool  flag);


private:
friend class ISeed;
  static const unsigned long& seed();

  IAttributeState*  fBundle;
  unsigned long     fSeed;
  bool              fHitFlag;
  bool              fHitEnableFlag;

};

class IGraphicIterator;

/**
 * IGraphicHierarchy is an abstract base class that defines a hierarchy protocol.
 * IGraphicHierarchy is an abstract base class that defines a hierarchy protocol.
 * This is the only class that has the protocol for creating an iterator which allows hierarchies
 * to traverse themselves. All clients must define their own set of hierarchies using this abstract
 * base class as its parent class.
 */

class IGraphicHierarchy: public IMGraphic {
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );
public:
  virtual ~IGraphicHierarchy ();

  /**
   * Creates a IGraphicIterator which iterates through the first level of the hierarchy.
   */
  virtual IGraphicIterator* createIterator() const = 0;

  /**
   * Draws the IGraphicHierarchy to the specific IGrafPort.
   */
  virtual void draw(IGrafPort&) const = 0;

  /**
   * Transforms the IGraphicHierarchy's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&) = 0;

  /**
   * Gets the bounding rectangle of the IGraphicHierarchy's geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const = 0;

  /**
   * Gets the bounding rectangle of the IGraphicHierarchy's geometry, taking into account any area added by the bundle.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const = 0;


/*********** do we need these
  // === Base Functionality ===
  bool operator== ( const IGraphicHierarchy& source ) const;
  bool operator!=(const IGraphicHierarchy&) const;
********************/

  /**
   * Tests the IGraphicHierarchy and the IMDrawable for equality.
   * Tests the IGraphicHierarchy and the IMDrawable for equality.
   * The base class only tests whether the two bundles have equal contents.
   */
  virtual bool operator==(const IMDrawable&) const;

protected:
  /**
   * Protected default constructor.
   */
  IGraphicHierarchy ();

  /**
   * Protected copy constructor.
   */
  IGraphicHierarchy ( const IGraphicHierarchy& );

  /**
   * Constructs an IGraphicHierarchy from a graph bundle.
   */
  IGraphicHierarchy (IGrafBundle* adoptBundle);

  /**
   * Copy operator.
   */
  IGraphicHierarchy& operator= ( const IGraphicHierarchy& source );

};

/**
 * IGraphicIterator is an abstract base class that allows iteration of a hierarchy.
 * IGraphicIterator is an abstract base class that allows iteration of a hierarchy.
 * This is an abstract base class and there is no implementation of this class.
 * By default TGraphicroup creates a shallow iterator which traverses only a one level.
 * In order to iterate thru the entire hierarchy the iterators should be created recursively.
 */

class IGraphicIterator {
    public:
      virtual                           ~IGraphicIterator ();

  /**
   * Resets this IGraphicIterator to the first IMGraphic in the hierarchy.
   */
  virtual void reset () = 0;

  /**
   * Gets the first IMGraphic in the hierarchy.
   */
  virtual IMGraphic* first() = 0;

  /**
   * Gets the last IMGraphic in the hierarchy.
   */
  virtual IMGraphic* last () = 0;

  /**
   * Increments the iterator and returns a pointer to that IMGraphic.
   */
  virtual IMGraphic* next () = 0;

  /**
   * Decrements the iterator and returns a pointer to that IMGraphic.
   */
  virtual IMGraphic* previous () = 0;

  protected:

  /**
   * Protected default constructor.
   */
  IGraphicIterator ();
};

/**
 * IGraphicGroup is a concrete class, derived from IGraphicHierarchy.
 * IGraphicGroup is a concrete class, derived from IGraphicHierarchy.
 * IGraphicGroup implements a conglomeration of graphics as a tree structure.
 * All children of the group are fullyt owned. This implementation
 * limits the creation of Trees only i.e. DAGS are not yet supported.
 *  Later utilities may be provided for the support of DAGs.
*/

class IGraphicGroup : public IGraphicHierarchy  {
        StreamableDeclarationsMacro(IGraphicGroup);
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );
public:
  typedef IVPtrDeque<IMGraphic*> GraphicDeque;

  /**
   * Default constructor. Creates a zero bounds.
   */
  IGraphicGroup();

  /**
   * Copy constructor.
   */
  IGraphicGroup(const IGraphicGroup&);

  /**
   * Constructs an IGraphicGroup and adopts the specified bundle.
   */
  IGraphicGroup( IGrafBundle* adoptedBundle);

  virtual ~IGraphicGroup();

  /**
   * Adopts the specified IMGraphic as the last child in the hierarchy.
   */
  virtual void      adoptLast(IMGraphic* obj);

  /**
   * Adopts the specified IMGraphic as the first child in the hierarchy.
   */
  virtual void      adoptFirst(IMGraphic* obj);

  /**
   * Orphans the specified IMGraphic.
   */
  virtual IMGraphic*    orphan(const IMGraphic& obj);

  /**
   * Orphans the last child in the hierarchy.
   */
  virtual IMGraphic*    orphanLast();

  /**
   * Orphans the first child in the hierarchy.
   */
  virtual IMGraphic*    orphanFirst();

  /**
   * Determines how many IMGraphics are in this IGraphicGroup.
   */
  virtual long      count() const;

  /**
   * Creates a IGraphicGroupIterator that iterates this IGraphicGroup's children.
   */
  virtual IGraphicIterator* createIterator() const;

  /**
   */
  virtual void draw (IGrafPort& port) const;
  virtual void transformBy (const IGrafMatrix&);
  virtual IGRect2D geometricBounds() const;
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Gets this IGraphicGroup's IGrafMatrix.
   */
  const IGrafMatrix* matrix() const;

  IGraphicGroup& operator= ( const IGraphicGroup& source );
  virtual bool operator==(const IMDrawable&) const;

private:

  //virtual IGArea* createArea() const { return 0 /*NIL*/; }

  void deleteAll ();    //convenience function

  IGrafMatrix     fMatrix;
  GraphicDeque fChildren;

  IGRect2D          fBounds;
  unsigned long fBoundsTimeStamp;
  friend class    IGraphicGroupIterator;
};

class IGraphicGroup;

/**
 * IGraphicIterator is used for building a hierarchical structure comprised of graphic objects.
 * IGraphicIterator is used for building a hierarchical structure comprised of graphic objects.
 * This class contains functions useful for traversing and managing this hierarchical tree.
 */
class IGraphicGroupIterator: public IGraphicIterator{
    public:
    IGraphicGroupIterator(const IGraphicGroup*);
    virtual                         ~IGraphicGroupIterator();

    virtual void reset();
    virtual IMGraphic* first();
    virtual IMGraphic* last();
    virtual IMGraphic* next();
    virtual IMGraphic* previous();
    private:

    IGraphicGroup::GraphicDeque :: Cursor fIterator;
};

/**
 * ILine is a wrapper for the geometry IGLine. It is used for drawing line segments.
 * ILine is a wrapper for the geometry IGLine. It is used for drawing line segments.
 * IInfiniteLine is not supported. Users wishing to use should subclass to for usage.
 */

class ILine: public IMGraphic {

    StreamableDeclarationsMacro(ILine);

protected :
    virtual void writeToStream( IDataStream& toWhere ) const;
    virtual void readFromStream( IDataStream& toWhere );

public:

  /**
   * Default constructor. Constructs an ILine which has an empty geometry.
   */
  ILine ();

  /**
   * Copy constructor.
   */
  ILine ( const ILine& );

  /**
   * Constructor that takes an IGLine and an IGrafBundle as parameters.
   */
  ILine (IGLine2D* adoptLine, IGrafBundle* adoptBundle = 0 /*NIL*/ );

  virtual ~ILine ();

   /**
    * Takes over the ownership of a geometry after deleting any existing geometries.
    */
  virtual void adoptGeometry(IGLine2D*);

   /**
    * Returns the ownership of a geometry to the caller.
    */
  virtual IGLine2D* orphanGeometry();

   /**
    * Returns an alias for accessing counterpart geometry.
    */
  virtual const IGLine2D* geometry();

  /**
   * Draws the ILine to the specific IGrafPort.
   */
  virtual void draw(IGrafPort&) const;

  /**
   * Transforms the graphic's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&);

  /**
   * Gets the bounding rectangle of the geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const;

  /**
   * Gets the entire graphic's bounding rectangle, taking into account the bundle information.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;

  /**
   * Checks if this line intersects with the specified rectangle.
   * Checks if this line intersects with the specified rectangle.
   * It also handles any de-generated rectangle which encloses zero area.
   * If this line is not "hitEnabled", the function returns false.
   */
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Assignment operator.
   */
  ILine& operator= ( const ILine& source );

  /**
   * Tests this ILine and IMDrawable for equality, by determining whether the geometries are equal and the bundles are equal.
   */
  virtual bool operator==(const IMDrawable&) const;

private:
  IGLine2D* fLine;
  unsigned long fBoundsTimeStamp;
};

  /**
   * IPolyline provides a wrapper for the IGPolyline geometry class.
   * IPolyline provides a wrapper for the IGPolyline geometry class.
   * A polyline is a collection of points that are connected with straight line segments.
   * Polylines are parameterized, much like linear curves.
   */
class IPolyline: public IMGraphic {
        StreamableDeclarationsMacro(IPolyline);
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );
public:
  /**
   * Default constructor. Constructs an IPolyline which has an empty geometry and empty bounds.
   */
  IPolyline ();

  /**
   * Copy constructor. Copies the IGPolyline2D and sets the bounds to empty.
   */
  IPolyline ( const IPolyline& );

  /**
   * Constructs an IPolyline by adopting an IGPolyline2D and an IGrafBundle.
   */
  IPolyline (IGPolyline2D* adoptPolyline, IGrafBundle* adoptBundle = 0 /*NIL*/ );

  virtual ~IPolyline ();

  /**
   * Takes over the ownership of a geometry after deleting any existing geometries.
   */
  virtual void adoptGeometry(IGPolyline2D*);

  /**
   * Returns the ownership of a geometry to the caller.
   */
  virtual IGPolyline2D* orphanGeometry();

  /**
   * Returns an alias for accessing counterpart geometry.
   */
  virtual const IGPolyline2D* geometry();

  /**
   * Draws the IPolyline to the specific IGrafPort.
   */
  virtual void draw(IGrafPort&) const;

  /**
   * Transforms the graphic's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&);

  /**
   * Gets the bounding rectangle of the geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const;

  /**
   * Gets the entire graphic's bounding rectangle, taking into account the bundle information.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;

  /**
   * Tests if this polyline intersects with the specified rectangle.
   * Tests if this polyline intersects with the specified rectangle.
   * It also handles any de-generated rectangle which encloses zero area.
   * If this polyline is not "hitEnabled", the function returns false.
   */
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Assignment operator.
   */
  IPolyline& operator= ( const IPolyline& source );

  /**
   * Tests this IPolyLine and IMDrawable for equality, by determining whether the geometries are equal and the bundles are equal.
   */
  virtual bool operator==(const IMDrawable&) const;

private:
  IGPolyline2D* fPolyline;
  IGRect2D* fBounds;
  unsigned long fBoundsTimeStamp;
};

/**
 * ICurve provides a wrapper for the TGCurve geometry class.
 * ICurve provides a wrapper for the TGCurve geometry class.
 * A TGCurve is a Non-Uniform Rational B-Spline (NURB) of arbitrary degree.
 */

class ICurve: public IMGraphic {
        StreamableDeclarationsMacro(ICurve);
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );

public:
  /**
   * Default constructor. Constructs an ICurve which has an empty geometry and empty bounds.
   */
  ICurve ();

  /**
   * Copy constructor. Copies the IGCurve2D and the matrix. Sets the bounds to empty.
   */
  ICurve ( const ICurve& );

  /**
   * Constructs an ICurve by adopting an IGCurve2D and an IGrafBundle.
   */
  ICurve (IGCurve2D* adoptCurve, IGrafBundle* adoptBundle = 0 /*NIL*/ );

  virtual ~ICurve ();

  /**
   * Takes over the ownership of a geometry after deleting any existing geometries.
   */
  virtual void adoptGeometry(IGCurve2D*);

  /**
   * Returns the ownership of a geometry to the caller.
   */
  virtual IGCurve2D* orphanGeometry();

  /**
   * Returns an alias for accessing counterpart geometry.
   */
  virtual const IGCurve2D* geometry();

  /**
   * Draws the ICurve to the specific IGrafPort.
   */
  virtual void draw(IGrafPort&) const;

  /**
   * Transforms the graphic's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&);

  /**
   * Gets the bounding rectangle of the geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const;

  /**
   * Gets the entire graphic's bounding rectangle, taking into account the bundle information.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;

  /**
   * Tests if this curve intersects with the specified rectangle.
   * Tests if this curve intersects with the specified rectangle.
   * It also handles any de-generated rectangle which encloses zero area.
   * If this curve is not "hitEnabled", the function returns false.
   */
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Assignment operator.
   */
  ICurve& operator= ( const ICurve& source );

  /**
   * Tests this ICurve and IMDrawable for equality, by determining whether the geometries are equal and the bundles are equal.
   */
  virtual bool operator==(const IMDrawable&) const;

private:
  IGCurve2D* fCurve;
  IGRect2D* fBounds;
  unsigned long fBoundsTimeStamp;
  IGrafMatrix fMatrix;
};

/**
 * IEllipse provides a wrapper for the IGEllipse geometry class.
 * IEllipse provides a wrapper for the IGEllipse geometry class.
 * IGEllipse is a vertically or horizontally oriented ellipse.
 * IEllipse has a IGrafMatrix that is used to concatenate all transformations.
 */

class IEllipse: public IMGraphic {
        StreamableDeclarationsMacro(IEllipse);
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );

public:
  /**
   * Default constructor. Constructs an IEllipse which has an empty geometry and empty bounds.
   */
  IEllipse ();

  /**
   * Copy constructor. Copies the IGEllipse2D and the matrix. Sets the bounds to empty.
   */
  IEllipse ( const IEllipse& );

  /**
   * Constructs an IEllipse by adopting an IGEllipse2D and an IGrafBundle.
   */
  IEllipse (IGEllipse2D* adoptEllipse, IGrafBundle* adoptBundle = 0 /*NIL*/ );

  virtual ~IEllipse ();

  /**
   * Takes over the ownership of a geometry after deleting any existing geometries.
   */
  virtual void adoptGeometry(IGEllipse2D*);

  /**
   * Returns the ownership of a geometry to the caller.
   */
  virtual IGEllipse2D* orphanGeometry();

  /**
   * Returns an alias for accessing counterpart geometry.
   */
  virtual const IGEllipse2D* geometry();

  /**
   * Draws the IEllipse to the specific IGrafPort.
   */
  virtual void draw(IGrafPort&) const;

  /**
   * Transforms the graphic's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&);

  /**
   * Gets the bounding rectangle of the geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const;

  /**
   * Gets the entire graphic's bounding rectangle, taking into account the bundle information.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;

  /**
   * Tests if this ellipse intersects with the specified rectangle.
   * Tests if this ellipse intersects with the specified rectangle.
   * It also handles any de-generated rectangle which encloses zero area.
   * If this ellipse is not "hitEnabled", the function returns false.
   */
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Assignment operator.
   */
  IEllipse& operator= ( const IEllipse& source );

  /**
   * Tests this IEllipse and IMDrawable for equality, by determining whether the geometries are equal and the bundles are equal.
   */
  virtual bool operator==(const IMDrawable&) const;

private:
  IGEllipse2D* fEllipse;
  IGRect2D* fBounds;
  unsigned long fBoundsTimeStamp;
  IGrafMatrix fMatrix;
};

/**
 * IPolygon provides a wrapper for the IGPolygon geometry class.
 * IPolygon provides a wrapper for the IGPolygon geometry class.
 * An IGPolygon is a collection of points connected by straight line segments, with the last
 * point automatically connected to the first, closing the path.
 */

class IPolygon: public IMGraphic {
        StreamableDeclarationsMacro(IPolygon);
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );

public:
  /**
   * Default constructor. Constructs an IPolygon which has an empty geometry and empty bounds.
   */
  IPolygon ();

  /**
   * Copy constructor. Copies the IGPolygon2D and sets the bounds to empty.
   */
  IPolygon ( const IPolygon& );

  /**
   * Constructs an IPolygon by adopting an IGPolygon2D and an IGrafBundle.
   */
  IPolygon (IGPolygon2D* adoptPolygon, IGrafBundle* adoptBundle = 0 /*NIL*/ );

  virtual ~IPolygon ();

  /**
   * Takes over the ownership of a geometry after deleting any existing geometries.
   */
  virtual void adoptGeometry(IGPolygon2D*);

  /**
   * Returns the ownership of a geometry to the caller.
   */
  virtual IGPolygon2D* orphanGeometry();

  /**
   * Returns an alias for accessing counterpart geometry.
   */
  virtual const IGPolygon2D* geometry();

  /**
   * Draws the IPolygon to the specific IGrafPort.
   */
  virtual void draw(IGrafPort&) const;

  /**
   * Transforms the graphic's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&);

  /**
   * Gets the bounding rectangle of the geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const;

  /**
   * Gets the entire graphic's bounding rectangle, taking into account the bundle information.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;

  /**
   * Tests if this polygon intersects with the specified rectangle.
   * Tests if this polygon intersects with the specified rectangle.
   * It also handles any de-generated rectangle which encloses zero area.
   * If this polygon is not "hitEnabled", the function returns false.
   */
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Assignment operator.
   */
  IPolygon& operator= ( const IPolygon& source );

  /**
   * Tests this IPolygon and IMDrawable for equality, by determining whether the geometries are equal and the bundles are equal.
   */
  virtual bool operator==(const IMDrawable&) const;

private:
  IGPolygon2D* fPolygon;
  IGRect2D* fBounds;
  unsigned long fBoundsTimeStamp;
};


/**
 * ILoop provides a wrapper for the IGLoop geometry class.
 * ILoop provides a wrapper for the IGLoop geometry class.
 * ILoop can be used for such shapes as rounded rectangles, ellipses with control points, and
 * more elaborate closed paths. Users wishing to modify Ellipses with control points and create
 * fancy shapes should use this class.
 */

class ILoop: public IMGraphic {
        StreamableDeclarationsMacro(ILoop);
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );

public:
  /**
   * Default constructor. Constructs an ILoop which has an empty geometry and empty bounds.
   */
  ILoop ();

  /**
   * Copy constructor. Copies the IGLoop2D and sets the bounds to empty.
   */
  ILoop ( const ILoop& );

  /**
   * Constructs an ILoop by adopting an IGLoop2D and an IGrafBundle.
   */
  ILoop (IGLoop2D* adoptLoop, IGrafBundle* adoptBundle = 0 /*NIL*/ );

  virtual ~ILoop ();

  /**
   * Takes over the ownership of a geometry after deleting any existing geometries.
   */
  virtual void adoptGeometry(IGLoop2D*);

  /**
   * Returns the ownership of a geometry to the caller.
   */
  virtual IGLoop2D* orphanGeometry();

  /**
   * Returns an alias for accessing counterpart geometry.
   */
  virtual const IGLoop2D* geometry();

  /**
   * Draws the ILoop to the specific IGrafPort.
   */
  virtual void draw(IGrafPort&) const;

  /**
   * Transforms the graphic's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&);

  /**
   * Gets the bounding rectangle of the geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const;

  /**
   * Gets the entire graphic's bounding rectangle, taking into account the bundle information.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;

  /**
   * Tests if this loop intersects with the specified rectangle.
   * Tests if this loop intersects with the specified rectangle.
   * It also handles any de-generated rectangle which encloses zero area.
   * If this loop is not "hitEnabled", the function returns false.
   */
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Assignment operator.
   */
  ILoop& operator= ( const ILoop& source );

  /**
   * Tests this ILoop and IMDrawable for equality, by determining whether the geometries are equal and the bundles are equal.
   */
  virtual bool operator==(const IMDrawable&) const;

private:
  IGLoop2D* fLoop;
  IGRect2D* fBounds;
  IGrafMatrix fMatrix;
  unsigned long fBoundsTimeStamp;
};

/**
 * IArea provides a wrapper for the IGArea geometry class.
 * IArea provides a wrapper for the IGArea geometry class.
 * The IGArea class defines an arbitrarily-shaped area by performing certain binary CAG (Constructive Area Geometry)
 * operations to combine other area-defining geometries.
 */

class IArea: public IMGraphic {
        StreamableDeclarationsMacro(IArea);
    protected :
        virtual void writeToStream( IDataStream& toWhere ) const;
        virtual void readFromStream( IDataStream& toWhere );

public:
  /**
   * Default constructor. Constructs an IArea which has an empty geometry and empty bounds.
   */
  IArea ();

  /**
   * Copy constructor. Copies the IGArea and sets the bounds to empty.
   */
  IArea ( const IArea& );

  /**
   * Constructs an IArea by adopting an IGArea and an IGrafBundle.
   */
  IArea (IGArea* adoptArea, IGrafBundle* adoptBundle = 0 /*NIL*/ );

  virtual ~IArea ();

  /**
   * Takes over the ownership of a geometry after deleting any existing geometries.
   */
  virtual void adoptGeometry(IGArea*);

  /**
   * Returns the ownership of a geometry to the caller.
   */
  virtual IGArea* orphanGeometry();

  /**
   * Returns an alias for accessing counterpart geometry.
   */
  virtual const IGArea* geometry();

  /**
   * Draws the IArea to the specific IGrafPort.
   */
  virtual void draw(IGrafPort&) const;

  /**
   * Transforms the graphic's shape and position by applying the specified transformation matrix.
   */
  virtual void transformBy(const IGrafMatrix&);

  /**
   * Gets the bounding rectangle of the geometry, without considering any area added by the bundle.
   */
  virtual IGRect2D geometricBounds() const;

  /**
   * Gets the entire graphic's bounding rectangle, taking into account the bundle information.
   */
  virtual IGRect2D looseFitBounds(const IGrafPort* = 0 /*NIL*/) const;

  /**
   * Tests if this area intersects with the specified rectangle.
   * Tests if this area intersects with the specified rectangle.
   * It also handles any de-generated rectangle which encloses zero area.
   * If this area is not "hitEnabled", the function returns false.
   */
  virtual bool      intersects (const IGRect2D &   rect) const;

  /**
   * Assignment operator.
   */
  IArea& operator= ( const IArea& source );

  /**
   * Tests this IArea and IMDrawable for equality, by determining whether the geometries are equal and the bundles are equal.
   */
  virtual bool operator==(const IMDrawable&) const;

private:
  IGArea* fArea;
  IGRect2D* fBounds;
  unsigned long fBoundsTimeStamp;
};

#pragma enum(pop)
#pragma pack(pop)

#if __IBMCPP__ >= 400
#pragma namemangling()
#endif

#endif // _IGRAPH2D_
