/***************************************************************************
                          cdownloadqueue.h  -  description
                             -------------------
    begin                : Don Mai 16 2002
    copyright            : (C) 2002-2003 by Mathias Küster
    email                : mathen@users.berlios.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 CDOWNLOADQUEUE_H
#define CDOWNLOADQUEUE_H

/**
  *@author Mathias Küster
  *
  * There is both a queue of file sources (nicks and hubs for files) and
  * a queue of the files and their segments.
  *
  * This class does not do much, and quite often CDownloadManager will
  * iterate over the CStringLists in this class, they are public.
  */

#include <time.h>

#include <dclib/dcos.h>
#include <dclib/dcobject.h>
#include <dclib/core/cstring.h>
#include <dclib/core/cstringlist.h>
#include <dclib/ctransfer.h>
#include <dclib/core/cbytearray.h>

#include <list>

class DCTransferQueueObject;
class DCTransferFileObject;
class DCFileChunkObject;
class CMutex;

class CDownloadQueue {
public:
	/** */
	CDownloadQueue();
	/** */
	virtual ~CDownloadQueue();

	/** */
	CStringList<DCTransferQueueObject> * GetUserHubList( CString nick );
	/** */
	DCTransferQueueObject * GetUserTransferObject( CString nick, CString hubname, CString hubhost );
	/** */
	DCTransferFileObject * GetUserFileObject( CString nick, CString hubname, CString hubhost, CString remotename );
	/** */
	bool DelUserFileObject( CString nick, CString hubname, CString hubhost, CString remotefile );
	/** */
	bool RemoveChunk( CString localfile );
	/** */
	bool RenameNick( CString srcnick, CString dstnick, CString srchubname, CString dsthubname );

	/** */
	DCFileChunkObject * GetFileChunkObject( CString file );

	/** mutex for queue */
	CMutex * pQueueMutex;
	
	/** file queue
	 -> [CStringList] nick
	  -> [CStringList] hubname
	   -> [CTransferObject] (nick,hubname,hubhost,[CStringList(CFileObject)]
	    -> [CStringList] remotefile (for double transfers check this name and filelength)
	     -> [CFileObject] (all the file stuff)
	*/
	CStringList<CStringList<DCTransferQueueObject> > * pQueue;

	/** mutex for chunks list */
	CMutex * pChunksMutex;

	/** file chunk list
	 -> [CStringList] sLocalFile
          -> DCFileChunkObject
	*/
	CStringList<DCFileChunkObject> * pChunkList;
};


class DCTransferFileObject {
public:
	/** */
	DCTransferFileObject();
	/** Does a deep copy of a non-null list */
	DCTransferFileObject( const DCTransferFileObject & other );
	/** */
	~DCTransferFileObject();

	/** */
	DCTransferFileObject & operator = ( DCTransferFileObject * TransferFileObject ) { copy(TransferFileObject); return *this; };

	/** */
	CString m_stHash;
	/** */
	CString m_sHash;
	/** file or buffer or client version */
	eltMedium m_eMedium;
	/** remote file with path */
	CString m_sRemoteFile;
	/** local file with path */
	CString m_sLocalFile;
	/** local path without root path */
	CString m_sLocalPath;
	/** local filename */
	CString m_sLocalFileName;
	/** */
	eTransferFileState m_eState;
	/** file size */
	ulonglong m_nSize;
	/** */
	bool m_bMulti;
	/** */
	int m_nPriority;
	/**
	 * For setting the filelist browser to a file/folder
	 * when downloaded from search.
	 */
	CString m_sJumpTo;
	/**
	 * For downloading folders from search.
	 */
	std::list<CString> * m_pDirList;

private:
	/** */
	void copy( DCTransferFileObject * TransferFileObject );
};

class DCChunkObject;
class DCChunkObject {
public:
	/** */
	DCChunkObject() {
		m_nStart      = 0;
		m_nEnd        = 0;
		m_eChunkState = ecsFREE;
	};
	/** */
	DCChunkObject( DCChunkObject * ChunkObject ) {
		m_nStart      = ChunkObject->m_nStart;
		m_nEnd        = ChunkObject->m_nEnd;
		m_eChunkState = ChunkObject->m_eChunkState;
	};
	/** */
	~DCChunkObject() {};

	/** */
	ulonglong m_nStart;
	/** */
	ulonglong m_nEnd;
	/** */ 
	eChunkState m_eChunkState;
};

class DCFileChunkObject;

class DCFileChunkObject {
public:
	/** */
	DCFileChunkObject();
	/** The normal C++ copy constructor */
	DCFileChunkObject( const DCFileChunkObject & other );
	/** What dclib is using */
	DCFileChunkObject( const DCFileChunkObject * other );
	/** */
	~DCFileChunkObject();

	/** */
	CString m_sLocalFile;
	/** */
	int m_nReferenceCount;
	/** */
	bool m_bMulti;
	/** */
	CString m_stHash;
	/** */
	CString m_sHash;
	/** file size */
	ulonglong m_nSize;
	/** file size done */
	ulonglong m_nSizeDone;

	/** list of unfinished chunks */
	CList<DCChunkObject> m_Chunks;
};

class DCTransferQueueObject {
public:
	/** */
	DCTransferQueueObject() {
		tTimeout = 0;
		iConnections = 0;
		bReconnect = false;
	};

	/** */
	~DCTransferQueueObject() {};

	/** */
	CString sNick;
	/** */
	CString sHubName;
	/** */
	CString sHubHost;
	/** */
	time_t tTimeout;
	/** */
	eTransferWaitState eState;
	/** */
	CString sUserFileList;
	/** */
	CStringList<DCTransferFileObject> pTransferFileList;
	/** */
	CList<DCHubObject> pHubList;
	/** */
	int iConnections;
	/** */
	bool bReconnect;
};

class DCTransferWait {
public:
	/** */
	DCTransferWait() {
		tTimeout = 0;
		m_nCount = 0;
	};

	/** */
	~DCTransferWait() {};

	/**
	 * Returns true if the nick and userhost of this object match
	 * the parameters.
	 * 
	 * If one of this object's nick and userhost is empty, then
	 * true is returned if the non-empty one matches the parameter
	 * and the empty one is set to the other parameter.
	 */
	bool Match( const CString & nick, const CString & userhost );

	/** */
	CString sNick;
	/** */
	CString sHubName;
	/** */
	CString sHubHost;
	/** */
	CString sUserHost;
	/** */
	ulonglong m_nCount;
	/** */
	time_t tTimeout;
};

#endif
