//this file is part of eMule
//Copyright (C)2002-2006 Merkur ( strEmail.Format("%s@%s", "devteam", "emule-project.net") / http://www.emule-project.net )
//
//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., 675 Mass Ave, Cambridge, MA 02139, USA.

#pragma once

class CUpDownClient;
enum EUploadState;

class UploadPacketCreaterThread;

class UploadDiskreaderThread :
    public CWinThread 
{
public:
    UploadDiskreaderThread(CUpDownClient* owner, uint8 byDataCompVer);
    ~UploadDiskreaderThread(void);

    void EndThread();

    // --- moved to here
    void    AddReqBlock(Requested_Block_Struct* reqblock);
    void    DrawUpStatusBar(CBarShader& s_UpStatusBar, UINT sessionPayloadUp, COLORREF crNextSending, COLORREF crSent, COLORREF crSending, COLORREF crBuffer);
	void	DrawUpStatusBarChunk(CBarShader& s_UpStatusBar, CDC* dc, RECT* rect, EMFileSize filesize, bool bFlat, UINT sessionPayloadUp, COLORREF crNextSending, COLORREF crSent, COLORREF crSending, COLORREF crBuffer, COLORREF crNeither);
	bool    HasBlocks() const								{ return !m_BlockRequests_queue.IsEmpty(); }
    UINT    GetNumberOfRequestedBlocksInQueue() const       { return m_BlockRequests_queue.GetCount(); }

    CString checkException(bool& anExceptionOccured);
public:
	void GetUploadingAndUploadedPart(uint8* abyUpPartUploadingAndUploaded, uint32 partcount) const;

private:
    static UINT RunProc(LPVOID pParam);
    UINT RunInternal();

    CEvent* threadEndedEvent;

    bool doRun;

    CEvent pauseEvent;

    CUpDownClient* m_owner;

    CCriticalSection blockLocker;
    CCriticalSection m_ExceptionLocker;

    uint8 m_byDataCompVer;

    // --- proxy methods
    CString			DbgGetClientInfo(bool bFormatIP = false) const;
    UINT			GetPayloadInBuffer() const;
    UINT			GetQueueSessionPayloadUp() const;
    INT				GetDatarate() const;
    bool            IsUploadingToPeerCache() const;
	LPCTSTR			GetUserName() const;
    void			SetUploadFileID(CKnownFile* newreqfile);

    // --- moved to here
	CTypedPtrList<CPtrList, Requested_Block_Struct*> m_BlockRequests_queue;
	CTypedPtrList<CPtrList, Requested_Block_Struct*> m_DoneBlocks_list;

	static CBarShader s_StatusBar;
	static CBarShader s_UpStatusBar;

    void CreateNextBlockPackage();
	void	CreateStandartPackets(byte* data, UINT togo, const uchar* FileID, uint64 StartOffset, uint64 EndOffset, uint64 currentBlock, bool bFromPF = true);
	void	CreatePackedPackets(byte* data, UINT togo, const uchar* FileID, uint64 StartOffset, uint64 EndOffset, bool bFromPF = true);

    UINT    m_minSendBufferSize;
    UINT    m_maxSendBufferSize;
    DWORD   m_dwLastDiskCountTick;
    uint64  m_currentBlockDone;
    bool    m_bQueueWasEmptyAfterLastRead;

    bool    m_bAnExceptionOccured;
    CString m_ExceptionString;

    UploadPacketCreaterThread* m_UploadPacketCreaterThread;
};
