
 // -*- C++ -*-


 namespace Kite {

 /*! \class        Track
  *  \brief        Structure managing one routing track.
  *
  *  \section      secTrackPurpose  Track Purpose
  *
  *                We use an array of <em>regularly spaced</em> Track as a geometrical
  *                fast access structure. It allows to know whether an area is used or
  *                not. The whole area may be seen as a set of adjoining tiles of fixed
  *                \e width but variable \e length.
  *
  *                The figure <b>(1.b)</b> show, for an horizontal, track the relation
  *                between <code>y,min,max</code> and the occupied area of the plane.
  *                \c min and \c max must take into account segment extensions (\c e) and
  *                the minimal distance between two rectangles (\c MD) of the same layer.
  *                We assume that the width of the segment, augmented of all it's
  *                contraints is no greater than \c TS (in fact it's how \c TS must be
  *                calculated).
  *
  *                For the whole track array, see RoutingPlane.
  *
  *                \image html  Track-0.png "Fig 1: Track Area"
  *
  *
  *  \section      secTrackImplementation  Track Implementation
  *
  *                A Track is implemented with a sorted vector of TrackElement.
  *                TrackElements from differents nets must not overlap.
  *                The sorting order is defined as follow:
  *                  - TrackElements are sorted by increasing source (\e min)
  *                    positions.
  *                  - In case of overlap (i.e. belongs to the same net), if
  *                    they share the same source position, then they are sorted
  *                    by \e decreasing length. This way, the longest one will be
  *                    the first encountered when walking through the Track in
  *                    increasing index order.
  *
  *                Figure <b>2.b</b> shows the details of the Track <b>[1]</b> of
  *                figure <b>1.a</b>. Net \b \<d\> show an exemple of overlapping. 
  *
  *                \image html  Track-1.png "Fig 2: Track Structure"
  *                \image latex Track-1.pdf "Track Structure" width=0.7\textwidth
  *
  *                In addition to the TrackSegments, the Track also manage additionnal
  *                informations through a second vector of TrackMarkers. TrackMarker
  *                are currently used only to hints at how strongly a terminal is
  *                dependant on that portion of Track to be accessed.
  *
  *
  * \subsection    ssecTrackIndexes  Indexes vs. Iterators
  *
  *                Numerical indexes have been prefered over iterators because they can
  *                be used more easily by objects other the Track itself for referencing.
  *                So internal managment follow the same rule, handling indexes or
  *                reference to indexes.
  *
  *
  * \subsection    ssecTrackUpdate  Update Mechanism
  *
  *                When a TrackElement is normaly inserted in a Track, a two way link
  *                is established. The Track has an entry in it's vector refering to
  *                TrackElement, and conversely, the TrackElement has it's \c track
  *                field pointing to it's owning Track.
  *
  *                <b>TrackElement Removal</b>
  *
  *                To remove a TrackElement from a Track, we break one of those two links:
  *                the TrackElement cease to refer to the owning Track, marking him for
  *                removal which will occurs at the next track revalidation (Track::doRemoval()).
  *                In figure <b>3</b>, the TrackElement belonging to net \b \<b\> is
  *                marked for removal.
  *
  *                \image html  Track-2.png "Fig 3: TrackElement Removal"
  *
  *                <b>TrackElement Insertion</b>
  *
  *                When a TrackElement is inserted into a Track, the two way link is
  *                immediatly created (but the TrackElement is not yet at it's final
  *                place in the Track's vector). Before inserting a TrackElement we
  *                check that it's been already detached (\c track field to \c NULL).
  *
  *                It is at that step that the TrackElement axis is actually updated
  *                through a call to TrackElement::setAxis().
  *                
  *                <b>Revalidation Sequence</b>
  *
  *                After a Track has been modificated either the Track element vector or
  *                the MarkerElement vector (or both) has been invalidateds. Revalidation
  *                take place in three steps:
  *                  - Track::doRemoval(), remove all TrackElement marked for removal.
  *                  - Track::insert(), insert the TrackElement into their new Track.
  *                  - Track::doReorder(), sort the TrackElement of the vector, that is, put the
  *                    newly inserted elements at their right place.
  *
  *                Each step must be done <em>for all Tracks</em> before proceeding to the
  *                next. This way a TrackElement \c track field doesn't get set \e before
  *                it has been actually removed from it's previous Track.
  *                
  *                
  *
  * \subsection    ssecTrackOperations  Main Operations on Tracks
  *
  *                <b>Helper Function:</b> Track::getBeginIndex()
  *
  *                Return in \c begin the index of the TrackElement whose minimum is immediately
  *                below the requested \c position on the Track axis. The second returned
  *                parameter \c state is a set of flags to tell how the \c begin index
  *                has to be interpreted.
  *
  *                <b>Helper Function:</b> Track::getOccupiedInterval()
  *
  *                Returns the complete interval of a set of overlapping TrackElement from
  *                the same net.
  */

 //! \enum         Track::IndexState
 //!               Indicates how to compute the bounds of the interval enclosing
 //!               a given \c position on track axis.
 //!
 //! \note         According to \e position, the interval can be a free interval
 //!               or a used interval.

 //! \var          Track::BeginIsTrackMin
 //!               (implies \c begin=0) there is no TrackElement \e before \c position

 //! \var          Track::BeginIsSegmentMin
 //!               The \c begin segment starts \e before \c position and ends \e after.

 //! \var          Track::BeginIsSegmentMax
 //!               The \c begin segment starts and ends \e before \c position.

 //! \var          Track::EndIsTrackMax
 //!               There is no TrackElement \e after \c position.

 //! \var          Track::EndIsSegmentMin
 //!               The \c begin segment starts \e before \c position.

 //! \var          Track::EndIsNextSegmentMin
 //!               The \c begin segment starts and ends \e before \c position. So the maximum
 //!               is given by the \c minimum of the \e next TrackElement.

 //! \var          Track::EndIsSegmentMax
 //!               The \c begin segment starts \e before \c position and ends \e after.

 //! \var          Track::BeforeFirstElement
 //!               the \c position is before the first TrackElement.

 //! \var          Track::InsideElement
 //!               the \c position is inside a TrackElement.

 //! \var          Track::OutsideElement
 //!               the \c position is in free zone between two TrackElements.

 //! \var          Track::AfterLastElement
 //!               the position is after the end of the last element.

 //! \var          Track::EmptyTrack
 //!               the track is still empty.

 //! \var          Track::BeginMask
 //!               To extract the \e begin part from a combination of flags.

 //! \var          Track::EndMask
 //!               To extract the \e end part from a combination of flags.

 //! \var          Track::npos;
 //!               A special index value (greatest integer) meaning that
 //!               an index is invalid.

 //! \function     bool  Track::isHorizontal () const;
 //! \sreturn      \true if the Track in horizontal direction.

 //! \function     bool  Track::isVertical () const;
 //! \sreturn      \true if the Track in vertical direction.

 //! \function     bool  Track::isLocalAssigned () const;
 //! \sreturn      \true is the Track should be preferentially used for local routing.

 //! \function     RoutingPlane* Track::getRoutingPlane () const;
 //! \sreturn      The RoutingPlane owning this Track.

 //! \function     KiteEngine* Track::getKiteEngine () const;
 //! \sreturn      The KiteEngine owning this Track.

 //! \function     unsigned int  Track::getDirection () const;
 //! \sreturn      The direction of the Track, either Katabatic::KbHorizontal or
 //!               Katabatic::KbVertical.

 //! \function     RoutingPlane* Track::getIndex () const;
 //! \sreturn      The index of this Track in the RoutingPlane Track vector.

 //! \function     unsigned int  Track::getDepth () const;
 //! \sreturn      The depth (as given by the RoutingGauge) of the Track's layer.

 //! \function     Layer* Track::getLayer () const;
 //! \sreturn      The \Layer of the Track.

 //! \function     Layer* Track::getBlockageLayer () const;
 //! \sreturn      The associated blockage \Layer to the Track's layer.

 //! \function     DbU::Unit  Track::getAxis () const;
 //! \sreturn      The Axis of the Track.

 //! \function     DbU::Unit  Track::getMin () const;
 //! \sreturn      The minimal allowed coordinate of the Track.

 //! \function     DbU::Unit  Track::getMax () const;
 //! \sreturn      The maximal allowed coordinate of the Track.

 //! \function     Track* Track::getNextTrack () const;
 //! \sreturn      The next Track in the \RoutingPlane vector. That is the
 //!               one with the axis immediatly superior.

 //! \function     Track* Track::getPreviousTrack () const;
 //! \sreturn      The previous Track in the \RoutingPlane vector. That is the
 //!               one with the axis immediatly inferior.

 //! \function     size_t  Track::getSize () const;
 //! \sreturn      The total number of TrackSegment in the Track.

 //! \function     Point  Track::getPosition ( DbU::Unit position ) const;
 //! \sreturn      the point at \c (position,getAxis()) for horizontal Track
 //!               at or \c (getAxis(),position) for vertical Track.

 //! \function     TrackSegment* Track::getSegment ( size_t index ) const;
 //! \param        index  The index of the TrackSegment.
 //! \return       The TrackSegment at \e index. The result will be \NULL in the
 //!               follwing cases :
 //!                 - \e index is outside the sorted zone.
 //!                 - \e index points to a hole in the Track.
 //!                 - \e index is equal to Track::npos.

 //! \function     TrackSegment* Track::getSegment ( DbU::Unit position ) const;
 //! \param        position  The position where to search.
 //! \return       The TrackSegment whose starting point is immediatly inferior to \e position.

 //! \function     TrackSegment* Track::getNext ( size_t& index, Net* net ) const;
 //! \param        index  Index of the starting TrackSegment.
 //! \param        net    A \Net to ignore.
 //! \return       The next TrackSegment (\NULL if not found).
 //!
 //!               Find, starting from TrackSegment at \e index the next TrackSegment
 //!               ignoring TrackSegment from \e net. \e index is modified to point
 //!               on the returned TrackSegment. If there's no next TrackSegment (\NULL)
 //!               then index is set to Track::npos.

 //! \function     TrackSegment* Track::getPrevious ( size_t& index, Net* net ) const;
 //! \param        index  Index of the starting TrackSegment.
 //! \param        net    A \Net to ignore.
 //! \return       The previous TrackSegment (\NULL if not found).
 //!
 //!               find, starting from TrackSegment at \e index the previous TrackSegment
 //!               ignoring TrackSegment from \e net. \e index is modified to point
 //!               on the returned TrackSegment. If there's no previous TrackSegment (\NULL)
 //!               then index is set to Track::npos.

 //! \function     TrackSegment* Track::getNextFixed ( size_t& index ) const;
 //! \param        index  Index of the starting TrackSegment.
 //! \return       The first previous \e Fixed TrackSegment.
 //!
 //!               find, starting from TrackSegment at \e index the first previous
 //!               with a \e Fixed attribute set. \e index is modified to point on the
 //!               returned TrackSegment. If there's no previous TrackSegment (\NULL)
 //!               then index is set to Track::npos.

 //! \function     size_t  Track::find ( const TrackElement* element ) const;
 //! \sreturn      the \e index of \e element inside the Track. If the \e element do
 //!               not belongs to the Track, return Track::npos.

 //! \function     DbU::Unit  Track::getSourcePosition ( size_t index ) const;
 //! \sreturn      The source position of TrackSegment at index \e index.
 //!               If \e index is equal to Track::npos, returns zero.

 //! \function     DbU::Unit  Track::getSourcePosition ( vector<TrackElement*>::iterator it ) const;
 //! \sreturn      The source position of TrackSegment pointed by iterator \e it.
 //!               If \e it is equal to \c end() , returns zero.

 //! \function     DbU::Unit  Track::getMinimalPosition ( size_t index, unsigned int state ) const;
 //! \sreturn      Extract the minimal position from the interval at \c index in accordance
 //!               to \c state hinting.
 //!
 //! \sa           Track::IndexState.

 //! \function     DbU::Unit  Track::getMaximalPosition ( size_t index, unsigned int state ) const;
 //! \sreturn      Extract the maximal position from the interval at \c index in accordance
 //!               to \c state hinting.
 //!
 //! \sa           Track::IndexState.

 //! \function     Interval  Track::getFreeInterval ( DbU::Unit position, Net* net=NULL ) const;
 //! \param        position  where fo find a free interval.
 //! \param        net       for which net to find the free interval.
 //! \sreturn      The longuest free interval enclosing \e position (may be empty).

 //! \function     Interval  Track::getOccupiedInterval ( size_t& begin ) const;
 //! \param        begin  index of one of the TrackElement set. May be modificated.
 //! \sreturn      the whole interval used by a set of overlaping TrackSegment.
 //!
 //!               As TrackElement from a same net can overlap, the interval of one of
 //!               them do not give the full extend of the Track occupation at this point.
 //!               This function looks for all overlaping segments and returns the
 //!               merged interval. Additionnaly it sets \c begin to the index of the
 //!               lowest TrackElement of the set.
 //!               
 //!               \image html  TrackOccupiedInterval-1.png "Fig 4: Track::getOccuppiedInterval()"

 //! \function     Interval  Track::expandFreeInterval ( size_t& begin, size_t& end, unsigned int state, Net* net ) const;
 //! \param        begin  the lowest used TrackSegment.
 //! \param        end    the highest used TrackSegment.
 //! \param        state  tells how to interpret the \c begin & \c end indexes.
 //! \param        net    the for wich we seek place.
 //! \sreturn      The longuest free interval between \c ]begin,end[ .
 //!
 //!               Starting from the initial <code>[begin,end]</code> interval, expand the
 //!               interval to encompass all free space or segments belonging to \c net.
 //!               \c state may be used to compute the interval bounds from \c begin
 //!               and \c end instead of directly using the returned \c interval.
 //!
 //! \note         \c ]begin,end[ must define a free interval between two TrackSegment.

 //! \function     void  Track::getBeginIndex ( DbU::Unit position, size_t& begin, unsigned int& state ) const;
 //! \param        position  The position where to search.
 //! \param        begin     Index of the immediatly inferior TrackElement.
 //! \param        state     how to interpret the returned \c begin.
 //!
 //!               Return in \c begin the index of the TrackElement whose minimum is immediately
 //!               below the requested \c position on the Track axis. The second returned
 //!               parameter \c state is a set of flags to tell how the \c begin index
 //!               has to be interpreted.
 //!
 //!               Flags for the \c state are:
 //!                 - Track::BeginIsTrackMin : (implies \c begin=0) there is no TrackElement
 //!                   \e before \c position.
 //!                 - Track::EndIsSegmentMin : The \c begin segment starts \e before \c position.
 //!                 - Track::BeginIsSegmentMin : The \c begin segment starts \e before \c position
 //!                   and ends \e after.
 //!                 - Track::EndIsSegmentMax : The \c begin segment starts \e before \c position
 //!                   and ends \e after.
 //!                 - Track::BeginIsSegmentMax : The \c begin segment starts and ends \e before
 //!                   \c position.
 //!                 - Track::EndIsNextSegmentMin : The \c begin segment starts and ends \e before
 //!                   \c position. So the maximum is given by the \c minimum of the \e next
 //!                   TrackElement.
 //!                 - Track::EndIsTrackMax : There is no TrackElement \e after \c position.
 //!
 //!               Based on the previous flags, we build the \c state parameter:
 //!                 - Track::BeforeFirstElement : the \c position is before the first TrackElement.
 //!                 - Track::InsideElement : the \c position is inside a TrackElement.
 //!                 - Track::OutsideElement : the \c position is in free zone between two
 //!                   TrackElements.
 //!                 - Track::AfterLastElement : the position is after the end of the last
 //!                   element.
 //!                 - Track::EmptyTrack : the track is still empty.
 //!
 //!               To separate flags relevant to \e begin and \e end informations, two masks
 //!               are provideds:
 //!                 - Track::BeginMask
 //!                 - Track::EndMask
 //!               
 //!               \image html  TrackBeginIndex-1.png "Fig 3: Track::getBeginIndex()"
 //!
 //!               <b>Reminder for myself:</b>
 //!               The Track::getBeginIndex() function relies on the \STL \lower_bound
 //!               function. \c lower_bound() finds the TrackElement immediately \e superior
 //!               to \c position (shown on Figure <b>3</b> by the \c LB label in white on black).
 //!
 //!               The relation between the returned \c begin index and the position is
 //!               given through the \c state parameter.

 //! \function     void  Track::getOverlapBounds ( Interval interval, size_t& begin, size_t& end ) const;
 //! \param        interval  the overlaping interval.
 //! \param        begin     where to store the starting bound.
 //! \param        end       where to store the ending bound.
 //!
 //!               find the range of TrackSegment intersecting \e interval.
 //!               Note that when the \e interval lower bound crosses a set of
 //!               overlaping intervals from the same \Net, the interval at
 //!               \e begin will crosses the lower bound but some following
 //!               of the same \Net may not.

 //! \function     TrackCost  Track::getOverlapCost ( Interval interval, Net* net, size_t begin, size_t end, unsigned int flags ) const;
 //! \param        interval  the overlaping interval.
 //! \param        net       a Net to ignore (null cost).
 //! \param        begin     the starting bound.
 //! \param        end       the ending bound.
 //! \param        flags     passed to the overlap cost function.
 //! \return       The cost of the overlap.
 //!
 //!               Compute the cost of the overlap of \e interval with the range
 //!               \c [begin,end] of TrackSegment. Any TrackSegment belonging to
 //!               \e net will be ignored.

 //! \function     TrackCost  Track::getOverlapCost ( Interval interval, Net* net, unsigned int flags ) const;
 //! \param        interval  the overlaping interval.
 //! \param        net       a Net to ignore (null cost).
 //! \param        flags     passed to the overlap cost function.
 //!
 //!               Compute the overlap cost of \e interval with TrackSegment from
 //!               the current Track, ignoring thoses belonging to \e net.

 //! \function     TrackCost  Track::getOverlapCost ( TrackElement* segment, unsigned int flags ) const;
 //! \param        segment   under which to compute overlap cost.
 //! \param        flags     passed to the overlap cost function.
 //!
 //!               Compute the overlap cost of \c segment with TrackSegment from
 //!               the current Track (interval and net are deduced from \c segment).

 //! \function     void  Track::getTerminalWeight ( Interval interval, Net* net, size_t& count, unsigned int& weight ) const;
 //! \param        interval   under which to compute terminal weight.
 //! \param        net        a net to be ignored.
 //! \param        count      incremented of the number of track markers under the
 //!                          \c interval.
 //! \param        weight     incremented of the sum of the weight of the track markers
 //!                          under the \c interval.
 //!
 //!               Compute and return the sum of the weight of the track markers (see TrackMarker)
 //!               under \c interval ignoring \c net (that is, \e for \c net).
 //!
 //! \remark       The referenced variables \c count and \c weight are <b>not</b> reset to
 //!               zero by this function. It is of the caller's responsability.

 //! \function     bool  Track::check ( unsigned int& overlaps, const char* message=NULL ) const;
 //! \param        overlaps  The number of overlaping segments.
 //! \param        message   An iformative message, only printed if an error occurs.
 //! \return       \true if the Track contains no incoherencies.
 //!
 //!               Perform a complete Track check. Looks for the following incoherencies :
 //!                 - TrackSegment do not refers this Track.
 //!                 - TrackSegment is detached (TrackSegment::getTrack() is \NULL).
 //!                 - TrackSegment is hollow, this one is very unlikely as hollow
 //!                   TrackSegment are only created for the \lower_bound.
 //!                 - \NULL pointers (should never occurs, nevertheless...)
 //!                 - Two consecutive TrackSegment from different \Net must not
 //!                   overlap.
 //!                 - For TrackSegment starting from the same position, the
 //!                   longuest must be first.

 //! \function     void  Track::invalidate ();
 //!               Inconditionnaly invalidate the Track, regardless if it has been
 //!               modificated. The Track will be forced to be revalidated on closure
 //!               of the current session.

 //! \function     void  Track::insert ( TrackElement* segment );
 //!               Adds \e segment to the Track. Must only be used inside a
 //!               Session. They must appears \e after Track::doRemoval()
 //!               and \e before Track::doReorder().
 //!
 //! \sa           Kite::Session.

 //! \function     void  Track::insert ( TrackMarker* marker );
 //!               Adds \e marker to the Track. Must only be used inside a
 //!               Session.
 //!
 //! \sa           Kite::Session.

 //! \function     void  Track::setSegment ( TrackElement* element, size_t index );
 //!               Directly affect the Track entry at position \c index to
 //!               \c element (use with great care).
 //!
 //! \sa           Kite::Session.

 //! \function     size_t  Track::doRemoval ();
 //! \sreturn      The number of removeds TrackSegment.
 //!
 //!               Suppress all the TrackSegment that have been withdraw from the
 //!               Track. TrackSegment must be withdraw trough the TrackSegment::detach()
 //!               method which sets their owning Track to \NULL (the removal criterion).
 //!               It uses the \STL \e remove_if algorithm that put all the to be removed
 //!               elements at the end of the vector.
 //!
 //! \sa           Kite::Session.

 //! \function     void  Track::doReorder ();
 //!
 //!               (Re)sort the TrackElement of the vector. Must be called \e after:
 //!                 - Track::doRemoval() so no detached TrackSegment are presents.
 //!                 - All calls to Track::insert(), as the newly inserted elements
 //!                   are put at the back of the vector.
 //!
 //! \sa           Kite::Session.

 }
