/*
  This class represents a DCC transfer.
*/

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

/*
  Copyright (C) 2002-2004 Dario Abatianni <eisfuchs@tigress.com>
  Copyright (C) 2004-2007 Shintaro Matsuoka <shin@shoegazed.org>
  Copyright (C) 2004,2005 John Tapsell <john@geola.co.uk>
*/

#ifndef DCCTRANSFER_H
#define DCCTRANSFER_H

#include <tqdatetime.h>
#include <tqobject.h>
#include <tqtimer.h>

#include <kurl.h>
#include <tdeio/global.h>

typedef double transferspeed_t;

class DccTransfer : public TQObject
{
    TQ_OBJECT
  

    public:
        enum DccType
        {
            Receive,
            Send
        };

        enum DccStatus
        {
            Configuring = 0,                      // Not queud yet (this means that user can't see the item at this time)
            Queued,                               // Newly added DCC, waiting user's response
            Preparing,                            // Opening TDEIO to write received data
            WaitingRemote,                        // Waiting for remote host's response
            Connecting,                           // RECV: trying to connect to the server
            Transferring,
            Done,
            Failed,
            Aborted
        };

        enum UnavailableStatus
        {
            Calculating = -1,
            NotInTransfer = -2,
            InfiniteValue = -3
        };

        DccTransfer( DccType dccType, TQObject* parent );
        virtual ~DccTransfer();

        // info of DccTransfer can be copied with this constructor.
        DccTransfer( const DccTransfer& obj );

        DccType            getType()                  const;
        DccStatus          getStatus()                const;
        const TQString&     getStatusDetail()          const;
        TQDateTime          getTimeOffer()             const;
        int                getConnectionId()         const;
        TQString            getOwnIp()                 const;
        TQString            getOwnPort()               const;
        TQString            getPartnerNick()           const;
        TQString            getPartnerIp()             const;
        TQString            getPartnerPort()           const;
        TQString            getFileName()              const;
        TDEIO::filesize_t    getFileSize()              const;
        TDEIO::fileoffset_t  getTransferringPosition()  const;
        TDEIO::fileoffset_t  getTransferStartPosition() const;
        KURL               getFileURL()               const;
        bool               isResumed()                const;
        bool               isReverse()                const;
        TQString            getReverseToken()          const;
        transferspeed_t    getAverageSpeed()          const;
        transferspeed_t    getCurrentSpeed()          const;
        int                getTimeLeft()              const;
        int                getProgress()              const;
        TQDateTime          getTimeTransferStarted()   const;
        TQDateTime          getTimeTransferFinished()  const;

        // common settings for DccTransferRecv / DccTransferSend

        // REQUIRED
        void setConnectionId( int connectionId );
        // REQUIRED
        void setPartnerNick( const TQString& nick );

    signals:
        void transferStarted( DccTransfer* item );
        void done( DccTransfer* item );
        void statusChanged( DccTransfer* item, int newStatus, int oldStatus );

    public slots:
        virtual bool queue();
        virtual void start() {};
        virtual void abort() {};

    protected:
        void setStatus( DccStatus status, const TQString& statusDetail = TQString() );
        void startTransferLogger();
        void finishTransferLogger();

        static TQString sanitizeFileName( const TQString& fileName );
        static TQString getNumericalIpText( const TQString& ipString );
        static unsigned long intel( unsigned long value );

    protected slots:
        void logTransfer();

    protected:
        // transfer information
        DccType m_type;
        DccStatus m_status;
        TQString m_statusDetail;
        bool m_resumed;
        bool m_reverse;
        TQString m_reverseToken;
        TDEIO::fileoffset_t m_transferringPosition;
        TDEIO::fileoffset_t m_transferStartPosition;

        /*
        TQValueList<TQDateTime> m_transferTimeLog;  // write per packet to calc CPS
        TQValueList<TDEIO::fileoffset_t> m_transferPositionLog;  // write per packet to calc CPS
        */

        // we'll communicate with the partner via this server
        int m_connectionId;
        TQString m_partnerNick;
        TQString m_partnerIp;                      // null when unknown
        TQString m_partnerPort;
        TQString m_ownIp;
        TQString m_ownPort;

        unsigned long m_bufferSize;
        char* m_buffer;

        /**
         * The filename.
         * For receiving, it holds the filename as the sender said.
         * So be careful, it can contain "../" and so on.
         */
        TQString m_fileName;

        /** The file size of the complete file sending/recieving. */
        TDEIO::filesize_t  m_fileSize;

        /**
         * If we are sending a file, this is the url of the file we are sending.
         * If we are recieving a file, this is the url of the file we are saving
         * to in the end (Temporararily it will be filename+".part" ).
         */
        KURL m_fileURL;

    private:
        DccTransfer& operator = ( const DccTransfer& obj );

        void updateTransferMeters();

    private:
        TQDateTime m_timeOffer;
        TQDateTime m_timeTransferStarted;
        //TQDateTime m_timeLastActive;
        TQDateTime m_timeTransferFinished;

        TQTimer m_loggerTimer;
        TQTime m_loggerBaseTime;  // for calculating CPS
        TQValueList<int> m_transferLogTime;
        TQValueList<TDEIO::fileoffset_t> m_transferLogPosition;

        transferspeed_t m_averageSpeed;
        transferspeed_t m_currentSpeed;
        int m_timeLeft;
};

#endif  // DCCTRANSFER_H
