// -*- 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.
*
* Special Case of HTee & VTee
*
* 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:
*
* - AutoContactTerminal to connect to a terminal (one segment).
*
- AutoContactTurn to make a turn: two perpandiculars segments.
*
- AutoContactHTee an horizontal tee: two \e aligned horizonals
* and one vertical.
*
- AutoContactVTee an horizontal tee: two \e aligned verticals
* and one horizontal.
*
*/
//! \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), must not be changed.
//! \var AutoContactFlag::CntTurn
//! The object true class is AutoContactTurn, must not be changed.
//! \var AutoContactFlag::CntHTee
//! The object true class is AutoContactHTee, must not be changed.
//! \var AutoContactFlag::CntVTee
//! The object true class is AutoContactVTee, must not be changed.
//! \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 ();
//! Base class method proxy.
//! \function Hook* AutoContact::getAnchorHook ();
//! Base class method proxy.
//! \function Component* AutoContact::getAnchor () const;
//! Base class method proxy.
//! \function Net* AutoContact::getNet () const;
//! Base class method proxy.
//! \function const Layer* AutoContact::getLayer () const;
//! Base class method proxy.
//! \function DbU::Unit AutoContact::getX () const;
//! Base class method proxy.
//! \function DbU::Unit AutoContact::getY () const;
//! Base class method proxy.
//! \function DbU::Unit AutoContact::getDx () const;
//! Base class method proxy.
//! \function DbU::Unit AutoContact::getDy () const;
//! Base class method proxy.
//! \function Point AutoContact::getCenter () const;
//! Base class method proxy.
//! \function Point AutoContact::getPosition () const;
//! Base class method proxy.
//! \function DbU::Unit AutoContact::getWidth () const;
//! Base class method proxy.
//! \function DbU::Unit AutoContact::getHalfWidth () const;
//! Base class method proxy.
//! \function DbU::Unit AutoContact::getHeight () const;
//! Base class method proxy.
//! \function DbU::Unit AutoContact::getHalfHeight () const;
//! Base class method proxy.
//! \function Components AutoContact::getSlaveComponents () const;
//! Base class method proxy.
//! \function void AutoContact::setLayer ( const Layer* ) ;
//! Base class method proxy.
//! \function void AutoContact::setWidth ( DbU::Unit ) ;
//! Base class method proxy.
//! \function void AutoContact::setHeight ( DbU::Unit ) ;
//! Base class method proxy.
//! \function void AutoContact::setSizes ( DbU::Unit w, DbU::Unit h ) ;
//! Base class method proxy.
//! \function void AutoContact::setX ( DbU::Unit ) ;
//! Base class method proxy.
//! \function void AutoContact::setY ( DbU::Unit ) ;
//! Base class method proxy.
//! \function void AutoContact::setPosition ( DbU::Unit w, DbU::Unit h ) ;
//! Base class method proxy.
//! \function void AutoContact::setPosition ( const Point& ) ;
//! Base class method proxy.
//! \function void AutoContact::setDx ( DbU::Unit ) ;
//! Base class method proxy.
//! \function void AutoContact::setDy ( DbU::Unit ) ;
//! Base class method proxy.
//! \function void AutoContact::setOffset ( DbU::Unit w, DbU::Unit h ) ;
//! Base class method proxy.
//! \function void AutoContact::translate ( const DbU::Unit& dx, const DbU::Unit& dy ) ;
//! Base class method proxy.
//! \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* reference ) const;
//! \sreturn The other AutoSegment the \e same direction as \c reference, this is
//! only meaningful on AutoContactHTee or AutoContactVTee. If there is
//! no opposite, \c NULL is returned.
//! \function AutoSegment* AutoContact::getPerpandicular ( const AutoSegment* reference ) const;
//! \sreturn The AutoSegment in the \e perpandicular direction to \c reference, this is
//! only meaningful on AutoContacTurn. It there is no unique perpandicular,
//! \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.
//! \function void AutoContact::migrateConstraintBox ( AutoContact* other );
//! Transfer the user constraint box from \c other to the current
//! object \c this. The constraints of \c other are restored to their
//! native values. The two contacts must belong to the same GCell for
//! this method to take effect.
/*! \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.
}