
 // -*- C++ -*-

 namespace Kite {

 /*! \class        Manipulator
  *  \brief        Handle TrackElement ripup & topological modifications.
  *
  *  \section      secManipStruct  Manipulator Structure
  *
  *                A Manipulator basically binds together a TrackElement, it's
  *                DataNegociate and RoutingEvent (cached for fast access), and
  *                \b a SegmentFsm.
  *
  *                <em>The TrackElement may differs from the one of the SegmentFsm.</em>
  *                This can occurs when manipulating perpandiculars or segments from
  *                other nets in conflict. For example: Manipulator::isCaged().
  *
  *                In the following documentation, the segment <em>which is associated
  *                to the SegmentFsm</em> will be called the <em>reference segment</em>.
  *
  *  \section      secManipDelayed  Delayed Modifications
  *
  *                It is important to note that when a Manipulator is called to
  *                modificate a TrackElement, nothing is actually done by the
  *                Manipulator itself. Instead, the Manipulator create the
  *                relevant SegmentAction (s) that are stored in the SegmentFsm. 
  *                The action themselves are done at the end of the SegmentFsm
  *                lifecycle (wrapped inside a Session).
  *
  *                \red{This is not true!} When dogleg are created, the topology is
  *                immediatly modificated. That way of doing must be clarified.
  */

 //! \enum         Manipulator::FunctionFlag
 //!               The various flags that can be passed to the Manipulator methods.

 //! \var          Manipulator::ToRipupLimit
 //!               The ripup limit must be immediatly to it's limit for the current
 //!               state.

 //! \var          Manipulator::AllowExpand
 //!               Allow break points for dogleg not to be exactly on the requested
 //!               position. Meaning that they are moved to the least congested
 //!               GCell.

 //! \var          Manipulator::NoExpand
 //!               Breakpoints for dogleg are kept right where they are requested.

 //! \var          Manipulator::PerpandicularsFirst
 //!               Reorder the events so that perpandiculars segments are re-processed
 //!               before their reference segment. By default this is the other way
 //!               around.

 //! \var          Manipulator::ToMoveUp
 //!               Try to move up ripped up segments.

 //! \var          Manipulator::AllowLocalMoveUp
 //!               Allow local segments to be moved up (forbidden by default).

 //! \var          Manipulator::AllowTerminalMoveUp
 //!               Allow terminal segments to be moved up (forbidden by default).

 //! \var          Manipulator::AllowShortPivotUp
 //!               Allow short segment yo be pivoted up.

 //! \var          Manipulator::NoDoglegReuse
 //!               When creating a dogleg, the default behavior is \e not to create a
 //!               new one if there's already one in the same GCell. If this flag is
 //!               set, a second dogleg will be created.

 //! \var          Manipulator::RightAxisHint
 //!               An explicit right axis hint has been supplied as argument.

 //! \var          Manipulator::LeftAxisHint
 //!               An explicit left axis hint has been supplied as argument.

 //! \var          Manipulator::NotOnLastRipup
 //!               The reference segment has still more than one ripup to go for
 //!               the given state.
 
 //! \function     Manipulator::Manipulator ( TrackElement* segment, SegmentFsm& fsm );
 //! \param        segment  The TrackElement to manipulate.
 //! \param        fsm      The associated SegmentFsm.
 //!
 //!               Construct a new Manipulator on \c segment.
 
 //! \function     TrackElement* Manipulator::getSegment () const;
 //! \sreturn      The working TrackElement.
 
 //! \function     DataNegociate* Manipulator::getData () const;
 //! \sreturn      The DataNegociate of the TrackElement (act as a cache).
 
 //! \function     RoutingEvent* Manipulator::getEvent () const;
 //! \sreturn      The RoutingEvent associated to the TrackElement (act as a cache).
 
 //! \function     bool  Manipulator::canRipup ( unsigned int flags ) const;
 //! \sreturn      \true if the maximum ripup, for the given SegmentFsm::State has not
 //!               been reached. If \c flags contains Manipulator::HasNextRipup, return
 //!               \true \b only if it still have at least one ripup to go.
 
 //! \function     bool  Manipulator::isCaged ( DbU::Unit axis ) const;
 //! \sreturn      \true if the segment is enclosed (in it's Track) by two fixed or
 //!               blockage segments which at least one is closer than 10 lambdas from
 //!               \c axis. Mostly used to know if a perpandicular is actually restricting
 //!               the axis span of a reference segment.
 
 //! \function     bool  Manipulator::ripup ( unsigned int type, DbU::Unit axisHint=0 );
 //! \param        type       The type of ripup action.
 //! \param        axisHint   An indication as where to move the riped up segment.
 //! \return       \true if the operation has succedeed.
 //!
 //!               If the TrackElement can be ripped up, schedule a ripup action, possibly
 //!               with a hint for the preferred axis position.
 
 //! \function     bool  Manipulator::ripupPerpandiculars ( unsigned int flags );
 //!               Schedule a ripup of all the perpandiculars of the reference segment.
 //!               \c flags that modificate the behavior:
 //!                 - Manipulator::PerpandicularsFirst : the queue will be reordered so
 //!                   that all the perpandiculars are re-processed (placed) before the
 //!                   reference segment.
 //!                 - Manipulator::ToRipupLimit : the ripup count of the reference segment
 //!                   is set to the limit (i.e. only one more attempt before a slackening
 //!                   occurs).
 //!
 //!               The method will fails (return \false) if at least one perpandicular can't
 //!               be changed of track (i.e. ripped up) \b and none of it's neighbors could
 //!               be ripped up either. Meaning that the free span on that track cannot be
 //!               changed.
 
 //! \function     void  Manipulator::repackPerpandiculars ();
 //!               Ripup all the perpandiculars of the reference segment, except fixed or
 //!               globals. The reference segment is rescheduled first (before it's
 //!               perpandicular).
 //!
 //!               This function may be used to find a better placement, maximizing the
 //!               overlap of the various perpandiculars.
 
 //! \function     bool  Manipulator::ripple ();
 //! \sreturn      true if the reference segment is local.
 //!
 //!               Applies only on reference segments that are of local type.
 //!               Tries to make room for the reference segment by ripping up it's neigbors
 //!               on the parallels tracks. On a vertical plane, left neigbors are shifted
 //!               one track left (trough axis hint) and right ones, one track right.
 //!               Note that they are ripped up and the shift is just a hint, there's no
 //!               guarantee that the router can honor it.
 
 //! \function     bool  Manipulator::minimize ();
 //! \sreturn      true if the reference segment can be mimized in a suitable track hole.
 //!
 //!               Compute the miminal span of the reference segment, summing up contraints
 //!               from source anchor and target anchors (if any) and perpandiculars.
 //!               Then find holes in the avalaible tracks, and check if one is suitable
 //!               for the miminized segment (try first the biggest hole).
 //!
 //!               This operation can only be called once on a segment (a flag is set in the
 //!               event).
 
 //! \function     bool  Manipulator::slacken ( unsigned int flags=KbNoFlags );
 //!               Simple proxy towards TrackElement::slacken().
 //!
 //!               \red{To be reviewed.}
 
 //! \function     bool  Manipulator::pivotUp ();
 //!               Tries to move up the reference segment. The segment will be moved
 //!               up only if a half track is free (for a local) or a full track is
 //!               free (for a global).
 //!
 //!               This function do not modifies/create perpandiculars.
 
 //! \function     bool  Manipulator::pivotDown ();
 //!               Tries to move down the reference segment. The segment will be moved
 //!               up only if \e two track are free (whether global or local). Is is more
 //!               restrictive than Manipulator::pivotUp().
 //!
 //!               This function do not modifies/create perpandiculars.
 
 //! \function     bool  Manipulator::moveUp ( unsigned int flags );
 //!               Tries to move up a segment, if there is enough space in the RoutingPlane
 //!               above and in the same direction.
 //!
 //!               This function may modificate perpandiculars in order to maintain
 //!               connexity.
 //!
 //!               \red{To be reviewed.}
 
 //! \function     bool  Manipulator::makeDogleg ();
 //! \sreturn      \false if the segment is \e not local or the dogleg cannot be done.
 //!
 //!               For \e local reference segment only, look in the first track candidate
 //!               for other segment overlapping and break the reference accordingly. 
 
 //! \function     bool  Manipulator::makeDogleg ( Interval overlap );
 //!               Create a dogleg to avoid the obstructed interval \c overlap.
 
 //! \function     bool  Manipulator::makeDogleg ( DbU::Unit position );
 //!               Create a dogleg in the GCell under \c position.

 //! \function     bool  Manipulator::relax ( Interval overlap, unsigned int flags=AllowExpand );
 //!               Break the reference segment so it can detour around the interval
 //!               \c overlap. If \c overlap is completly enclosed inside the span of
 //!               the reference segment two dogleg will be created. If the overlap occurs
 //!               only on one side of the reference segment, only one dogleg will be
 //!               created.
 //!
 //!               If \c flags contains Manipulator::AllowExpand, the dogleg are not created
 //!               exactly at the edges of the overlap but on the lowest density GCell
 //!               (outside the overlap interval).
 //!
 //!               The axis of the created dogleg are sets so that the broken part of the
 //!               segment completly enclose \c overlap. That is, the orignal segment no
 //!               longer intersect with \c overlap. So the min dogleg is pushed to the
 //!               left and the max to the right if they are in the same GCell as the
 //!               min/max of \c overlap. Otherwise (they have been expanded), they are
 //!               put in the center of the GCell.
 //!
 //!               We do not allow to dogleg twice in the same GCell, so if min or max
 //!               is in respectively the first or last GCell, it is not done. Moreover
 //!               if there is only one dogleg \e and it is in the first or last GCell,
 //!               the relax method is cancelled (and returns \false). It means that
 //!               this is the segment which is likely to be enclosed inside \c overlap.
 //!
 //!               \redB{Important:} The doglegs are created immediatly and not in a delayed
 //!               fashion like the SegmentAction.
 //!
 //!               \image html  ManipulatorRelax-1.png "Two Doglegs (min & max), no expansion"
 //!               \image html  ManipulatorRelax-2.png "Two Doglegs (min & max), with expansion"
 //!               \image html  ManipulatorRelax-3.png "One Dogleg (min)"
 //!               \image html  ManipulatorRelax-4.png "One Dogleg (max)"
 
 //! \function     bool  Manipulator::insertInTrack ( size_t i );
 //!               Try to insert the reference segment in the track at index \c i (in the cost
 //!               table from SegmentFsm). The insertion is done by ripping up overlapping
 //!               segment or shrinking them to left/right if possible.
 //!
 //!               \red{This operation ripup the processed segment neighbors (and their perpandiculars).}
 
 //! \function     bool  Manipulator::forceToTrack ( size_t i );
 //!               Try to insert the reference segment in the track at index \c i  (in the cost
 //!               table from SegmentFsm). The insertion is done by \e forcibly ripping up the
 //!               overlapping segments \b and their perpandiculars.
 //!
 //!               \red{This operation ripup the processed segment neighbors (and their perpandiculars).}
 
 //! \function     bool  Manipulator::shrinkToTrack ( size_t i, unsigned int flags, DbU::Unit leftAxisHint, DbU::Unit rightAxisHint );
 //!               Attempt to minimize the reference segment to fit into the track.
 //!               For this operation to succeed, the minimal span of the segment must
 //!               not overlap any other segment already in the track. To reach the
 //!               minimal span the perpandiculars are ripped up with an axis hint
 //!               which is the center of the minimal span or the explicit value given
 //!               as arguments \c leftAxisHint and \c rightAxisHint if \c flags contains
 //!               respectively Manipulator::LeftAxisHint or Manipulator::RightAxisHint.
 //!
 //!               \red{This operation ripup the processed segment itself and its perpandiculars.}
 
 //! \function     bool  Manipulator::forceOverLocals ();
 //!               Loop over all the candidate tracks and, insert in the first which
 //!               all conflicting segments are locals (rip them up).
 
 //! \function     bool  Manipulator::repackPerpandiculars ();
 //!               Ripup all perpandiculars and the reference segment itself for a complete
 //!               re-placement. The reference segment will be reprocessed \e before it's
 //!               perpandiculars.

 }
