/***************************************************************************
                          msnftpconnection.h -  description
                             -------------------
    begin                : Tue 06 30 2005
    copyright            : (C) 2003 by Mike K. Bennett
                           (C) 2005 by Diederik van der Boor
    email                : mkb137b@hotmail.com
                           vdboor --at-- codingdomain.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 MSNFTPCONNECTION_H
#define MSNFTPCONNECTION_H

#include "directconnectionbase.h"

#include <QString>

#include <KLocale>


class QIODevice;
class QFile;



/**
 * The class for receiving and sending files.
 * The MSNFTP protocol is used by old clients to transfer files.
 * It's initiated by the FileTransfer class.
 * Current clients use the direct-connection support of the P2PApplication invitations to transfer file data.
 * The old file transfer support is still available in most clients for backwards compatibility.
 *
 * @author Diederik van der Boor, Mike K. Bennett (original work).
 * @ingroup NetworkExtra
 */
class MsnFtpConnection : public DirectConnectionBase
{
  Q_OBJECT

  public:
    // The constructor
                           MsnFtpConnection( const QString authHandle, const QString authCookie );
    // The destructor
    virtual               ~MsnFtpConnection();

    // Close the connection
    void                   closeConnection();
    // Cancel the transfer
    void                   cancelTransfer(bool userCancelled = true);
    // Send a file
    bool                   sendFile(QFile *inputFile);
    // Retrieve a file
    bool                   retrieveFile(QFile *outputFile, const QString &ipAddress, const quint16 port);

  private slots:
    // This is called when a connection is established.
    void                   slotConnectionEstablished();
    // This is called when the connection could not be made.
    void                   slotConnectionFailed();
    // This is called when data is received from the socket.
    void                   slotSocketDataReceived();
    // The socket is ready for writing.  Write any outstanding commands.
    void                   slotWriteData();

  private: // Private methods
    // Emit a cancel message
    void                   emitCancelStatusMessage(bool contactCancelled);
    // Parse a command received from the contact
    void                   parseCommand(const QStringList &command);
    // Handle the received file data
    void                   parseReceivedFileData();
    // Write a cancel data block
    void                   writeCancelData();
    // Write more file data to the socket
    void                   writeFileData();
    // Write a message to the socket.
    void                   writeMessage(QString message);

  public:  // Public attributes
    // Constants for the statusMessage signal
    enum StatusType { STATUS_CHAT   = 0
                    , STATUS_DIALOG = 1
                    , STATUS_CHAT_FAILED   = 2
                    , STATUS_DIALOG_FAILED = 3
                    };

//    // Constants for the cancel/bye message

//    enum MsnFtpStatusCodes { FTP_STATUS_NO_SPACE           = 2147942405
//                           , FTP_STATUS_RECEIVER_CANCELLED = 2164261682
//                           , FTP_STATUS_SENDER_CANCELLED   = 2164261683
//                           , FTP_STATUS_CONNECTION_BLOCKED = 2164261694
//                           , FTP_STATUS_SUCCESS            = 16777987
//                           , FTP_STATUS_SUCCESS2           = 16777989
//                           };

  private: // Private attributes
    enum Mode { WAIT            =  0    // wait for slotDataReceived()
              , SEND_VER        =  1    // client: send VER command
              , SEND_USR        =  2    // client: send USR command
              , SEND_TFR        =  3    // client: send TFR command
              , RECEIVE_DATA    =  4    // client: receiving file data
              , SEND_BYE        =  5    // client: send BYE command
              , WAIT_VER        =  6    // server: wait for VER
              , SEND_VER2       =  7    // server: got VER, send VER confirmation
              , SEND_FIL        =  8    // server: got USR, send FIL command
              , WAIT_TFR        =  9    // server: authorized client, wait for TFR
              , SEND_DATA       = 10    // server: send data block
              , SEND_CANCEL     = 11    // server: send cancel block
              , SEND_CCL        = 12    // server/client: send a CCL message to abort
              };

    // The authorization cookie
    QString                authCookie_;
    // The authorization user handle
    QString                authHandle_;
    // The number of bytes received
    qint64                 fileBytesRemaining_;
    // The remaining bytes of the file
    qint64                 fileSize_;
    // The stream to read file data from
    QIODevice             *inputStream_;
    // The mode of the transfer.
    Mode                   mode_;
    // The stream to write received data to
    QIODevice             *outputStream_;
    // True when only partial file data was received
    qint64                 remainingBlockBytes_;
    // True if the user cancelled the session
    bool                   userCancelled_;

  signals:
    // Display a status message
    void                   statusMessage(QString message, int statusType);
    // Display a status message (as a raw localization string)
    void                   statusMessage( KLocalizedString message, int statusType );
    // Signal when the transfer was succesful
    void                   transferComplete();
    // Signal when the transfer failed
    void                   transferFailed();
    // Signal when the transfer made progress
    void                   transferProgess(unsigned long bytesReceived);
};

#endif
