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

#include <time.h>

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

class DCTransferQueueObject;
class DCTransferFileObject;
class DCFileChunkObject;

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

	/** */
	CStringList * 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 );

	/** 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)
	*/
	CThreadStringList * pQueue;

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


class DLL_EXPORT DCTransferFileObject : public CObject {
public:
	/** */
	DCTransferFileObject();
	/** */
	virtual ~DCTransferFileObject();

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

	/** file id */
	ulonglong m_nID;
	/** */
	ulonglong m_nTime;
	/** */
	CString m_sIndex;
	/** */
	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;

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

class DCChunkObject;
class DLL_EXPORT DCChunkObject : public CObject {
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;
		m_sMD5        = ChunkObject->m_sMD5;
	};
	/** */
	virtual ~DCChunkObject() {};

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

class DCFileChunkObject;

#ifdef WIN32
template class DLL_EXPORT CList<DCChunkObject>;
template class DLL_EXPORT CList<DCHubObject>;
#endif

class DLL_EXPORT DCFileChunkObject : public CObject {
public:
	/** */
	DCFileChunkObject() {
		m_sLocalFile      = "";
		m_stHash          = "";
		m_sHash           = "";
		m_bMulti          = FALSE;
		m_nSize           = 0;
		m_nSizeDone       = 0;
		m_nReferenceCount = 0;
	};
	/** */
	DCFileChunkObject( DCFileChunkObject * FileChunkObject ) {
		m_sLocalFile      = FileChunkObject->m_sLocalFile;
		m_stHash          = FileChunkObject->m_stHash;
		m_sHash           = FileChunkObject->m_sHash;
		m_bMulti          = FileChunkObject->m_bMulti;
		m_nSize           = FileChunkObject->m_nSize;
		m_nSizeDone       = FileChunkObject->m_nSizeDone;
		m_nReferenceCount = FileChunkObject->m_nReferenceCount;

		DCChunkObject * ChunkObject = 0;
		while( (ChunkObject=FileChunkObject->m_Chunks.Next(ChunkObject)) != 0 )
		{
			m_Chunks.Add( new DCChunkObject(ChunkObject) );
		}
	};
	/** */
	virtual ~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 DLL_EXPORT DCTransferQueueObject : public CObject {
public:
	/** */
	DCTransferQueueObject() {
		tTimeout = 0;
		iConnections = 0;
		bReconnect = FALSE;
	};

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

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

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

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

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

#endif
