#ifndef __PLUGINCONTAINER_H_2004_06_23
#define __PLUGINCONTAINER_H_2004_06_23

#include <vector>
#include <utility>

#include <qstring.h>

#include "iplugininformer.h"
#include "ixmlstorable.h"

#include "xmldata.h"

using namespace std;

class QWidget;
class QAction;

namespace NPlugin
{

class Plugin;
class IProvider;


/** This collects the information about a plugin.
  * 
  * It should be offered by every plugin via a get_pluginInformation() 
  * function.
  */
struct PluginInformation
{
	PluginInformation(const string& name_="", const string& version_="", const string& author_="")
	{
		name = name_;
		version = version_;
		author = author_;
	}
	string name;
	string version;
	string author;
	/** Compares to plugins are identical by comparing all available attributes. */
	bool operator==(const PluginInformation& p) const
	{
		return name == p.name && version == p.version && author == p.author;
	}
};



// Interface PluginContainer
// 
// 
class PluginContainer : public IPluginInformer, public NXml::IXmlStorable
{
public:
	virtual ~PluginContainer() {};
	/** @brief Loads and initializes all offered plugins.
	  *
	  * @param pProvider the provider which offers information for the plugins
	  * @returns if the plugin was successfully initialized, if it returns false,
	  * the plugin container should be deleted by the plugin user as the plugin
	  * container is in an undefined state and function calls might crash the 
	  * application.
	  */
	virtual bool init(IProvider* pProvider) = 0;
	/** This returns the names of all plugins offered by this container. */
	virtual vector<string> offeredPlugins() const = 0;
	/** @brief Get the plugin with the given name. The plugin is not 
	  * initialized so call Plugin::init() for it.
	  *
	  * Release the requested plugins with releasePlugin().
	  * @param name name of the plugin to be requested
	  * @returns the plugin with this name, or 0 if no such plugin exists
	  */
	virtual Plugin* requestPlugin(const string& name) = 0;
	/** Gets a list of all plugins currently loaded. 
	  */
	virtual vector<Plugin*> getLoadedPlugins() const = 0;
	/** @brief This signals that a user of the Plugin no longer uses it. 
	  *
	  * It is used to see if we can delete shared resources. The plugin 
	  * will be deleted by this function. If the plugin is not owned by this
	  * container the function will return immidiately.
	  * @param pPlugin the plugin to be released
	  */
	virtual void releasePlugin(Plugin* pPlugin) = 0;
	/** Returns the title of this container.
	  */
	virtual QString title() const = 0;
	/** @brief Returns the name of this plugin.
	  *
	  * This must correspond to the name of the library where the plugin is stored in.
	  * It is case sensitive. It should be a unique identifier from all available plugins.
	  */
	virtual string name() const = 0;
	/** @brief This will return a widget to control the Plugin Container 
	  * (i.e. enabling/disabling parts of the plugin container and make 
	  * settings for the plugins).
	  *
	  * The PluginContainer will cease control about the widget to the calling 
	  * function and if this does not care, the widget will be deleted with its 
	  * parent (through the QT Garbage collection).\n
	  * The Widget will be connected to the container, so the container can 
	  * handle the input from the widget.\n
	  * The default implementation (if not overloaded) is to return 0.
	  * @param pParent the parent for this control widget. It will delete the 
	  * widget returned if destroyed
	  */
	virtual QWidget* getSettingsWidget(QWidget* pParent);
	/** @brief Call this to apply the settings configured in the settings widget.
	  *
	  * Call this function only after getSettingsWidget() was called and before
	  * the widget is deleted.\n
	  * The default implementation is empty.
	  */
	virtual void applySettings();
};

}	// namespace NPlugin

#endif //	__PLUGINCONTAINER_H_2004_06_23

