#ifndef _FTPPROT_H_
#define _FTPPROT_H_

#include <config.h>

#include "protocol.h"

#define	FTP_OK		0	// 2xx responses
#define	FTP_ERROR	-1	// 5xx responses
#define	FTP_BROKEN	-2	// sock = -1
#define FTP_CLOSED	-3	// 4xx responses
#define	FTP_COMMERROR	-3	// 4xx responses
#define	FTP_NOTCONN	-4
#define	FTP_CONNERROR	-5	// error while trying to connect
#define	FTP_SOCKERROR	-6	// general socket error

class FtpProtocol : public Protocol
{
public:
	FtpProtocol(const char *host, const char *path = 0, const char *login = 0, const char *passwd = 0, const char *port = 0);
	virtual ~FtpProtocol();

	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);
	void shutDown();

protected:
	bool fillBuffer();
	QString readLine();
	void flushBuffer();
	int readAnswer();
	void sendCommand(const char *cmd, const char *args = 0);
	void connectionClosed();
	int setErrorMsg(int result);
	int setupDataConnection();
	int acceptDataConnection(int sData, bool writeFlag = FALSE);
	void readDataBuffer();
	void download();
	void upload();

	void* thread_protocolCmd(ProtocolCmd *cmd);
	void thread_protocolCleanup(ProtocolCmd *cmd);

	int ftpConnect();
	int ftpLogin();
	int ftpPwd();
	int ftpCd(const char *path);
	int ftpList();
	int ftpMkDir(const char *dirName);
	int ftpGet(const char *src, const char *dest);
	int ftpGetDir(const char *src, const char *dest);
	int ftpPut(const char *src, const char *dest);
	int ftpPutDir(const char *src, const char *dest);
	int ftpRename(const char *src, const char *dest);
	int ftpRm(const char *filename);
	int ftpRmDir(const char *dirname);

	bool updateEntries();
	bool updateFilteredEntries(bool hidden, bool dirsOnly, bool showArchive = FALSE);

protected:
	QString		Host;
	QString		Path;
	QString		Login;
	QString		Passwd;
	int		Port;

	int		sock;
	int		dataSock;
	int		file;
	QString		CurrentPath;
	FileInfoList	*entries, *rawEntries;
	QStrList	*namedEntries;
	bool		updateFlag, filterFlag;
	QString		Buffer;
	QString		AnswerBuffer;
	QString		DataBuffer;
	int		posBuffer;
	int		totalBytes, downBytes;
	ProgressDlg	*dialog;
	bool		UnixType;
	bool		Aborted;

private:
	bool thread_Init();
	bool thread_setPath(const char *pathname);
	bool thread_mkdir(const char *dirName);
	bool thread_updateEntries();
	bool thread_copyToProtocol(const char *filename, const char *targetDir = 0, bool move = FALSE, ProgressDlg *dlg = 0);
	bool thread_copyFromProtocol(const char *filename, const char *targetDir, bool move = FALSE, ProgressDlg *dlg = 0);
	bool thread_rename(const char *src, const char *dest);
	bool thread_remove(const char *filename);
	bool thread_rmdir(const char *dirname, ProgressDlg *dlg = 0);
};

inline bool FtpProtocol::isRoot()
{ return (CurrentPath == "/");}

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

inline bool FtpProtocol::isLocal()
{ return FALSE;}

inline uint FtpProtocol::freeSize(const char *)
{ return (uint)0;}

inline bool FtpProtocol::hasChilds(const char *dirname)
{ return TRUE;}

#endif
