/* 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_TPLUGIN_HPP
#define NMM_TPLUGIN_HPP NMM_TPLUGIN_HPP

#include "nmm/nmm_prefix.hpp"

#include "Plugin.hpp"
#include "INode.hpp"
#include "NodeDescription.hpp"
#include "TFactoryObject.hpp"

namespace NMM {

/** A standard plug-in.
 * This parametrized class offers a standard implementation of the class Plugin.
 * It can be used for registration of most classes of nodes.
 *
 * If the node needs no configuration events, then this class can be used without any extension.
 * Otherwise, a subclass of this class can reimplement the nmmRegistryInit() method to send
 * the required configuration events to the node.
 */
template <typename T >
class TPlugin : public Plugin {
public:
  /** @name Constructor & Destructor
   */
  //@{
  /** Create a plug-in.
   *
   * @param node_name The name of the node
   * @param max_instances Maximum number of instances. A value of -1 means no limitation.
   */
  TPlugin(const std::string& node_name, int max_instances = -1)
    : Plugin(node_name, max_instances) { }

  /** Virtual destructor.
   */
  virtual ~TPlugin() {  }
  //@}

  /** @name Plug-in Registration
   */
  //@{
  /** Plug-in activation.
   * This method is called by the PluginManager when the plug-in is activated.
   * It can be implemented by subclasses to perform specific actions required for a particular plug-in.
   *
   * The default implementation does nothing and never throws an exception.
   *
   * @exception SerializedException if an error occurred
   * @exception Exception if an error occurred
   */
  virtual void nmmInit()
    throw(const Exception&, const SerializedException&) {}

  /** Plug-in deactivation.
   * This method is called by the PluginManager when the plug-in is deactivated.
   * It can be implemented by subclasses to perform specific actions required for a particular plug-in.
   * This method may not throw an exception.
   *
   * The default implementation does nothing.
   * It must always be called by implementations in subclasses.
   */
  virtual void nmmFini()      {}

  /** Plug-in registration.
   * This method is called by the PluginManager when the plug-in is registered.
   * It can be implemented by subclasses to perform specific actions required for a particular plug-in.
   *
   * The default implementation creates a node description from the node and registers the node.
   * It must always be called by implementations in subclasses.
   *
   * @exception SerializedException if an error occurred
   * @exception Exception if an error occurred
   */
   virtual void nmmRegistryInit()
     throw(const Exception&, const SerializedException&);

  /** Plug-in deregistration.
   * This method is called by the PluginManager when the plug-in is deregistered.
   * It can be implemented by subclasses to perform specific actions required for a particular plug-in.
   * This method may not throw an exception.
   *
   * The default implementation does nothing.
   * It must always be called by implementations in subclasses.
   */
  virtual void nmmRegistryFini();

  /** Plug-in factory registration.
   * This method is called by the PluginManager when the node is registered at the NodeFactory.
   * It can be implemented by subclasses to perform specific actions required for a particular plug-in.
   *
   * The default implementation does nothing.
   * It must always be called by implementations in subclasses.
   *
   * @exception SerializedException if an error occurred
   * @exception Exception if an error occurred
   */
  virtual void nmmFactoryInit()
    throw(const Exception&, const SerializedException&);

  /** Plug-in factory deregistration.
   * This method is called by the PluginManager when the node is deregistered at the NodeFactory.
   * It can be implemented by subclasses to perform specific actions required for a particular plug-in.
   * This method may not throw an exception.
   *
   * The default implementation does nothing.
   * It must always be called by implementations in subclasses.
   */
  virtual void nmmFactoryFini();

  /** Get factory object.
   * This method returns a factory object for this plug-in.
   * The caller is responsible for deleting the returned FactoryObject.
   *
   * This implementation creates a TFactoryObject for the node class of this plug-in.
   *
   * @return A new factory object for this plug-in
   */
  virtual FactoryObject* getFactoryObject() { return new TFactoryObject<T>(getLibraryName(), getNodeName()); }
//@}
};


template <typename T>
void TPlugin<T>::nmmRegistryInit()
  throw(const Exception&, const SerializedException&)
{
  /* 1. create a dummy node  */
  T node;

  /* 3. prepare the interface for registration and get the interface that must be used */
  INode_var i_node( prepareRegistration( node ) );

  /* 4. create the NodeDescription */
  NodeDescription description;
  createNodeDescription(*i_node.get(), description);

  /* 5. and finaly register the node */
  registerNode( description, getMaxInstanceCount() );
}

template <typename T>
void TPlugin<T>::nmmRegistryFini()
{

}

template <typename T>
void TPlugin<T>::nmmFactoryInit( )
   throw(const Exception&, const SerializedException&)
{

}

template <typename T>
void TPlugin<T>::nmmFactoryFini( )
{

}

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

#endif

