/* 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_IRegistry_HPP
#define NMM_IRegistry_HPP

#include "nmm/nmm_prefix.hpp"

#include "nmm/comm/Interface.hpp"
#include "nmm/comm/messaging/Event.hpp"
#include "nmm/comm/messaging/IllegalStateException.hpp"
#include <memory>

/* Network-Integrated Multimedia Middleware (NMM)
 * http://www.motama.com/nmm.html
 *
 * Copyright (C) 2006-2007
 * Motama GmbH, Saarbruecken, Germany
 * http://www.motama.com
 *
 * See file LICENCE for terms and conditions of usage
 *
 */

#include "Response.hpp"
#include "NodeFactoryID.hpp"
#include "FactoryTicket.hpp"
#include "RegistryException.hpp"
#include "nmm/multimedia/NodeDescription.hpp"
#include "GraphDescription.hpp"
#include "RegistryMemento.hpp"
#include "NodeInfo.hpp"
#include "nmm/multimedia/INode.hpp"

#include "visibility.hpp"

namespace NMM
{
  /** \class IRegistry
   * Base class for all Registry Interfaces.
   */

  class DLLEXPORT IRegistry : virtual public NMM::Interface { 
  public:
    IRegistry() : NMM::Interface(IRegistry::IRegistry_type, "NMM") { };

    IRegistry(NMM::NMMObject& parent) : NMM::Interface (parent, IRegistry::IRegistry_type, "NMM") { };

    virtual ~IRegistry() {};

    static const char* IRegistry_type;

    virtual  string getInterfaceType() const { return IRegistry_type; }

    NMM::Interface* copy() const { return new IRegistry(*this); }
    static void used(); 
    static const char* requestNode_event;
    static const char* requestObject_event;
    static const char* releaseNode_event;
    static const char* releaseObject_event;
    static const char* initRequest_event;
    static const char* initObjectRequest_event;
    static const char* searchNode_event;
    static const char* reserveNode_event;
    static const char* instantiateNode_event;
    static const char* releaseReservation_event;
    static const char* destroyNode_event;
    static const char* getMaxInstanceCount_event;
    static const char* getInstanceCount_event;
    static const char* getPluginInfo_event;
    static const char* getNodeList_event;
    static const char* getReservedNodeList_event;
    static const char* getNodeInfoList_event;
    static const char* getNodeDescription_event;
    static const char* getNodeDescriptionList_event;
    static const char* getNodeFactoryID_event;
    static const char* resetInternalReservation_event;
    static const char* resetSpecificInternalReservation_event;
    static const char* initTransaction_event;
    static const char* closeTransaction_event;
    static const char* getRegistryID_event;
    static const char* getChildList_event;
    static const char* isSubRegistry_event;
    static const char* getMemento_event;
    static const char* setMemento_event;
    /** This method requests a Node and returns its INode interface. 
     *
     * If the Node can not be requested
     * an exception is thrown. This method calls the method reserveNode() to reserve the Node
     * and instantiateNode() to create it.
     * 
     * @param reg The RegistryID of the Registry which manages the node.
     * @param node_id The ObjectID of the Node that is requested.
     * @param info The UserInfo of the application that requests the node.
     * @param nd NodeDescription describing the node
     * @return INode interface for requested Node
     * @sa reserveNode()
     * @sa instantiateNode()
     */

    virtual INode* requestNode(const RegistryID& reg, const ObjectID& node_id, const UserInfo& info, NodeDescription& nd)
      throw(const NMM::SerializedException&, const RegistryException&);
    /** This method requests a Object and returns its interface. 
     *
     * If the objecte can not be requested an exception is thrown. 
     *
     * @param reg The RegistryID of the Registry which manages the node.
     * @param node_id The ObjectID of the object that is requested.
     * @param info The UserInfo of the application that requests the object.
     * @return Interface for requested object
     */

    virtual Interface* requestObject(const RegistryID& reg, const ObjectID& node_id, const UserInfo& info)
      throw(const NMM::SerializedException&, const RegistryException&);
    /** This method releases a requested Node. 
     *
     * This method calls the method releasReservation() to
     * to release the reservation and destroyNode() to delete it.
     *
     * @param reg_id The RegistryID of the Registry which manages the node.
     * @param ref The NMMReference of the Node that is released.
     * @param node_id The ObjectID of the Node that is released.
     * @param user_info The UserInfo of the application that requested the node.
     * @sa releaseReservation()
     * @sa destroyNode()
     */

    virtual void releaseNode(const RegistryID& reg_id, const NMMReference& ref, const ObjectID& node_id, const UserInfo& user_info)
      throw(const NMM::SerializedException&);
    /** This method releases a requested object. 
     *
     * @param reg_id The RegistryID of the Registry which manages the object.
     * @param ref The NMMReference of the object that is released.
     * @param node_id The ObjectID of the object that is released.
     * @param user_info The UserInfo of the application that requested the object.
     */

    virtual void releaseObject(const RegistryID& reg_id, const NMMReference& ref, const ObjectID& node_id, const UserInfo& user_info)
      throw(const NMM::SerializedException&);
    /** Searches for Nodes with capabilities described in given NodeDescription.
     *
     * This method searches for Nodes with certain capabilities, which are described in the
     * NodeDescription.
     *
     * @param node_desc The NodeDescription with the requirements of a searched node.
     * @return list of Responses 
     */

    virtual list<Response >  initRequest(const NodeDescription& node_desc) const
      throw(const NMM::SerializedException&);
    /** This method searches for objects with certain capabilities, which are described in the
     * ObjectDescription.
     *
     * @param node_desc The ObjectDescription with the requirements of a searched object.
     * @return list of Responses for request
     */

    virtual list<Response >  initObjectRequest(const ObjectDescription& node_desc) const
      throw(const NMM::SerializedException&);
    /** Searches for Node matching the given NodeDescription.
     *
     * This method searches for a specific node that matches the given NodeDescription. The NodeDescription
     * is created by an application and stores the information, like formats and interfaces, that must be
     * supported by the node.
     *
     * @param registry_id The RegistryID of the Registry that should be searched.
     * @param node_desc The NodeDescription that must be supported by the nodes
     * @return A list of ObjectID's from nodes that support the requirements in the NodeDescription
     */

    virtual list<ObjectID >  searchNode(const RegistryID& registry_id, const NodeDescription& node_desc) const
      throw(const NMM::SerializedException&);
    /** Reserves node managed by given Registry.
     *
     * This method reserves a node which is managed by a Registry. If the reservation is succesfull,
     * the Registry returns a FactoryTickt that allows the caller to instantiate a Node by a NodeFactory.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param node_id The ObjectID of the Node which is used to identify the Node inside the Registry
     * @param info The UserInfo identifies the user that requests the Node. If the node is released this parameter must be specified again, whereby no other user can release the reserved node.
     * @return FactoryTickt that allows the caller to instantiate a Node by a NodeFactory
     */

    virtual FactoryTicket reserveNode(const RegistryID& reg_id, const ObjectID& node_id, const UserInfo& info)
      throw(const NMM::SerializedException&, const RegistryException&);
    /** Creates an instance of a reserved node.
     *
     * This method creates an instance of a reserved node. If the node can be created its INode interface is
     * returned. Otherwise an exception is thrown.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param ticket The FactoryTicket must be send to allow the Registry to instantiate the node
     * @param info The UserInfo identifies the user that requests the Node. If the node is released
     *        this parameter must be specified again, whereby no other user can release the reserved node.
     * @return INode interface for instantiated Node
     * @sa destroyNode
     */

    virtual INode* instantiateNode(const RegistryID& reg_id, const FactoryTicket& ticket, const UserInfo& info)
      throw(const NMM::SerializedException&, const RegistryException&);
    /** Releases a reserved node.
     *
     * This method releases a reserved node. The node is not destroyed, only th reservation is released.
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param node_id The ObjectID of the reserved node
     * @param user_info The UserInfo identifies the user that requests the Node. If the node is released
     *        this parameter must be specified again, whereby no other user can release the reserved node.
     * @sa reserveNode
     */

    virtual void releaseReservation(const RegistryID& reg_id, const ObjectID& node_id, const UserInfo& user_info)
      throw(const NMM::SerializedException&);
    /** This method destroys a created node.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param reference The NMMReference of the instantiated node.
     * @param info The UserInfo identifies the user that requests the Node. If the node is released
     *        this parameter must be specified again, whereby no other user can release the reserved node.
     * @sa instantiateNode
     */

    virtual void destroyNode(const RegistryID& reg_id, const NMMReference& reference, const UserInfo& info)
      throw(const NMM::SerializedException&);
    /** This method returns the maximum instance count for a specific node.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param node_id The ObjectID of the node.
     * @return maximum instance count for specified node
     */

    virtual nmm_int32 getMaxInstanceCount(const RegistryID& reg_id, const ObjectID& node_id) const
      throw(const NMM::SerializedException&);
    /** This method returns the current instance count for a specific node.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param node_id The ObjectID of the node.
     * @return current instance count for specified node
     */

    virtual nmm_int32 getInstanceCount(const RegistryID& reg_id, const ObjectID& node_id) const
      throw(const NMM::SerializedException&);
    /** This method returns the library that must be load for a specific node.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param node_id The ObjectID of the node.
     * @return library that must be loaded for specified node
     */

    virtual string getPluginInfo(const RegistryID& reg_id, const ObjectID& node_id) const
      throw(const NMM::SerializedException&);
    /** This method returns ObjectIDs of all nodes that are available.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @return ObjectIDs of all nodes that are available
     */

    virtual list<ObjectID >  getNodeList(const RegistryID& reg_id) const
      throw(const NMM::SerializedException&);
    /** This method returns ObjectIDs of all nodes that are currently reserved and not available.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @return ObjectIDs of all nodes that are currently reserved and not available
     */

    virtual list<ObjectID >  getReservedNodeList(const RegistryID& reg_id) const
      throw(const NMM::SerializedException&);
    /** This method returns a short NodeInfo for all nodes that are managed in a specific registry.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @return list of NodeInfos of all nodes managed in specified registry
     */

    virtual list<NodeInfo >  getNodeInfoList(const RegistryID& reg_id) const
      throw(const NMM::SerializedException&);
    /** This method returns the complete NodeDescription of a specifc node.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param node_id The ObjectID of the node.
     * @return NodeDescription of specified node
     */

    virtual NodeDescription getNodeDescription(const RegistryID& reg_id, const ObjectID& node_id) const
      throw(const NMM::SerializedException&);
    /** This method returns all NodeDescriptions stored by a Registry.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @return list of all NodeDescriptions stored by specified registry
     */

    virtual list<NodeDescription >  getNodeDescriptionList(const RegistryID& reg_id)
      throw(const NMM::SerializedException&);
    /** This method returns the NodeFactoryID of the NodeFactory that can instantiate a specific node.
     *
     * @param reg_id The RegistryID of the Registry that should be searched.
     * @param node_id The ObjectID of the node.
     * @return NodeFactoryID of the NodeFactory that can instantiate specified node
     */

    virtual NodeFactoryID getNodeFactoryID(const RegistryID& reg_id, const ObjectID& node_id) const
      throw(const NMM::SerializedException&);
    /** This method releases ALL Nodes.
     */

    virtual void resetInternalReservation()
      throw(const NMM::SerializedException&);
    /** This method releases ALL Nodes reserved by specifc user.
     *
     * @param user_info UserInfo specifying user which Nodes should be released
     */

    virtual void resetSpecificInternalReservation(const UserInfo& user_info)
      throw(const NMM::SerializedException&);
    /** This method enables the access control. 
     *
     * If the access control is enabled, no other application can access the Registry.
     *
     * @param info The UserInfo of the application that tries to enable the access control.
     */

    virtual void initTransaction(const UserInfo& info)
      throw(const NMM::SerializedException&, const RegistryException&);
    /** This method disables the access control, so other applications can access the Registry again.
     *
     * @param info The UserInfo of the application that tries to disable the access control.
     */

    virtual void closeTransaction(const UserInfo& info)
      throw(const NMM::SerializedException&);
    /** This method returns the RegistryID of this Registry.
     *
     * @return RegistryID of this Registry
     */

    virtual RegistryID getRegistryID() const
      throw(const NMM::SerializedException&);
    /** This method returns the RegistryID's of all child-Registries.
     *   
     * @param registry_id Registry to get lis of children 
     * @return list of registry children of given Registry
     */

    virtual list<RegistryID >  getChildList(const RegistryID& registry_id) const
      throw(const NMM::SerializedException&);
    /** Tests if Registry is managed by this Registry or by one of its children.
     *
     * This method returns true, if the Registry with given RegistryID is managed by this
     * Registry or by one the children of the Registry.
     *
     * @param reg_id The RegistryID of the searched Registry.
     * @return true if Registry is manager by this Registry or one of its children, false otherwise
     */

    virtual nmm_bool isSubRegistry(const RegistryID& reg_id) const
      throw(const NMM::SerializedException&);
    /** Returns RegistryMemento.
     *
     * @return RegistryMemento
     */

    virtual RegistryMemento getMemento()
      throw(const NMM::SerializedException&);
    /** Sets RegistryMemento.
     *
     * @param rm RegistryMemento to set
     */

    virtual void setMemento(const RegistryMemento& rm)
      throw(const NMM::SerializedException&);


  };

  typedef auto_ptr<IRegistry> IRegistry_var;




}

#include "nmm/nmm_suffix.hpp"

#endif
