//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 PacketParameters
{
    public:
        ~PacketParameters();

        virtual void CreateAndSend() = 0;

    protected:
        virtual void Init(CUpDownClient* owner, byte* par_data, UINT par_togo, const uchar* par_FileID, uint64 par_StartOffset, uint64 par_EndOffset, uint64 par_currentBlockDone, bool par_bFromPF, UINT par_packetSplitSize);

        void SendPacket(Packet* packet, uint32 actualPayloadSize = 0);

        CUpDownClient* m_owner;

        byte* data;
        UINT togo;
        uchar FileID[16];
        uint64 StartOffset;
        uint64 EndOffset;
        uint64 currentBlockDone;
        bool bFromPF;
        UINT packetSplitSize;
};

class StandardPacketParameters :
    public PacketParameters
{
    public:
        StandardPacketParameters(CUpDownClient* owner, byte* data, UINT togo, const uchar* FileID, uint64 StartOffset, uint64 EndOffset, uint64 currentBlockDone, bool bFromPF, UINT packetSplitSize);

        virtual void CreateAndSend();

    protected:
        StandardPacketParameters();
};

class PackedPacketParameters :
    public StandardPacketParameters
{
    public:
        PackedPacketParameters(CUpDownClient* owner, byte* data, UINT togo, const uchar* FileID, uint64 StartOffset, uint64 EndOffset, bool bFromPF, UINT packetSplitSize);

        virtual void CreateAndSend();
};

//-

class UploadPacketCreaterThread :
    public CWinThread 
{
public:
    UploadPacketCreaterThread(CUpDownClient* owner);
    ~UploadPacketCreaterThread(void);

    void EndThread();

    void	CreateStandartPackets(byte* data, UINT togo, const uchar* FileID, uint64 StartOffset, uint64 EndOffset, uint64 currentBlockDone, bool bFromPF, UINT packetSplitSize);
	void	CreatePackedPackets(byte* data, UINT togo, const uchar* FileID, uint64 StartOffset, uint64 EndOffset, bool bFromPF, UINT packetSplitSize);

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

    CEvent* threadEndedEvent;

    bool doRun;

    CEvent pauseEvent;

    PacketParameters* GetNextPacketParam();

    CUpDownClient* m_owner;

    CCriticalSection paramQueueLocker;

	CTypedPtrList<CPtrList, PacketParameters*> m_PacketCreation_queue;
};
