/***************************************************************************
 *   Copyright (C) 2007 by Anistratov Oleg                                 *
 *   ower@users.sourceforge.net                                            *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation;                         *
 *                                                                         *
 *   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.                          *
 *                                                                         *
 ***************************************************************************/

#ifndef LARGEDATAGRAMOUT_H
#define LARGEDATAGRAMOUT_H

#include <QObject>
#include <QHostAddress>
#include <QUdpSocket>
#include <QTimer>
#include <QFile>
#include <QTcpSocket>

/**
	@author Anistratov Oleg <ower@users.sourceforge.net>
*/
class LargeDatagramOut : public QObject
{
  Q_OBJECT
  private:
    quint32      m_id;
    QString      m_filename;
    QFile        m_file;
    bool         m_confirmed;
    bool         m_inited;
    bool         m_rest;
    quint16      m_headerSize;
    quint32      m_dataSize;
    quint64      m_fileSize;
    quint32      m_sizePerFragment;
    quint32      m_totalFragments;
    quint32      m_fragmentsRemain;
    char*        m_header;
    char*        m_data;
    /// shows which fragments was sent
    char*        m_fragments;
    QTimer*      m_selfDestroyTimer;
    quint32      m_selfDestroyInterval;

    /// UserID in server mode and User's IP Address in serverless mode
    quint64      m_destUid;

  public:
    LargeDatagramOut(QObject *parent = 0);
    ~LargeDatagramOut();

//     const QHostAddress & addr() const {return m_destAddr;}
    bool    complete         () const {return !m_fragmentsRemain;}
    quint32 id               () const {return m_id;}

    void init(char* hdr, quint16 hdr_sz, char* data, quint32 data_sz, quint64, quint32 id);
    void init(char* hdr, quint16 hdr_sz, const QString & filename   , quint64, quint32 id);

    void prepareInitHeader();
    void fragmentsRequest (const char* , quint16);
    void sendNextFragment (QAbstractSocket* socket, quint16 port, char* buf);
    void acceptSending    (){m_confirmed = true;}
    quint32 writeFragment (char* buf, quint32 num);

    void setDestUid( const uint& theValue ){m_destUid = theValue;}
    uint destUid() const {return m_destUid;}

  public slots:
    void selfDestroy();
    void slot_confirmed(unsigned short ID);

  signals:
    void wantDie         (LargeDatagramOut*);
    void sendingCancelled(quint16);

};

#endif
