/***************************************************************************
 *   Copyright (C) 2007 by Anistratov Oleg                                 *
 *   ower86@gmail.com                                                      *
 *                                                                         *
 *   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 QCHATSOCKET_H
#define QCHATSOCKET_H

#include <QObject>
#include <QTcpSocket>

#include "abstractchatcore.h"

/**
	@author Anistratov Oleg <ower86@gmail.com>
*/
class QChatSocket : public QObject, public AbstractChatCore
{
  Q_OBJECT
  public:
    enum QChatSocketState{Unconnected, Connected, LoggedIn};

  private:
    char* m_buffer;
    char* m_dtgrm;
    int   m_bufferSize;
    QChatSocketState m_state;

    int   m_fullDtgrmSize;
    int   m_currentDtgrmSize;

    bool  m_newDtgrmReady;

    QString m_nickname;

    QTcpSocket* m_socket;

  private:
    char* appendData(const char*, int&);

  public:
    QChatSocket(QObject* parent = 0, QTcpSocket* = 0);
    ~QChatSocket();

    void login(const QString&, const QString& = "");

//     QChatSocketState state() const {return m_state;}
    int readDtgrm(char*, int);

    const QString& nickname() const {return m_nickname;}

    //******************************
    QTcpSocket* socket() const {return m_socket;}

    qint64 write(const char* data, qint64 maxSize)
    {return m_socket->write(data, maxSize);}

    QHostAddress peerAddress() const
    {return m_socket->peerAddress();}

    quint16 peerPort() const
    {return m_socket->peerPort();}

    void disconnectFromHost()
    {m_socket->disconnectFromHost();}

    void connectToHost(const QString & hostName, quint16 port, QIODevice::OpenMode openMode = QIODevice::ReadWrite)
    {m_socket->connectToHost(hostName, port, openMode);}

    void connectToHost(const QHostAddress & address, quint16 port, QIODevice::OpenMode openMode = QIODevice::ReadWrite)
    {m_socket->connectToHost(address, port, openMode);}

    bool waitForConnected (int msecs = 30000)
    {return m_socket->waitForConnected(msecs);}

    bool flush()
    {return m_socket->flush();}

    QAbstractSocket::SocketState state () const {return m_socket->state();}
    //******************************
    void sendData();

  public slots:
    void processNewData();

  signals:
    void badLogin(const QString&);
    void newDtgrm();

    /**
     *
     * @param  err_id id of error
     * 0: no errors
     * 2: cannot login to server
     * @param  descr optional text description of error
     */
    void loginFinished(int err_id, const QString& descr);
    void disconnected();
};

#endif
