Source: plugins/wtapi.chat.js

import WTAPI from '../wtapi'
import {JSJaCMessage} from '../jsjac';

/**
 * A plugin that provides Chat functionality
 *
 * @version 1.0.0
 */

/**
 * Constructor for Chat plugin.
 * Instance will be created each time when new WTAPI instance is created. <br />
 * Plugin could be accessible thought WTAPI with <b>chat</b> property.
 *
 * @tutorial chat-plugin
 * @memberof WTAPI
 * @alias WTAPI.ChatPlugin
 * @augments Observer
 * @public
 * @constructor
 */
function ChatPlugin(wtapi) {
    this._wtapi = wtapi;
    this._wtapi.registerHandler("message", this._handleMessage, this, 100);
    this._roster = this._wtapi.roster;

    // Initialize supper
    WTAPI.Observable.call(this);
}

ChatPlugin.prototype = Object.create(WTAPI.Observable.prototype);

// ============================================================
// Public events
// ============================================================

/**
 * Indicates that new message is received from remote user.
 *
 * @event WTAPI.ChatPlugin#message_received
 * @property {WTAPI.User} user
 * @property {WTAPI.Message} message
 */

/**
 * Indicates that message is read by destination.
 *
 * @event WTAPI.ChatPlugin#message_delivered
 * @property {WTAPI.User} user
 * @property {string} id Id message delivered
 */

// ============================================================
// Public functions
// ============================================================

/**
 * Sends a message to user.
 *
 * @param {WTAPI.User} user
 * @param {WTAPI.Message} message
 */
ChatPlugin.prototype.send = function (user, message) {
    var packet = new JSJaCMessage();
    packet.setID(message.getId());
    packet.setTo(user.getJid());
    packet.setType('chat');
    packet.setBody(message.getBody());

    packet.appendNode('request', {'xmlns': 'urn:xmpp:receipts'});
    packet.appendNode('markable', {'xmlns': 'urn:xmpp:chat-markers:0'});

    this._wtapi.getConnection().send(packet);
}

/**
 * Sends a notification that message are read by user.
 *
 * @param {WTAPI.User} user A user that send message
 * @param {WTAPI.Message} message
 */
ChatPlugin.prototype.sendDeliveryConfirmation = function (user, message) {
    var packet = new JSJaCMessage();
    packet.setTo(user.getJid());
    packet.setType('chat');
    packet.appendNode('received', {'xmlns': 'urn:xmpp:receipts', 'id': message.getId()});
    packet.appendNode('displayed', {'xmlns': 'urn:xmpp:chat-markers:0', 'id': message.getId()});
    packet.appendNode('store', {'xmlns': 'urn:xmpp:hints'});

    this._wtapi.getConnection().send(packet);
}

// ============================================================
// ChatPlugin callbacks
// ============================================================

/**
 * @private
 */
ChatPlugin.prototype._handleMessage = function (packet) {
    if (this._handleMessageDelivery(packet)) {
        return true;
    }

    // Default chat message handling
    var type = packet.getType();
    var body = packet.getBody();

    if (!(type == "" || type == "chat" || type == "normal") || body.length == 0) {
        return false;
    }

    var id = packet.getID();
    var builder = new WTAPI.Message.Builder();
    builder.withId(id);
    builder.withBody(body);
    var message = builder.build();

    var nick = packet.getChildVal('nick', 'http://jabber.org/protocol/nick')
    var from = packet.getFromJID();
    var jid = from.removeResource().toString();
    var user = this._roster.getUser(jid);

    if (user === null) {
        if (nick == '') {
            nick = null;
        }
        user = this._roster.createUser(jid, nick);
    }
    this._fire("message_received", user, message);
}

/**
 * @private
 */
ChatPlugin.prototype._handleMessageDelivery = function (packet) {
    var els = packet.getNode().getElementsByTagName('received');
    if (els.length == 1) {
        if (els.item(0).namespaceURI != 'urn:xmpp:receipts') {
            return false;
        }
    } else {
        els = packet.getNode().getElementsByTagName('displayed');
    }
    if (els.length == 1) {
        var received = els.item(0);
        var id = received.getAttribute('id');
        var from = packet.getFromJID();
        var jid = from.removeResource().toString();
        var user = this._roster.getUser(jid);

        if (user && id) {
            this._fire("message_delivered", user, id);
        }
    }
}

export default ChatPlugin;