/***************************************************************************
                          cdownloadqueue.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 CDOWNLOADQUEUE_H
#define CDOWNLOADQUEUE_H

#include <time.h>

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

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

class DCTransferObject;
class DCTransferFileObject;
class DCFileChunkObject;

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

	/** */
	CStringList * GetUserHubList( CString nick );
	/** */
	DCTransferObject * GetUserTransferObject( CString nick, CString hubname );
	/** */
	DCTransferFileObject * GetUserFileObject( CString nick, CString hubname, CString remotename );
	/** */
	bool DelUserFileObject( CString nick, CString hubname, CString remotefile );
	/** */
	bool RemoveChunk( CString localfile );

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

	/** */
	CString stHash;
	/** */
	CString sMD4Hash;
	/** */
	CList<CString> pMD4ChunkHashList;
	/** */
	CString sMD5Hash;
	/** file or buffer */
	eltMedium eMedium;
	/** remote file with path */
	CString sRemoteFile;
	/** local file with path */
	CString sLocalFile;
	/** local path without root path */
	CString sLocalPath;
	/** local filename */
	CString sLocalFileName;
	/** */
	eTransferFileState eState;
	/** file size */
	ulonglong lSize;
	/** */
	bool bMulti;

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

class DCChunkObject;
class DLL_EXPORT DCChunkObject : public CObject {
public:
	/** */
	DCChunkObject() {
		lStart  = 0;
		lEnd    = 0;
		bLocked = FALSE;
	};
	/** */
	DCChunkObject( DCChunkObject * ChunkObject ) {
		lStart  = ChunkObject->lStart;
		lEnd    = ChunkObject->lEnd;
		bLocked = ChunkObject->bLocked;
	};
	/** */
	virtual ~DCChunkObject() {};

	/** */
	ulonglong lStart;
	/** */
	ulonglong lEnd;
	/** */
	bool bLocked;
};

class DCFileChunkObject;

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

class DLL_EXPORT DCFileChunkObject : public CObject {
public:
	/** */
	DCFileChunkObject() {
		sLocalFile      = "";
		stHash          = "";
		sMD4Hash        = "";
		sMD5Hash        = "";
		bMulti          = FALSE;
		lSize           = 0;
		lSizeDone       = 0;
		iReferenceCount = 0;
	};
	/** */
	DCFileChunkObject( DCFileChunkObject * FileChunkObject ) {
		sLocalFile      = FileChunkObject->sLocalFile;
		stHash          = FileChunkObject->stHash;
		sMD4Hash        = FileChunkObject->sMD4Hash;
		sMD5Hash        = FileChunkObject->sMD5Hash;
		bMulti          = FileChunkObject->bMulti;
		lSize           = FileChunkObject->lSize;
		lSizeDone       = FileChunkObject->lSizeDone;
		iReferenceCount = FileChunkObject->iReferenceCount;

		DCChunkObject * ChunkObject = 0;
		while( (ChunkObject=FileChunkObject->pChunks.Next(ChunkObject)) != 0 )
		{
			pChunks.Add( new DCChunkObject(ChunkObject) );
		}
		CString *st = 0;

		while ( (st = FileChunkObject->pMD4ChunkHashList.Next(st)) != 0 )
		{
			pMD4ChunkHashList.Add(new CString(*st));
		}
	};
	/** */
	virtual ~DCFileChunkObject() {};

	/** */
	CString sLocalFile;
	/** */
	int iReferenceCount;
	/** */
	bool bMulti;
	/** */
	CString stHash;
	/** */
	CString sMD4Hash;
	/** */
	CList<CString> pMD4ChunkHashList;
	/** */
	CString sMD5Hash;
	/** file size */
	ulonglong lSize;
	/** file size */
	ulonglong lSizeDone;
	/** list of unfinished chunks */
	CList<DCChunkObject> pChunks;
};

class DLL_EXPORT DCTransferObject : public CObject {
public:
	/** */
	DCTransferObject() {
		tTimeout = 0;
		iConnections = 0;
	};

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

	/** */
	CString sNick;
	/** */
	CString sHubName;
	/** */
	CString sHubHost;
	/** */
	time_t tTimeout;
	/** */
	eTransferWaitState eState;
	/** */
	CString sUserFileList;
	/** */
	CStringList pTransferFileList;
	/** */
	int iConnections;
};

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

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

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

#endif
