/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *  
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *  
 * This file is part of NMM. 
 * 
 * NMM is free software; you can redistribute it and/or modify it    
 * under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; only version 2 of the License.      
 * 
 * NMM is distributed in the hope that it will be useful, but WITHOUT 
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 
 * License for more details.  
 * 
 * You should have received a copy of the GNU General Public License 
 * along with NMM; if not, write to the Free Software Foundation,    
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 */
#ifndef NMM_FACTORYTICKET_HPP
#define NMM_FACTORYTICKET_HPP

#include "nmm/nmm_prefix.hpp"

#include "NodeFactoryID.hpp"
#include "nmm/comm/ObjectID.hpp"

#include "nmm/comm/serialize/SerializedValue.hpp"
#include "nmm/comm/messaging/Event.hpp"
#include "nmm/comm/messaging/CEvent.hpp"

namespace NMM {
  /** A FactoryTicket authorizes an component to instantiate a Node by a NodeFactory.
   */
  class FactoryTicket  :  public SerializedValue {
  friend class Registry;
  friend class NodeFactory;
  public:
    /** @name Constructor & Destructor
     */
    //@{
    /** Constructor.
     */
    FactoryTicket();

    /** Copy-Constructor.
     *
     * @param ft FactoryTicket to copy
     */
    FactoryTicket(const FactoryTicket& ft);

    /** virtual Copy-Constructor
     *
     * @return a copy of this FactoryTicket. 
     */
    FactoryTicket* copy()                             const { return new FactoryTicket(*this); }
    //@}

    /** @name Operator
     */
    //@{
    /** The assignment operator stores all values from the given ft in this object. 
     *
     * If the is_valid-flag is true in the given ft, it is set to false and the 
     * is_value-flag of this FacotryTicket is set to true. 
     * So the implementation of the assignement operator ensures that a valid 
     * FactoryTicket can not be used twice.
     *
     * @param ft reference to the FactoryTicket that should be assigned
     * @return reference to the assigned FactoryTicket
     */
    FactoryTicket& operator=(const FactoryTicket& ft);
    //@}

    /** @name Access FacotryTicket information
     */
    //@{
    /** This method returns the config event to configure the created node.
     * 
     * @return configuration event that must be send to the Node. 
     */
    inline const CEvent& getConfigEvent()             const { return __config_event; }

    /** This method returns the config event to configure the created node.
     * 
     * @return configuration event that must be send to the Node. 
     */
    inline       CEvent& getConfigEvent()                   { return __config_event; }

    /** This method returns the NodeFactoryID of the NodeFactory that can create the node.
     * 
     * @return ID of the NodeFactory that can instantiate the corrsponding Node. 
     */
    inline const NodeFactoryID& getNodeFactoryID()    const { return __factory_id; }

    /** This method returns the NodeFactoryID of the NodeFactory that can create the node.
     * 
     * @return ID of the NodeFactory that can instantiate the corrsponding Node. 
     */
    inline       NodeFactoryID& getNodeFactoryID()          { return __factory_id; }

    /** This method returns the ObjectID of the node that should be created.
     * 
     * @return the ObjectID of the node that should be created.
     */
    inline const ObjectID& getObjectID()                  const { return __node_id.getRValue(); }

    /** This method returns true if the FactoryTicket can be used to create a node. If the node
     * was created, the FactoryTicket returns false.
     *
     * @return true, if the FactoryTicket is still valid, false otherwise. 
     */
    inline bool  isValid()                            const { return __is_valid.getRValue(); }
    //@}

    /** @name Set FactoryTicket information
     * These methods are for internal use in a Registry.
     */
    //@{
    /** This method sets the ObjectID of the Node that should be created.
     *
     * @param node_id The ObjectID of the node that should be created.
     */
    inline void  setObjectID(const ObjectID& node_id)           { __node_id.setValue(node_id); }

    /** This method sets ConfigEvent which is need to configure the node.
     *
     * @param config_event The CEvent that is send to the node.
     */
    inline void  setConfigEvent(const CEvent& config_event) { __config_event = config_event; }

    /** This method sets the NodeFactoryID of the NodeFactory which can create the Node.
     *
     * @param id NodeFactoryID The ID of the NodeFactory.
     */
    inline void  setNodeFactoryID(const NodeFactoryID& id)  { __factory_id = id; }
    //@}

  protected:
    /** Sets the internal valid-flag to the given value.
     *
     * @param value the new value of the is_valid-flag
     */
    void  setValid(bool value)                        const { __is_valid = value; }
  private:

    /** This method registers all attributes by the base class for serialization/deserialization.
     */
    void  registerAttributes();

  private:
    CEvent                    __config_event;    ///< stores the configuration of the node.
    NodeFactoryID             __factory_id;      ///< stores the NodeFactoryID of the NodeFactory that can create the node
    TValue<ObjectID>          __node_id;         ///< stores the ObjectID of the node
    mutable TValue<nmm_bool>      __is_valid;        ///< is true if the FacotryTicket is valid
  };

}//end namespace
#include "nmm/nmm_suffix.hpp"

#endif
