#ifndef _PROTOCOL_H_
#define _PROTOCOL_H_

#include <qstring.h>
#include <qstrlist.h>
#include <qregexp.h>
#include "ProgressDlg.h"
//#include <qprogressdialog.h>
#include <kurl.h>

#include "fileinfo.h"
#include "mimemagic.h"
#include "kmime.h"
#include "protinter.h"


class SubProtocol;
typedef QList<SubProtocol> 	SubProtList;
typedef QListIterator<SubProtocol>	SubProtListIterator;

SubProtocol* matchFileName(const char *str, SubProtList *list);

class Protocol
{
	friend void* thread_Interface(ProtocolCmd *cmd);
	friend void thread_Cleanup(ProtocolCmd *cmd);

public:
	enum TypeSpec { File, Mount, Ftp, Trash, Arch, Tar, Zip, Rpm};

	Protocol(TypeSpec type = File);
	virtual ~Protocol();

	int type() const;
	void setupMime(KMimeExtDict *extDict = 0, KMimeExtList *nameDict = 0, MimeMagic *magic = 0, bool use = TRUE);
	KMimeExtension* getMimeTypeFromExtension(FileInfo *fi);
	KMimeExtension* getMimeTypeFromName(FileInfo *fi);
	KMimeExtension* getMimeTypeFromMagic(FileInfo *fi);
	KMimeExtension* getMimeTypeFromNode(FileInfo *fi);
	void setupSubProtList(SubProtList *list = 0);

//	virtual bool cd(const char *path) = 0;
//	virtual bool cdUp() = 0;
//	virtual int sorting() = 0;
//	virtual void setSorting(int sort) = 0;
//	virtual int filter() = 0;
//	virtual void setFilter(int filt) = 0;
	virtual const FileInfoList* entryInfoList(bool hidden, bool dirsOnly, bool showArchive = FALSE) = 0;
	virtual const QStrList* entryList(bool hidden, bool dirsOnly, bool showArchive = FALSE) = 0;
//	virtual bool isReadable() = 0;
	virtual bool mkdir(const char *pathname) = 0;
	virtual QString absPath() = 0;
	virtual bool setPath(const char *pathname) = 0;
	virtual QString dirName() = 0;
	virtual bool remove(const char *filename) = 0;
	virtual bool rmdir(const char *dirname, ProgressDlg *dlg = 0) = 0;
	virtual bool isRoot() = 0;
	virtual bool rename(const char *src, const char *dest) = 0;
	virtual bool exists(const char *filename) = 0;
	virtual bool chmod(const char *filename, int perm) = 0;

	virtual bool copyToProtocol(const char *filename, const char *targetDir = 0, bool move = FALSE, ProgressDlg *dlg = 0) = 0;
	virtual bool copyFromProtocol(const char *filename, const char *targetDir, bool move = FALSE, ProgressDlg *dlg = 0) = 0;
	virtual bool init() = 0;
	virtual bool finish() = 0;
	virtual bool cleanup() = 0;
	virtual bool matchURL(KURL url) = 0;
	virtual const char* currentURL() = 0;
	virtual bool isLocal() = 0;
	void abort();
	int score() { return Prefix.length();}
	QString prefix() { return Prefix;}
	const char* errorMsg() { return ErrorMsg.data();}
	virtual uint freeSize(const char *dirname) = 0;
	virtual bool hasChilds(const char *dirname) = 0;
	virtual FileInfo* getInfo(KURL& url) = 0;
//	virtual int dirSize(const char *dirname) = 0;
	virtual void shutDown();

protected:
	TypeSpec	Type;
	KMimeExtDict	*ExtDict;
	KMimeExtList	*NameDict;
	MimeMagic	*Magic;
	bool		UseMagic;
	pthread_t	th_ID;
	QString		Prefix;
	QString		ErrorMsg;
	SubProtList	*ProtList;

	virtual void* thread_protocolCmd(ProtocolCmd *cmd) = 0;
	virtual void thread_protocolCleanup(ProtocolCmd *cmd) = 0;
	void launchThread(struct ProtocolCmd *cmd);
};

inline Protocol::Protocol(TypeSpec type) : Type(type), ExtDict(0), NameDict(0)
{}

inline Protocol::~Protocol()
{}

inline int Protocol::type() const
{ return Type;}

inline void Protocol::setupMime(KMimeExtDict *extDict, KMimeExtList *nameDict, MimeMagic *magic, bool use)
{
	ExtDict = extDict;
	NameDict = nameDict;
	Magic = magic;
	UseMagic = use;
}

inline void Protocol::setupSubProtList(SubProtList *list)
{ ProtList = list;}

//----------------------------------------------------------------------------------------------
// This class is used for subprotocols, that is
// the protocol used for archive files.
//
// Formats supported : Tar, Zip, Rpm

class SubProtocol
{
public:
	SubProtocol(int _type, const char *str) : type(_type), extension(str,TRUE,TRUE)
	{
		switch (type) {
		   case Protocol::Tar: protocol = "tar"; break;
		   case Protocol::Zip: protocol = "zip"; break;
		   case Protocol::Rpm: protocol = "rpm"; break;
		}
	}
	bool matchFileName(const char *name) { return (extension.match(name) != -1);}

	int		type;
	QRegExp		extension;
	QString		protocol;
};

#endif
