#ifndef PLUGIN_LOADER_H
#define PLUGIN_LOADER_H

#include <qstring.h>
#include <qvaluelist.h>
#include <qstringlist.h>
#include <noatunapp.h>

#include <klibloader.h>
#include <qdict.h>

struct NoatunLibraryInfo
{
	QString specfile;
	QString filename;
	QString author;
	QString license;
	QString type;
	QString site;
	QString email;
	QString name;
	QString comment;
	QStringList require;
};

class PlayList;
class Visualization;
class Plugin;

class LibraryLoader
{
	friend class Plugin;
	struct PluginLibrary
	{
		Plugin *plugin;
		const char *title;
		void (Plugin::*deleter)();
		KLibrary *library;
	};

public:
	LibraryLoader();
	~LibraryLoader();

	QValueList<NoatunLibraryInfo> availible() const;
	QValueList<NoatunLibraryInfo> loaded() const;

	/**
	 * loads all the enabled plugins
	 **/
	bool loadAll(void);
	bool loadAll(const QStringList &);

	bool isLoaded(const QString &spec) const;
	void add(const QString &spec);
	void setModules(const QStringList &mods);
	/**
	 * unload the plugin specified by spec
	 **/
	bool remove(const QString &spec);
	/**
	 * unload the plugin that is plugin
	 **/
	bool remove(const LibraryLoader::PluginLibrary *plugin);
	bool remove(const Plugin *plugin);
	
	PlayList *playlist() const;

	/**
	 * When you call NOATUNPLUGINC(ClassName)
	 * well, title is ClassName
	 **/
	Plugin *pluginByName(const QCString &title);

	/**
	 * This is needed for the Plugin-List-View
	 * to see what plugins are required to show
	 * (when required by another noatun-plugin)
	**/
	NoatunLibraryInfo getInfo(const QString &spec) const;
	
public: // DO NOT CALL THIS!!!
	void _addHashCallback(const char *title, void (Plugin::*deleter)());
	void _addHashCallback(void (Plugin::*deleter)()) {_addHashCallback(0,deleter);}

private:
	bool loadSO(const QString &spec);
	void removeNow(const QString &spec);

private:
	QDict<LibraryLoader::PluginLibrary> mLibHash;
	PlayList *mPlaylist;
	PluginLibrary *mCurrentCallbackRes;
};

#endif

