/***************************************************************************
                          cdownloadmanager.h  -  description
                             -------------------
    begin                : Don Mai 16 2002
    copyright            : (C) 2002 by Mathias Küster
    email                : mathen@ketelhot.de
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef CDOWNLOADMANAGER_H
#define CDOWNLOADMANAGER_H

#include <dclib/dcos.h>
#include <dclib/clist.h>
#include <dclib/ctransfer.h>
#include <dclib/cthread.h>
#include <dclib/clisten.h>
#include <dclib/cstringlist.h>
#include <dclib/cdownloadqueue.h>

/**
  *@author Mathias Küster
  */

class  DLL_EXPORT CUserFileInfo : public CObject {
public:
	/** */
	CUserFileInfo() {};
	/** */
	virtual ~CUserFileInfo() {};
	/** */
	eTransferWaitState eWaitState;
	/** */
	eTransferFileState eFileState;
	/** */
	CString sUserFileList;
	/** */
	CString sLocalFile;
	/** */
	bool bMulti;
};

class  DLL_EXPORT CExtraUserSlot : public CObject {
public:
	/** */
	CExtraUserSlot() {};
	/** */
	virtual ~CExtraUserSlot() {};
	/** */
	CString sNick;
	/** */
	CString sHubName;
	/** */
	int iSlots;
	/** */
	bool bPermanent;
};

class  DLL_EXPORT CDownloadManagerInfo : public CDCMessage {
public:
	/** */
	CDownloadManagerInfo();
	/** */
	virtual ~CDownloadManagerInfo() {};
	/** */
	ulonglong rate_ul,rate_dl;
	/** */
	int slot_max,slot_use;
};

#ifdef WIN32
template class DLL_EXPORT CList<CExtraUserSlot>;
#endif

class  DLL_EXPORT CDownloadManager : public CThread {
public: 
	/** */
	CDownloadManager();
	/** */
	virtual ~CDownloadManager();

	/** */
	int LoadQueue();
	/** */
	int SaveQueue();
	/** disconnect all transfers for a clean shutdown */
	void Shutdown();
	/** */
	int GetShutdownState() const;
	/** */
	int GetUsedSlots() const;

	/** */
	int CheckFile( CString nick, CString hubname, CString hubhost,
				CString remotename, CString localname,
				CString localpath, CString localrootpath,
				eltMedium medium, ulonglong size );
	/** */
	void AddWaitTransfer( CString nick, CString hubname, CString hubhost,
				CString remotename, CString localname,
				CString localpath, CString localrootpath,
				eltMedium medium, ulonglong size,
				ulonglong startposition,
				bool multi = FALSE );
	/** */
	bool GetUserFileInfo( CString nick, CString hubname, CString hubhost, CString file, CUserFileInfo * UserFileInfo );
	/** */
	DCFileChunkObject * GetFileChunk( CString file );

	/** */
	void TryConnect( CString nick, CString hubname );
	/** */
	bool UpdateServer( CString nick, CString hubname );
	/** */
	void AddTransfer( CString host, int port, CString hubname, CString hubhost );
	/** */
	bool AddTransfer( CString nick, CString userhost, CString hubname, CString hubhost );
	/** */
	bool RemoveQueue( CString nick, CString hubname, CString remotefile );
	/** */
	bool RemoveQueue( CString localfile );
	/** */
	bool TransferClose( CString transferid );
	/** */
	bool TransferCancel( CString nick, CString host, CString file );
	/** */
	eDirection TransferDirection( CString transferid );
	/** */
	bool TransferSetRate( CString transferid, ulonglong rate );
	/** */
	ulonglong TransferGetRate( CString transferid );

	/** */
	bool InitListen( CString & s );
	/** */
	void StopListen();
	/** */
	void AddUserSlot( CString nick, CString hubname, int slot, bool permanent = FALSE );

	/** thread callbackfunction */
	virtual void Thread( CObject * Object );
	/** callback function */
	virtual int DC_DownloadManagerCallBack( CObject * ) { return -1; };

protected:
	/** */
	int DM_TransferCallBack( CObject * Sender, CObject * Object );
	/** listen callback function */
	int DM_ListenCallBack( CObject * Sender, CObject * Object );

private:
	/** */
	void SendFileInfo( DCTransferObject * TransferObject, DCTransferFileObject * TransferFileItem = 0, bool bRemoveFile = FALSE );
	/** */
	void SendTransferInfo( CTransfer * Transfer, bool remove = FALSE );
	/** */
	void SendSlotInfo( CExtraUserSlot * Object );
	/** */
	void SendLogInfo( CString message, CTransfer * Transfer = 0 );
	/** */
	void SendDownloadManagerInfo( CDownloadManagerInfo * dminfo );
	/** */
	bool CheckUserSlot( CString nick, CString hubname );
	/** */
	bool GetNextChunk( CString file, ulonglong * lstart, ulonglong * lend );
	/** */
	int UpdateChunk( CString file, ulonglong lstart, ulonglong lend, ulonglong lcurrent );
	/** */
	bool GetNewChunkEnd( CString file, ulonglong lstart, ulonglong lend, ulonglong lcurrent, ulonglong * lnstart, ulonglong *lnend );

	/** */
	void UpdateQueueList( time_t ttimeout );
	/** */
	void UpdateTransferList( time_t ttimeout );

	/** */
	bool CheckWaitTransfer( CTransfer * Transfer );
	/** */
	bool ChangeDirection( CTransfer * Transfer );
	/** */
	bool SetNextFile( CTransfer * Transfer );
	/** */
	bool SetDirection( CTransfer * Transfer );
	/** */
	bool SetFile( CTransfer * Transfer );
	/** */
	void UpdateFileState( CTransfer * Transfer, eTransferFileState eState );
	/** */
	void FileListDone( CTransfer * Transfer );
	/** */
	bool CheckHash( CTransfer * Transfer );

	/** */
	bool RemoveQueueFile( CString nick, CString hubname, CString remotefile );
	/** */
	bool RemoveQueueFile( CString localfile );

	/** */
	CString GetNewTransferID();

	CDownloadManagerInfo DownloadManagerInfo;

	/** */
	int iShutdownState;
	/** */
	CThread TransferCallBackThread;
	/** */
	CThread LogThread;
	/** */
	ulonglong lTransferID;
	/** */
	long lUsedSlots;

	/** */
	time_t tDownloadQueueTimeout;
	/** */
	time_t tUpdateTransferTimeout;

	/** */
	CDownloadQueue pDownloadQueue;
	/** */
	CThreadStringList *pTransferList;
	/** */
	CThreadList<DCTransferWait> *pTransferWaitList;
	/** */
	CListen Listen;
	/** */
	CList<CExtraUserSlot> *pExtraUserSlotList;
};

/** */
inline int CDownloadManager::GetShutdownState() const
{ return iShutdownState; }
/** */
inline int CDownloadManager::GetUsedSlots() const
{ return lUsedSlots; }


#endif
