#ifndef __FILENAMEPLUGIN_H_2004_06_21
#define __FILENAMEPLUGIN_H_2004_06_21

#include <string>

#include <QFileInfo>
#include <QObject>
#include <qstring.h>
#include <qstringlist.h>
#include <qmutex.h>

#include <searchplugin.h>
#include <informationplugin.h>

class FilenameView;
class FilenameSearchInput;
class FilenameFeedbackWidget;
class QWidget;
class QTimer;

namespace NApplication
{
	class RunCommandForOutput;
}

using namespace std;

namespace NPlugin
{

// Class FilenamePlugin
// 
// 
class FilenamePlugin : public SearchPlugin, public InformationPlugin 
{
	Q_OBJECT
public:
	static const QString PLUGIN_NAME;
	FilenamePlugin();
	virtual ~FilenamePlugin();
	/** @name Plugin Interface
	  * 
	  * Implementation of the PluginInterface
	  */
	//@{
	virtual uint priority() const { return 7; };
	virtual void init(IProvider* pProvider);
	/// @todo not yet implemented
	virtual void setEnabled(bool)	{};
	/// @todo not yet implemented
	virtual void setVisible(bool)	{};
	virtual QString name() const { return PLUGIN_NAME; }
	/** @returns &quot;FilenamePlugin&quot; */
	virtual QString title() const;
	virtual QString briefDescription() const;
	virtual QString description() const;
	//@}
	
	/** @name InformationPlugin interface
	  * 
	  * Implementation of the InformationPlugin interface
	  */
	//@{
	virtual uint informationPriority() const	{ return 7; }
	/** @returns a widget which shows a description of this package. */
	virtual QWidget* informationWidget() const;
	/** @returns &quot;Description&quot; */
	virtual QString informationWidgetTitle() const;
	virtual void updateInformationWidget(const string& package);
	virtual void clearInformationWidget();
	/** This plugin offers an information text. */
	virtual bool offersInformationText() const { return false; };
	virtual QString informationText(const string& package);
	//@}
	
	/** @name SearchPlugin interface
	  * 
	  * Implementation of the SearchPlugin interface
	  */
	//@{
	virtual uint searchPriority() const { return 7; };
	virtual QWidget* inputWidget() const;
	virtual QString inputWidgetTitle() const;
	virtual QWidget* shortInputAndFeedbackWidget() const;
	virtual void clearSearch();
	virtual bool usesFilterTechnique() const { return false; };
	virtual const std::set<string>& searchResult() const	{ return _searchResult; };
	virtual bool filterPackage(const string&) const	{ return true; };
	virtual bool isInactive() const;
	//@}
protected:
	/** This exception is thrown to indicate that no information about the 
	  * package could have be retrieved. */
	class NoInformationException
	{
	public:
		/** This holds a message about what wen wrong. */
		QString _errorMessage;
		NoInformationException(const QString& errorMessage)	
			{ _errorMessage = errorMessage; };
	};

	/** @brief This returns the files which belong to the given package.
	  * 
	  * It might return an empty list, if the information can not 
	  * be retrieved immidiately.\n
	  * @throws NoInformationException if no inforamtion about the package
	  * can be retrieved. */
    QStringList filesForPackage(const string& packageName);
	/** @brief File info for the file containing the list of installed files for the package. 
	 * 
	 * I first looks for the file in /var/lib/dpkg/info/<em>packagename</em> without 
	 * any arch extension, then for any file
	 * with an arbitrary extension (returns the first match).
	 * Returns an empty QFileInfo if the package is not installed (i.e. no list file is
	 * available). 
	 */
	QFileInfo getFileListFileName(const string& packageName);
	/** @brief Returns if the given package is installed.
	  */
	bool isInstalled(const string& packageName);
	/** This checks if the apt-file system is available. */
	bool aptFileAvailable();
protected Q_SLOTS:
	/** @brief Slot that calls clearSearch() */
	void onClearSearch()	{ clearSearch(); };
	/** @brief Evaluates the currently entered search. */
	void evaluateSearch();
private Q_SLOTS:
	/** This is called whenever the text of the widget where to insert the 
	  * search pattern changes. */
	void onInputTextChanged(const QString&);
	/** Called when the search process has exited. */
	void onSearchProcessExited();
	/** Called when the search process has exited. */
	void onFilelistProcessExited();
	/** Called whenever the user clicked "show" in the view. */
	void onShowRequested();
private:
	/** Locked if we currently evaluate a search. */
	QMutex _processMutex;
	/** Process currently executed, make sure to get the _processMutex if you want to use it.
	  *
	  * 0 if no process is currently running. */
	NApplication::RunCommandForOutput* _pProcess;
	/** @brief This checks if the given entry is for the handed package and 
	  * prepares the entry for output.
	  * 
	  * It works on entries as returned by <tt>apt-file list <i>packageName</i></tt>. 
	  * (which have the type: <tt>package: filename</tt>).
	  * The entries which are for the given package will be changed to represent the
	  * file location (i.e. the leading <tt>packageName: </tt> will be replaced by <tt>/</tt>).
	  * @param entry the entry to be fixed (it will be changed by this function)
	  * @param packageName the package to be matched against 
	  * @returns false if the entry is not for the current package (i.e. does not start with packageName:) 
	  * else true.
	  */
	bool fixEntry(QString& entry, const QString& packageName);
	/** Widget where the search might be enterd. */
	FilenameSearchInput* _pInputWidget;
	/** The widget where the files will be shown in. */
	FilenameView* _pFileView;
	/** The widget where the search selected is shown in. */
	FilenameFeedbackWidget* _pFilenameFeedbackWidget;
	/** Holds a pointer to the pluginmanager which manages this pugin. */
	IProvider* _pProvider;
	/** This holds the result of the currently active search. */
	std::set<string> _searchResult;
	/** This timer is used to delay the evaluation of the search a little to avoid unneccessary operations
	  * e.g. on text input. */
	QTimer* _pDelayTimer;
	/** This is the delay time in ms the delay timer waits for another input. */
	uint _delayTime;
	/** The package where information for should be displayed. */
	QString _currentPackage;
	/** @brief Returns an error message reporting, that apt-file is missing, and required for
	  * retrieving file information for the given package. 
	  */
	QString aptFileMissingErrorMsg(QString packageName);
};



}	// namespace NPlugin

#endif //	__FILENAMEPLUGIN_H_2004_06_21

