#ifndef __SEARCHPLUGIN_H_2004_06_21
#define __SEARCHPLUGIN_H_2004_06_21

#include <string>
#include <list>
#include <set>

#include <QObject>
#include <QString>

#include "plugin.h"

class QWidget;

using namespace std;

namespace NPlugin
{
// Interface SearchPlugin
// 
// 
/**
 * TODO: change signal "void searchChanged(NPlugin::SearchPlugin* pPlugin)" to 
 * listener pattern based on function. This way, we can get rid of the QObject 
 * stuff here (which severly breaks design). Instead plugins should themselves
 * derive from QOBject if desired.
 */
class SearchPlugin : public QObject, virtual public Plugin 
{
	Q_OBJECT
public:
	/** @brief This returns the widget which is used for inputting the information.
	  *
	  * In opposite to shortInputAndFeedbackWidget() this can be used to show 
	  * larger widgets. They will be shown in a seperate section so they won't
	  * push the user.
	  * @returns the widget used, 0 if no such widget is offered by this plugin
	  */
	virtual QWidget* inputWidget() const = 0;
	/** @brief This returns the title used for the input widget.  */
	virtual QString inputWidgetTitle() const = 0;
	/** @brief Returns the widget to be shown in the easy accesible area of the SearchWindow.
	  * Use this if your widget is really small (perhaps two lineedits) and you consider your
	  * search to be important only. 0 if no such widget exists.<br>
	  * It can also be the widget used to show the currently active. Such a feedback widget 
	  * should only be shown if there is an active search (i.e. isInactive()). You should 
	  * really offer such a feedback widget if you do also offer input widgets
	  */
	virtual QWidget* shortInputAndFeedbackWidget() const = 0;
	/**
	  * @brief This clears the currently entered search.
	  * 
	  * It sets all widgets to an empty search. The searchChanged signal will not be emitted.
	  */
	virtual void clearSearch() = 0;
	/** @brief @returns if this plugin uses filtering to create its results. 
	  * 
	  * This means that packges are queried via filterPackage() and processed accordingly. 
	  * This is in opposite to the searchResults() funtion. Only one of the techniques can be used.
	  */
	virtual bool usesFilterTechnique() const = 0;
	/** @brief @returns the set of packages which matched the search. 
	  * This function must not be used if usesFilterTechnology() returns true.
	  * 
	  * @see usesFilterTechnology()
	  */
	virtual const std::set<string>& searchResult() const = 0;
	/**
	  * 
	  * @param package package to be checked
	  */
	virtual bool filterPackage(const string& package) const = 0;
	/**
	  * @returns Returns the widget to be shown in the easy accesible area of the SearchWindow. 
	  * Use this if your widget is really small (perhaps two lineedits) and you consider 
	  * your search to be important only. 0 if no such widget exists.<br>
	  * It can also be the widget used to show the currently active. Such a feedback widget 
	  * should only be shown if there is an active search (i.e. isInactive()). You should 
	  * really offer such a feedback widget if you do also offer input widgets
	  * 
	  * 
	  */
	virtual bool isInactive() const = 0;
	/** @brief Returns the priority of this search plugin. 
	  * 
	  * Lower values mean that the plugins output will be shown most visible (e.g. on top). */
	virtual uint searchPriority() const = 0;
signals:
	/**
	  * The searchChanged signal is emitted whenever the results produced by this 
	  * search have changed. The SearchWindow will evaluate the search then.
	  * @param pPlugin the plugin that emitted this signal
	  * @warning always make sure to have a matching signature when matching - remember that
	  * for QT the strings must match not the types (i.e. SLOT(searchChanged(SearchPlugin* pPlugin))
	  * won't work.
	  */
	void searchChanged(NPlugin::SearchPlugin* pPlugin);
};


}	// namespace NPlugin

#endif //	__SEARCHPLUGIN_H_2004_06_21

