
 // -*- C++ -*-


 namespace Hurricane {

 /*! \class        Go
  *  \brief        Go description (\b API)
  *
  *  \section      secGoIntro  Introduction
  *
  *                The Gos represent the category of graphical objects. 
  *
  *                They are stored in a fast geometric access data structure : a 
  *                quadtree (let us recall that the organization of each 
  *                quadtree depends essentially of the geometrical envelope of 
  *                those objects and of their number). 
  * 
  * 
  *  \section      secGoMaterialization  Materialization
  *
  *                A graphical object can be materialized or not. 
  *
  *                A graphical object is said materialized when it is 
  *                effectively inserted into a quadtree. It has then a graphical 
  *                appearance (it's the least it can do) but also it will be 
  *                taken into account within each collection which uses 
  *                quadtrees in order to find its constituents (like the 
  *                collection returned by the call 
  *                cell-\>GetComponentsUnder(area) for instance). 
  *
  *                On the other hand, non materialized graphic objects will 
  *                neither be visible nor taken into account by those 
  *                collections. This may be a significant advantage in some 
  *                situations and a great drawback in others. 
  *
  *  \remark       <b>Plugs are never materialized</b>. 
  * 
  * 
  *  \section      secGoUpdateSessions  Update sessions
  *
  *                The location of an object within its quadtree depends of its 
  *                bounding box, if a modification of this one must occur for 
  *                any reason, the object must be removed from the quadtree 
  *                before doing the modification and re-inserted after, at the 
  *                right place, according to its new bounding box. 
  *
  *                Furthermore the change on an object may lead to changes on 
  *                other ones. For instance the move of a contact will 
  *                forcefully affect the components which are anchored on it, 
  *                and so forth ... 
  *
  *                Furthermore it may be interesting to apply many modifications 
  *                at the same time, avoiding so intermediate or useless 
  *                multiple updates (many changes on the same object but also on 
  *                different objects lying in different unrelated cells). 
  *
  *                type: In order to control this process we must operate in 
  *                three steps 
  *
  *                Open an update session. Do all the needed modifications. 
  *                Close the update session. 
  *
  *                type: Let us examine the following piece of code which 
  *                illustrates that 
\code
UpdateSession::open();
 
contact->setLayer(...);
contact->setSize(...);
contact->setPosition(...);
 
UpdateSession::close();
\endcode
  *                The call to the generic function <b>UpdateSession::open()</b> 
  *                allows to open a new update_session. 
  *
  *                The three following lines call upon functions which modify 
  *                the contact and, for the last one, also the components which 
  *                directly or indirectly bear on it. 
  *
  *                At last the call to the generic function 
  *                <b>UpdateSession::close()</b> allows to close the last update 
  *                session currently open. 
  *
  *                type: What does really happen ? 
  *
  *                The update sesion is a shared property which is put at its 
  *                creation on the top of a FIFO stack. The last update cession 
  *                placed on the top of this stack represents the current 
  *                session. 
  *
  *                When the object is modified : the method <b>Go::invalidate()</b> 
  *                which we will detail later is called upon. The purpose of 
  *                this method is to de-materialize all materialized objects 
  *                affected directly or indirectly by this modification and 
  *                notify those objects to the current update session. Each of 
  *                those objects then becomes an owner of this update session 
  *                which is, let us recall it, a shared property. 
  *
  *                Finally, when the current update session is closed, it is 
  *                simply unstacked and destroyed. While being destroyed, it 
  *                materializes again the objects which are still attached to 
  *                it, that is those which were de-materialized within the 
  *                modification phase (and only those ones) and which were not 
  *                destroyed in between (invaluable contribution of the shared 
  *                property). 
  * 
  *  \section      secGoConstructionAndDestruction  Construction and destruction
  *
  *                Graphic objects are, by default, automatically materialized 
  *                at their creation (unless the plugs which are never 
  *                materialized) and forcefully de-materialized at their 
  *                destruction. 
  *
  *                Nevertheless it is possible to inhibit temporarily the 
  *                automatic materialization in some cases (like within the 
  *                loading phase for instance) and to execute the 
  *                materialization a posteriory and in a global way.This allows 
  *                to avoid multiple updates of the quadtree. 
  */


 /*! \function     bool Go::autoMaterializationIsDisabled();
  *  \Return       \true if the automatic materialization is disabled.
  */

 /*! \function     bool Go::isMaterialized() const;
  *  \Return       \true if the Go is materialized, that is, inserted in the
  *                QuadTree.
  */


 /*! \function     void Go::enableAutoMaterialization();
  *  \see          Go::DisableAutoMaterialization().
  */

 /*! \function     void Go::disableAutoMaterialization();
  *                Those two static member functions allows to inhibit
  *                or restore the automatic materialization of all
  *                graphic objects.
  *                
  *                When the automatic materialization is inhibited,
  *                the postponed materialization of dematerialized
  *                objects has to be taken in charge explicitely by
  *                the developper (it will not be automatically done
  *                at the restore of the automatic mode).
  *                
  *                The following sample code shows how to proceed :
\code
Cell* LoadCellFromFile ( ... )
{
   Cell* cell = Cell::create( ... );
 
   bool enabledFlag = not Go::autoMaterializationIsDisabled();
   Go::disableAutoMaterialization(); // we force the mode
 
   ... // we open the file and load the cell 
 
   if (enabledFlag) // we restore the initial state if needed
     Go::enableAutoMaterialization();
 
   cell->materialize(); // delayed materialization of cell content
 
   return cell;
}
\endcode
  */

 /*! \function     void Go::materialize();
  *                Triggers the materialization, that is, insert into the relevant
  *                QuadTree.
  */

 /*! \function     void Go::unmaterialize();
  *                Withdrawn the Go from it's QuadTree.
  */

 /*! \function     void Go::invalidate(bool propagateFlag = true);
  *                This method must be called before a change of the
  *                object geometry.
  *
  *                It is within this function that the object captures
  *                or not the current update session, which involves
  *                its future re-materialization when the time commes.
  *
  *                It is also within this function that all objects,
  *                whose geometry will be affected directly or
  *                indirectly by the object change, must be
  *                invalidated. The flag \c \<propagateFlag\> allows to
  *                limit the propagation in some cases (i.e. when the
  *                contact size changes, objects anchored on it are
  *                not affected and there is no need to invalidate
  *                them).
  *
  *                An already dematerialized object must not be taken
  *                in count in the current update session, but its
  *                propagation, if required, must be systematically
  *                executed.
  *
  * \sample        We give as an example the implementation for the instances :
\code
void Instance::invalidate ( bool propagateFlag )
{
  Inherit::invalidate(false);
 
  if (propagateFlag) {
    forEach(Plug*, iplug, GetConnectedPlugs()) {
      iplug->invalidate(true);
    }
  }
}
\endcode
\code
void Component::invalidate ( bool propagateFlag )
{
  Inherit::invalidate(false);
 
  if (propagateFlag) {
    forEach(Component*, icomponent, GetSlaveComponents()) {
      icomponent->invalidate(false);
    }
  }
}
\endcode
\code
void Contact::setLayer ( Layer* layer )
{
  if (!layer) throw Error("Can't set layer : null layer");
 
  if (layer != _layer) {
    // we do the change only if necessary
    invalidate(false); // done before the modification
 
    _layer = layer;
  }
}
\endcode
\code
void Instance::setTransformation(const Transformation& transformation)
{
  if (transformation != _transformation) {
    // we do the change only if necessary
    invalidate(true); // done before the modification

    _transformation = transformation;
  }
}
\endcode
  */

 /*! \function     void Go::translate(const DbU::Unit& dx, const DbU::Unit& dy);
  *                Translate the graphic object of the quantity \c \<dx\> and 
  *                \c \<dy\>. 
  *
  *                This virtual method should be specialized for a new kind of 
  *                graphic object. 
  */


 //! \name         Go Collection
 //  \{

 /*! \typedef      Gos
  *                Generic collection representing a set of graphic objects. 
  */

 /*! \typedef      GoLocator
  *                Generic locator for visiting a collection of graphic objects. 
  */

 /*! \typedef      GoFilter
  *                Filter to selecting a subset of graphic objects matching some 
  *                criteria. 
  */

 /*! \def          forEach(Go*, igo, gos)
  *                Macro for visiting all graphic objects of a graphic objects 
  *                collection. 
  */

 //  \}

 }
