/*
 * QtTapioca, the Tapioca Qt4 Client Library
 * Copyright (C) 2006 by INdT
 *  @author Andre Moreira Magalhaes <andre.magalhaes@indt.org.br>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA
 */

#ifndef QTTAPIOCA_TEXT_CHANNEL_H
#define QTTAPIOCA_TEXT_CHANNEL_H

#include <QtCore/QList>
#include <QtCore/QObject>
#include <QtCore/QString>
#include <qglobal.h>

#include <QtTapioca/Channel>

namespace QtTapioca {

class Connection;
class ChannelTarget;
class TextChannelPrivate;

class Q_DECL_EXPORT TextChannel : public Channel {
    Q_OBJECT
    Q_DECLARE_PRIVATE(TextChannel)
    Q_ENUMS(ChatState)

public:
    class Message {
    public:
        enum Type {
            Normal = 0,
            Action = 1,
            Notice = 2,
            AutoReply = 3
        };

        enum DeliveryError {
            Unknown = 0,
            ContactOffline,
            InvalidContact,
            PermissionDenied,
            MessageTooLong
        };

        Message(const QString &contents);
        ~Message();

        QString contents() const { return m_contents; }
        uint timestamp() const { return m_timestamp; }
        Type type() const { return m_type; }


    private:
        friend class TextChannel;

        Message(const QString &contents, uint timestamp, Type type, int id = -1, bool pending = true);

        QString m_contents;
        uint m_timestamp;
        Type m_type;
        int m_id;
        mutable bool m_pending;
    };

    enum ChatState {
        Gone = 0,
        Inactive = 1,
        Active = 2,
        Paused = 3,
        Composing = 4
    };


    ~TextChannel();

    void sendMessage(const QString &contents);
    void sendMessage(const Message &message);
    void acknowledge(const Message &message);
    QList<TextChannel::Message>  pendingMessages() const;
    bool setLocalChatState(TextChannel::ChatState state);
    TextChannel::ChatState localChatState() const;

Q_SIGNALS:
    void messageReceived(const QtTapioca::TextChannel *tch, const QtTapioca::TextChannel::Message &message);
    void messageDeliveryError(const QtTapioca::TextChannel::Message &message,
                              QtTapioca::TextChannel::Message::DeliveryError error);
    void messageSent(const QtTapioca::TextChannel::Message &message);
    void chatStateChanged(const QtTapioca::TextChannel *tch, QtTapioca::TextChannel::ChatState state);

private Q_SLOTS:
    void onMessageReceived(uint id, uint timestamp, uint sender, uint type, uint flags, const QString &text);
    void onSendError(uint error, uint timestamp, uint type, const QString &text);
    void onSent(uint timestamp, uint type, const QString &text);
    void onChatStateChanged(uint contact, uint state);

private:
    friend class Connection;

    TextChannel(Connection *conn, const QString &serviceName, const QString &objPath, ChannelTarget *target, QObject *parent = 0);

    TextChannelPrivate *d;
};

} // namespace

#endif

