/***************************************************************************
 *   Copyright (C) 2004 by Magnus Kulke                                    *
 *   mkulke@magnusmachine                                                  *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#ifndef FTPTHREAD_H
#define FTPTHREAD_H

#define KB_THREAD_TIMEOUT 1000

#include <list>
#include <tqthread.h>
#include <tqstringlist.h>
#include <tqvaluelist.h>
#include <tqvaluevector.h>
#include "eventhandler.h"
#include "kbfileinfo.h"

using namespace std;

class ftplib;
class TQObject;
class KbDirInfo;

typedef list<KbFileInfo*> filist;
typedef pair<off64_t, bool> xferpair;
typedef pair<filist, filist> dirpair;

/**
@author Magnus Kulke
*/
class FtpThread : public TQThread 
{
public:
   FtpThread();
   ~FtpThread();
	static void CallbackLog(char *log, void *arg, bool out);
	static int CallbackXfer(off64_t xfered, void *arg);
	void SetEventReceiver(TQObject* eventreceiver);
	void ClearQueue();
	bool Connect(TQString host);
	bool Login(TQString user, TQString pass);
	bool Quit();
	bool Pwd();
	bool Chdir(TQString path);
	bool Cdup();
	bool Dir(bool force = false);
	bool Scandir(KbDirInfo* dir);
	bool Rm(TQString name);
	bool Rmdir(TQString name);
	bool Authtls();
	bool Pasv(bool flag);
	bool EncryptData(bool flag, bool force = false);
	bool Transfer_Fxp(TQString src, TQString dst, FtpThread* dstftp, int srctls, int dsttls, off64_t resume = 0, int alt = 0);
	bool Mkdir(TQString path);
	bool Rename(TQString src, TQString dst);
	bool Raw(TQString cmd);
	bool Transfer_Get(TQString src, TQString dst, int tls, off64_t resume = 0);
	bool Transfer_Put(TQString src, TQString dst, int tls, off64_t resume = 0);
	bool Transfer_Changedir(TQString dir, int tls);
	bool Transfer_Mkdir(TQString dir);
	void Event(EventHandler::EventType type, void *data = NULL);
	ftplib* Ftp() { return mp_ftp; };
	void FxpReportResult(bool result);
	bool FxpDisableTls();
private:
	enum task
	{
		connect = 0,
		negotiateencryption,
		login,
		quit,
		pwd,
		chdir,
		cdup,
		dir,
		scandir,
		rm,
		rmdir,
		authtls,
		dataencryption,
		mkdir,
		rename,
		raw,
		transfer_changedir,
		transfer_get,
		transfer_mkdir,
		transfer_put,
		transfer_fxp
	};	
	void run();
	bool FormatFilelist(const char *filename,
		TQString current,
		filist *filetable,
		filist *dirtable
	);
	void InitInternals();
	void Connect_thread(); 
	void Login_thread(); 
	void Pwd_thread();
	void Quit_thread();
	void Chdir_thread();
	void Cdup_thread();
	void Dir_thread();
	void Scandir_thread();
	void Delete_thread();
	void Rm_thread();
	void Rmdir_thread();
	void Authtls_thread();
	void Dataencryption_thread();
	void Mkdir_thread();
	void Rename_thread();
	void Raw_thread();
	void Transfer_Changedir_thread();
	void Transfer_Get_thread();
	void Transfer_Put_thread();
	void Transfer_Fxp_thread();
	void Transfer_Mkdir_thread();
	bool Scandir_recurse(KbDirInfo *dir, TQString path);
	bool Delete_recurse(TQString name);
	bool ConnectionLost();
private:
	TQMutex* mp_mutex;
	TQObject* mp_eventreceiver;
	ftplib* mp_ftp;
	TQString m_pwd;
	bool m_dataencrypted;
	KbDirInfo* mp_scandir;
	filist m_dirlist, m_filelist;
	dirpair m_dircontent;
	TQValueList<task> m_tasklist;
	TQStringList m_stringlist;
	TQValueList<int> m_intlist;
	TQValueList<off64_t> m_ulonglist;
	TQValueList<FtpThread*> m_ftplist;
	TQValueVector<dirpair> m_cache_vector;
	TQStringList m_cache_list;
public:
	TQString m_linebuffer;
};

#endif
