/***************************************************************************
                          msnsockettcp.h  -  description
                             -------------------
    begin                : Thu Jan 23 2003
    copyright            : (C) 2003 by Mike K. Bennett
    email                : mkb137b@hotmail.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 MSNSOCKETTCP_H
#define MSNSOCKETTCP_H

#include "msnsocketbase.h"

#include <QAbstractSocket>
#include <QStringList>
#include <QTimer>

// Forward declarations
class QTcpSocket;



/**
 * @brief Basic I/O functionality for the MSN server protocol over a TCP connection.
 *
 * The class provides the following facilities:
 * - asynchronous connection to the MSN servers.
 * - sending/receiving raw protocol data.
 * - transparent reconstruction of fragmented received payloads.
 *
 * Data from the server is handled by the slotSocketDataReceived() slot.
 * This method buffers and processes the data, until a complete command or payload message is received.
 * Then a signal with the full message contents is forwarded to MsnConnection, which manages it.
 * This class only handles the parsing of socket input, the handling the commands
 * happens in the MsnConnection class.
 *
 * @author Mike K. Bennett
 * @author Valerio Pilo <valerio@kmess.org>
 * @ingroup NetworkCore
 */
class MsnSocketTcp : public MsnSocketBase
{
  Q_OBJECT


  public: // Public methods
    // The constructor
                         MsnSocketTcp( ServerType serverType );
    // The destructor
    virtual             ~MsnSocketTcp();
    // Connect to the given server via the socket
    void                 connectToServer( const QString& server = QString(), const quint16 port = 0 );
    // Disconnect from the server, if connected
    void                 disconnectFromServer( bool isTransfer = false );
    // Get the IP address of this machine.
    QString              getLocalIp() const;
    // Whether or not the class is connected
    bool                 isConnected() const;
    // Set whether we're sending pings or not (also resets ping timer)
    void                 setSendPings( bool sendPings );
    // Write data to the socket without conversions
    qint64               writeBinaryData(const QByteArray& data);
    // Write data to the socket
    qint64               writeData(const QString& data);


  private slots: // Private slots
    // Called when the connection has been successfully opened
    void                 slotConnected();
    // Called when the connection has been closed
    void                 slotDisconnected();
    // Called when the connection did not complete within a time limit
    void                 slotLoginFailed();
    // Called when the server's IP address has been found
    void                 slotHostFound();
     // Send a "ping" to the server
    void                 slotSendPing();
    // Read data from the socket
    void                 slotSocketDataReceived();
    // Detect socket errors
    void                 slotSocketError( QAbstractSocket::SocketError errorCode );


  private: // Private attributes
    // A timer to watch over the connection process
    QTimer               connectionTimer_;
    // Number of errant pings since last good one
    int                  missedPings_;
    // The next payload command
    QStringList          nextPayloadCommand_;
    // The size of the next expected payload message
    int                  nextPayloadSize_;
    // Whether the last ping send got a reply
    bool                 pingReceived_;
    // A timer to regularly "ping" the server
    QTimer               pingTimer_;
    // Are we sending pings?
    bool                 sendPings_;
    // The socket
    QTcpSocket          *socket_;
    // List of accepted commands which carry a data payload
    QStringList          acceptedPayloadCommands_;

};



#endif
