/***************************************************************************
                          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 <qobject.h>
#include <qstring.h>

class KExtendedSocket;
class QIODevice;
class QFile;

/**
 * The class for receiving and sending files.
 * @author Diederik van der Boor, Mike K. Bennett (original work).
 */
class MsnFtpConnection : public QObject
{
  Q_OBJECT

  public:
    // The constructor
                           MsnFtpConnection();
    // The destructor
    virtual               ~MsnFtpConnection();

    // Cancel the transfer
    void                   cancelTransfer(bool userCancelled = true);
    // Close the connection
    void                   closeConnection();
    // Return true if a connection is active
    bool                   isConnected() const;
    // Get the server port that will be used
    int                    getLocalServerPort();
    // Set the authentication parameters
    void                   setAuthInfo(const QString authHandle, const QString authCookie);
    // Send a file
    bool                   sendFile(QFile *inputFile);
    // Retrieve a file
    bool                   retrieveFile(QFile *outputFile, const QString &ipAddress, const int port);

  private slots: // Protected slots
    // Handle the received file data
    void                   parseReceivedFileData();
    // Accept incoming connections on the socket.
    void                   slotAcceptConnection();
    // This is called when data is received from the socket.
    void                   slotDataReceived();
    // This is called when there's an error in the socket.
    void                   slotSocketError(int error);
    // The socket is ready for writing.  Write any outstanding commands.
    void                   slotWriteCommand();

  private: // Private methods
    // Emit a cancel message
    void                   emitCancelStatusMessage(bool contactCancelled);
    // Connect to a host
    bool                   openConnection(const QString &ipAddress, int port);
    // Wait for an incoming connection
    bool                   openServerPort();
    // Parse a command received from the contact
    void                   parseCommand(const QStringList &command);
    // 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
    unsigned long          fileBytesRemaining_;
    // The remaining bytes of the file
    unsigned long          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_;
    // The server socket which listens for incoming connections.
    KExtendedSocket       *server_;
    // The server port this class will use
    int                    serverPort_;
    // The socket over which data is sent or received.
    KExtendedSocket       *socket_;
    // True when only partial file data was received
    int                    remainingBlockBytes_;
    // True if the user cancelled the session
    bool                   userCancelled_;

  signals:
    // Display a status message
    void                   statusMessage(QString 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
