#ifndef _ARCHPROT_H_
#define _ARCHPROT_H_

#include <config.h>
#include <qdict.h>
#include <stdio.h>
#include <wait.h>
#include "protocol.h"

struct TreeItem
{
	TreeItem(const char *name) : Name(name) { List = new FileInfoList; List->setAutoDelete(FALSE);}
	~TreeItem() { delete List;}
	QString		Name;
	FileInfoList	*List;
};

class ArchiveProtocol : public Protocol
{
public:
	ArchiveProtocol(const char *localFile, const char *file);
	virtual ~ArchiveProtocol();

	const FileInfoList* entryInfoList(bool hidden, bool dirsOnly, bool showArchive = FALSE);
	const QStrList* entryList(bool hidden, bool dirsOnly, bool showArchive = FALSE);
  	bool mkdir(const char *pathname);
	QString absPath();
	bool setPath(const char *pathname);
	QString dirName();
	bool remove(const char *filename);
	bool rmdir(const char *dirname, ProgressDlg *dlg = 0);
	bool isRoot();
	bool rename(const char *src, const char *dest);
	bool exists(const char *filename);
	bool chmod(const char *filename, int perm);

	bool copyToProtocol(const char *filename, const char *targetDir = 0, bool move = FALSE, ProgressDlg *dlg = 0);
	bool copyFromProtocol(const char *filename, const char *targetDir, bool move = FALSE, ProgressDlg *dlg = 0);
	bool init();
	bool finish();
	bool cleanup();
	bool matchURL(KURL url);
	const char* currentURL();
	bool isLocal();
	uint freeSize(const char *dirname);
	bool hasChilds(const char *dirname);
	FileInfo* getInfo(KURL& url);

protected:
	QString		LocalFile;
	QString		File;
	QString		CurrentPath;
	bool		ReadOnly;
	FileInfoList	*rawEntries, *entries;
	QStrList	*namedEntries;
	bool		updateFlag, filterFlag;
	QDict<TreeItem>	*DirDict;
	int		out[2], err[2];
	int		ProcID;
	QString		Buffer;
	FILE		*fout;
	int		Code;

	bool executeCommand(const char *prog, QStrList& args);
	bool finishCommand();
	bool setupCommunication();
	bool CommDoneChild();
	bool CommDoneParent();
	bool CommDone();
	void processEntry(FileInfo *fi);

	void* thread_protocolCmd(ProtocolCmd *cmd);
	void thread_protocolCleanup(ProtocolCmd *cmd);
	bool updateEntries();
	bool updateFilteredEntries(bool hidden, bool dirsOnly, bool showArchive);
	bool setErrorMsg(int);

private:
	virtual bool thread_updateEntries() = 0;
	virtual void createParentStr(QString&,FileInfo*) = 0;
	virtual bool extract(const char *src, const char *dest, ProgressDlg *dlg = 0) = 0;
	bool thread_copyFromProtocol(const char *filename, const char *targetDir, bool move = FALSE, ProgressDlg *dlg = 0);
};

inline QString ArchiveProtocol::absPath()
{ return CurrentPath;}

#endif
