// -*- C++ -*-

 namespace Katabatic {

 /*! \class        AutoContact
  *
  *  \brief        Abstract base class for AutoContact
  *
  *  \section      secACCache  Caching Mechanism
  *
  *                To bypass the Ring/Hook mechanism \e and the subsequent Session::Lookup()
  *                call, the AutoSegments anchored on an AutoContact are cached in the
  *                AutoContact itself. They can be accessed through \c getHorizontalN() and
  *                getVerticalN() accessors \c N depending on the subtype of AutoContact.
  *
  *                Cached AutoSegments are updated in the AutoContact::updateTopology()
  *                function only.
  *
  *
  *  \section      secACInvalidate  Invalidate on AutoContacts
  *
  *                The invalidation of an AutoContact invalidate all the segments
  *                that are anchored on it.
  *
  *                <b>Special Case of HTee & VTee</b>
  *
  *                When invalidating an HTee or VTee, two out of the three anchored
  *                segments are parallels. The \e aligned constraint is passed on
  *                those two. By default, when we invalidate an AutoSegment, the
  *                invalidation is applied to the whole aligned set through the
  *                AutoSegment::getAligneds() collection. So if one of the parallel
  *                is invalidated and the other not, it should only be because we
  *                are already in \c getAligneds(), then we do not want to invalidate
  *                again the whole aligned set. In that case, we perform an atomic only
  *                invalidation (reset Katabatic::KbPropagate).
  *
  *                For the complete invalidation/revalidation mechanism see
  *                \ref secSessionAlgo "Session Algorithm".
  *
  *
  *  \section      secDiffFromKatabatic2  Notes - Differences from Katabatic 2
  *
  *                From the previous version of Katabatic, AutoContact have
  *                been greatly stripped down (again). They are now always punctual
  *                objetcs with stricly fixed topologies:
  *                <ul>
  *                  <li>AutoContactTerminal to connect to a terminal (one segment).
  *                  <li>AutoContactTurn to make a turn: two perpandiculars segments.
  *                  <li>AutoContactHTee an horizontal tee: two \e aligned horizonals
  *                      and one vertical.
  *                  <li>AutoContactVTee an horizontal tee: two \e aligned verticals
  *                      and one horizontal.
  *                </ul>
  */

 //! \enum         AutoContactFlag
 //!               Set of flags to describe the internal state of an AutoContact.

 //! \var          AutoContactFlag::CntFixed
 //!               This contact cannot be moved.

 //! \var          AutoContactFlag::CntTerminal
 //!               This contact is anchored on a terminal (AutoContactTerminal), <b>must not be changed</b>.

 //! \var          AutoContactFlag::CntTurn
 //!               The object true class is AutoContactTurn, <b>must not be changed</b>.

 //! \var          AutoContactFlag::CntHTee
 //!               The object true class is AutoContactHTee, <b>must not be changed</b>.

 //! \var          AutoContactFlag::CntVTee
 //!               The object true class is AutoContactVTee, <b>must not be changed</b>.

 //! \var          AutoContactFlag::CntInvalidated
 //!               At least one AutoSegment of this contact has been moved, the contact
 //!               position must be recomputed (in the Session revalidation).

 //! \var          AutoContactFlag::CntInvalidatedCache
 //!               At least one AutoSegment has been broken or moved up, the connexity
 //!               must be checked and possibly corrected (in Session revalidation).

 //! \var          AutoContactFlag::CntInCreationStage
 //!               Sets only during the initial creation process.

 //! \var          AutoContactFlag::CntBadTopology
 //!               Something wrong has happened and the connexity of the AutoContact is
 //!               no longer ensured (too much or too less AutoSegments, too wide span of
 //!               AutoSegment layers).

 //! \function     Hook* AutoContact::getBodyHook ();
 //!               <em>Base class method proxy.</em>

 //! \function     Hook* AutoContact::getAnchorHook ();
 //!               <em>Base class method proxy.</em>

 //! \function     Component* AutoContact::getAnchor () const;
 //!               <em>Base class method proxy.</em>

 //! \function     Net* AutoContact::getNet () const;
 //!               <em>Base class method proxy.</em>

 //! \function     const Layer* AutoContact::getLayer () const;
 //!               <em>Base class method proxy.</em>

 //! \function     DbU::Unit  AutoContact::getX () const;
 //!               <em>Base class method proxy.</em>

 //! \function     DbU::Unit  AutoContact::getY () const;
 //!               <em>Base class method proxy.</em>

 //! \function     DbU::Unit  AutoContact::getDx () const;
 //!               <em>Base class method proxy.</em>

 //! \function     DbU::Unit  AutoContact::getDy () const;
 //!               <em>Base class method proxy.</em>

 //! \function     Point  AutoContact::getCenter () const;
 //!               <em>Base class method proxy.</em>

 //! \function     Point  AutoContact::getPosition () const;
 //!               <em>Base class method proxy.</em>

 //! \function     DbU::Unit  AutoContact::getWidth () const;
 //!               <em>Base class method proxy.</em>

 //! \function     DbU::Unit  AutoContact::getHalfWidth () const;
 //!               <em>Base class method proxy.</em>

 //! \function     DbU::Unit  AutoContact::getHeight () const;
 //!               <em>Base class method proxy.</em>

 //! \function     DbU::Unit  AutoContact::getHalfHeight () const;
 //!               <em>Base class method proxy.</em>

 //! \function     Components  AutoContact::getSlaveComponents () const;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setLayer ( const Layer* ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setWidth ( DbU::Unit ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setHeight ( DbU::Unit ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setSizes ( DbU::Unit w, DbU::Unit h ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setX ( DbU::Unit ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setY ( DbU::Unit ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setPosition ( DbU::Unit w, DbU::Unit h ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setPosition ( const Point& ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setDx ( DbU::Unit ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setDy ( DbU::Unit ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::setOffset ( DbU::Unit w, DbU::Unit h ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     void  AutoContact::translate ( const DbU::Unit& dx, const DbU::Unit& dy ) ;
 //!               <em>Base class method proxy.</em>

 //! \function     bool  AutoContact::isInCreationStage () const;
 //! \sreturn      \true if the AutoContact is still in it's initial creation stage.

 //! \function     bool  AutoContact::isInvalidated () const;
 //! \sreturn      \true if the some AutoSegment has changed and the AutoContact needs
 //!               to be repositionned (through a call to AutoContact::updateGeometry()).

 //! \function     bool  AutoContact::isInvalidatedCache () const;
 //! \sreturn      \true if the some AutoSegment has changed and the AutoContact
 //!               topology needs to be restored, as a gap may have appeared
 //!               (through a call to AutoSegment::updateTopology()).

 //! \function     bool  AutoContact::isTurn () const;
 //! \sreturn      \true if the dynamic type of the AutoContact is of type Turn.

 //! \function     bool  AutoContact::isTee ( unsigned int direction ) const;
 //! \sreturn      \true if the dynamic type of the AutoContact is either of type
 //!               AutoContactHTee or AutoContactVTee, according to \c direction.

 //! \function     bool  AutoContact::isHTee () const;
 //! \sreturn      \true if the dynamic type of the AutoContact is of type AutoContactHTee.

 //! \function     bool  AutoContact::isVTee () const;
 //! \sreturn      \true if the dynamic type of the AutoContact is of type AutoContactHTee.

 //! \function     bool  AutoContact::isFixed () const;
 //! \sreturn      \true if the AutoContact cannot be moved.

 //! \function     bool  AutoContact::hasBadTopology () const;
 //! \sreturn      \true if the AutoContact topology has been broken and a gap has appeared.
 //!               (sould not happen...)

 //! \function     bool  AutoContact::canDestroy ( unsigned int flags ) const;
 //! \sreturn      \true if the AutoContact could be destroyed, that is, no segments
 //!               remains anchored on it. If \c flags contains Katabatic::KbWarnOnError,
 //!               issue an error message.

 //! \function     bool  AutoContact::canMoveUp ( const AutoSegment* moved ) const;
 //! \sreturn      \true if \c segment can be moved up without triggering a topological
 //!               modification. It meaans that:
 //!                 - Without \c moved, the AutoContact needs only one layer.
 //!                 - \c moved go from \e below the AutoContact to \e above.

 //! \function     Contact* AutoContact::base () const;
 //! \sreturn      The Hurricane::Contact which is decorated.

 //! \function     size_t  AutoContact::getAllocateds ();
 //! \sreturn      The total number of AutoContact currently allocateds.

 //! \function     const Name&  AutoContact::getStaticName ();
 //! \sreturn      The name of the Hurricane::ExtensionGo slice.

 //! \function     const Name&  AutoContact::getName () const;
 //! \sreturn      The name of the Hurricane::ExtensionGo slice.

 //! \function     const Name&  AutoContact::getId () const;
 //! \sreturn      The unique \c identifer of the AutoSegment.

 //! \function     Box  AutoContact::getBoundingBox () const;
 //! \see          Contact::getBoundingBox().

 //! \function     GCell* AutoContact::getGCell () const;
 //! \sreturn      The GCell into which the AutoContact is located.

 //! \function     AutoSegment* AutoContact::getOpposite ( const AutoSegment* segment ) const;
 //! \sreturn      The AutoSegment other the same direction as \c segment, this is
 //!               only meaningful on AutoContactHTee or AutoContactVTee. It there is
 //!               no opposite, \c NULL is returned.

 //! \function     AutoSegment* AutoContact::getSegment ( unsigned int index ) const;
 //! \sreturn      The nth anchored AutoSegment. The index is significant:
 //!                 - \b 0 : first horizontal (\b h1).
 //!                 - \b 1 : second horizontal (\b h2).
 //!                 - \b 2 : first vertical (\b b1).
 //!                 - \b 3 : second vertical (\b b2).
 //!
 //!               Not all the indexes are filled for every AutoContact. For example
 //!               \c Turn have \b h1 and \b b1, and \c HTee have \b h1, \b h2 and
 //!               \b v1.

 //! \function     unsigned int  AutoContact::getMinDepth () const;
 //! \sreturn      The layer depth of the bottom layer of the AutoContact.

 //! \function     unsigned int  AutoContact::getMaxDepth () const;
 //! \sreturn      The layer depth of the top layer of the AutoContact.

 //! \function     void  AutoContact::getLengths ( DbU::Unit* lengths, AutoSegment::DepthLengthSet& processeds );
 //! \param        lengths     A table of DbU::Unit, the size of all routing layers used.
 //! \param        processeds  An AutoSegment sorted set holding all the already processeds
 //!                           AutoSegments.
 //!
 //!               Compute the lengths over the owning GCell of all the AutoSegments anchored
 //!               on this AutoContact. The lengths are added to the total length table
 //!               \c lengths. To avoid double accounting of the local AutoSegments
 //!               that have both source & target in the same GCell, we keep a set
 //!               of already processeds AutoSegments in \c processeds.

 //! \function     Box  AutoContact::getNativeConstraintBox () const;
 //! \sreturn      The native constraint box (that is, whithout any user constraints
 //!               applied). For AutoContactTerminal, this is the Box of the supporting
 //!               external component, and for all others the bounding box of the
 //!               owning GCell.

 //! \function     Interval  AutoContact::getUConstraints ( unsigned int direction ) const;
 //! \sreturn      The constraint interval in \c direction (that is, the relevant side
 //!               of the constraint box).

 //! \function     DbU::Unit  AutoContact::getCBXMin () const;
 //! \sreturn      The X coordinate of the bottom left corner of the constraint box.

 //! \function     DbU::Unit  AutoContact::getCBYMin () const;
 //! \sreturn      The Y coordinate of the bottom left corner of the constraint box.

 //! \function     DbU::Unit  AutoContact::getCBXMax () const;
 //! \sreturn      The X coordinate of the top right corner of the constraint box.

 //! \function     DbU::Unit  AutoContact::getCBYMax () const;
 //! \sreturn      The Y coordinate of the top right corner of the constraint box.

 //! \function     Box  AutoContact::getConstraintBox () const;
 //! \sreturn      The current constraint box: the native constraint box with all
 //!               the user's contraints applieds.

 //! \function     Box& AutoContact::intersectConstraintBox ( Box& box ) const;
 //! \sreturn      The intersection between \c box and the constraint box. The
 //!               result is stored into \c box and a reference to it is returned.

 //! \function     void  AutoContact::invalidate ( unsigned int flags=0 );
 //!               Invalidate the AutoContact, schedule it for revalidation in the
 //!               Session. If flag containt Katabatic::CntInvalidTopology,
 //!               the topology of the AutoContact will also be checked and
 //!               possible gap closeds.
 //!
 //!               The revalidations methods associated are:
 //!                 - AutoSegment::updateGeometry(), recompute the punctual contact position.
 //!                 - AutoSegment::updateTopology(), restore the connexity.

 //! \function     void  AutoContact::updateGeometry ();
 //!               Compute the new position of the AutoContact based on the AutoSegment
 //!               positions. The Session mechanism ensure that all AutoSegment are
 //!               set into their final positions before calling this updator.

 //! \function     void  AutoContact::updateTopology ();
 //!               Modificate the AutoContact topology to close any gap. This could
 //!               be by changing layer or creating a new dogleg on an incident
 //!               AutoSegment.

 //! \function     void  AutoContact::_getTopology ( Component*& anchor, Horizontal**& hs, Vertical**& vs, size_t sz );
 //! \param        anchor   The anchor, if any.
 //! \param        hs       The Hurricane::Horizontal anchored.
 //! \param        vs       The Hurricane::Vertical anchored.
 //! \param        sz       The size of boths \c hs & \c vs table passed as arguments.
 //!
 //!               Fill \c anchor , \c hs and \c vs with the components anchored on this
 //!               AutoContact.

 //! \function     void  AutoContact::showTopologyError ( const std::string& message );
 //!               Comprensive display of the topology of the AutoContact to ease the
 //!               debug work. Prepend with the error message \c message. Do no throw
 //!               an error.

 //! \function     void  AutoContact::checkTopology ();
 //!               Check for topology correctness (no gaps), display an error message
 //!               if needed.

 //! \function     void  AutoContact::setGCell ( GCell* gcell );
 //!               Set the owning GCell.

 //! \function     void  AutoContact::setCBXMin ( DbU::Unit xMin );
 //!               Set the lower left X coordinate of the constraint box.
 //!
 //! \remark       It cannot go outside the GCell bounding box.

 //! \function     void  AutoContact::setCBYMin ( DbU::Unit yMin );
 //!               Set the lower left Y coordinate of the constraint box.
 //!
 //! \remark       It cannot go outside the GCell bounding box.

 //! \function     void  AutoContact::setCBXMax ( DbU::Unit xMax );
 //!               Set the upper right X coordinate of the constraint box.
 //!
 //! \remark       It cannot go outside the GCell bounding box.

 //! \function     void  AutoContact::setCBYMax ( DbU::Unit yMax );
 //!               Set the upper right Y coordinate of the constraint box.
 //!
 //! \remark       It cannot go outside the GCell bounding box.

 //! \function     void  AutoContact::setConstraintBox ( const Box& box );
 //!               Set the constraint box.
 //!
 //! \remark       It cannot go outside the GCell bounding box.

 //! \function     bool  AutoContact::restrictConstraintBox ( DbU::Unit min, DbU::Unit max, unsigned int flags=KbWarnOnError );
 //! \param        min    The minimum of the restriction interval.
 //! \param        max    The maximum of the restriction interval.
 //! \param        flags  Gives the direction of the restriction.
 //! \return       \true if the restriction was actually applied.
 //!
 //!               Restrict the current constraint box but check if the restriction 
 //!               will not lead to an empty interval, in that case, do nothing and
 //!               return \false.


 /*! \class        LocatorHelper
  *
  *  \brief        Locator Helper Collection's Locators
  *
  *                Provide a small uniform walktough over the AutoSegments anchored
  *                on AutoContacts. The \c flags argument allows to choose between
  *                direction and include perpandiculars (in that case all segments
  *                are processeds).
  *
  *
  *  \section      secLocHelperImplementation  Implementation Details
  *
  *                As, at most, two horizontals and two verticals may be anchored on
  *                any AutoContact subtype, the locator helper perform a walk through
  *                a virtual table of 4 elements. The two first are the horizontals,
  *                the two last the verticals. The meaning of this index is consistent
  *                whith the \c index argument of AutoContact::getSegment(). When
  *                a segment is not present in an AutoContact, the \c getSegment()
  *                returns \c NULL and the LocatorHelper::progress() function will
  *                skip it.
  *
  *                The private methods:
  *                  - \c LocatorHelper::_min()
  *                  - \c LocatorHelper::_max()
  *
  *                Computes the bounds of \c _index according to the value of \c _flags:
  *                  - \c KbHorizontal : \c 0 to less than \c 2.
  *                  - \c KbVertical   : \c 2 to less than \c 4.
  *                  - \c KbHorizontal|KbVertical : \c 0 to less than \c 4.
  */

 //! \function     LocatorHelper::LocatorHelper ( AutoContact* contact, unsigned int flags );
 //!               Create a helper to iterate over the AutoSegments anchored on \c contact.
 //!               The \c flags arguments allow to select:
 //!                 - The direction: Katabatic::KbHorizontal or Katabatic::KbVertical.
 //!                 - Perpandicular inclusion: Katabatic::KbWithPerpands.
 //!
 //!               When setting KbWithPerpands, all the segments will be iterated over.
 //!               It may seems a somewhat contorted way of doing things, the reason is
 //!               the ability to share (an pass) flags directly between different
 //!               functions.

 //! \function     bool  LocatorHelper::isValid() const;
 //! \sreturn      \true if there is an AutoSegment to be processed.

 //! \function     AutoSegment* LocatorHelper::getSegment() const;
 //! \sreturn      The current AutoSegment. \c NULL if the loop is over.

 //! \function     void  LocatorHelper::progress();
 //! \sreturn      Go to the next AutoSegment.

 }