// -----------------------------------------------------
// Functionality to support the XMPP client in Liferay.
//
// $Id$
// -----------------------------------------------------

(function(callback) 
{
    var Palantiri;

    function $chat(jid, pass) { return new Palantiri.Chat(jid, pass); }

    Palantiri = {
        VERSION:  '1.0.0',
        BOSH_URL: '/http-bind'
    };

    Palantiri.Chat = function(jid, pass) 
    {
        this.connection = null; // The strophe connection object
        this.pass = pass;
        this.connected = false;

        this.jid = jid;
        this.sid = "";
        this.rid = "";

        this.avail = true;
        this.show  = "";
        this.msg   = "";
    };

    Palantiri.Chat.prototype = 
    {
        connect: function(cb)
        {
            this.connection = new Strophe.Connection(Palantiri.BOSH_URL);
            this.connection.connect(this.jid, this.pass, cb); //this.onConnect);
        },

        pause:  function() { this.connection.pause();  },
        resume: function() { this.connection.resume(); },

        attach: function()
        {
            this.sid = jQuery.cookie('XMPP_SID');
            this.rid = jQuery.cookie('XMPP_RID');
            this.jid = jQuery.cookie('XMPP_JID');

            if (this.sid && this.rid && this.jid)
            {
                this.connection = new Strophe.Connection(Palantiri.BOSH_URL);
                this.connection.attach(this.jid, this.sid, this.rid, function(status, error) {});

                var manager = Liferay.Chat.Manager;
                var roster  = jQuery.cookie("XMPP_ROSTER");
                var users;

                if (roster) 
                { 
                    users = roster.split(";");
                    users.pop();
                }
                else
                {
                    users = [];
                }

                manager._onlineBuddiesCount = 0;

                jQuery.each(users, function(i,v) { 
                    manager.myBuddies[i] = v;
                    manager._onlineBuddiesCount = manager._onlineBuddiesCount + 1;
                });

                manager._updateBuddyList();
            }
            else
            {
                this.connection = new Strophe.Connection(Palantiri.BOSH_URL);
                this.connection.connect(this.jid, this.pass, function(status, error) {});
            }
        },

        /** Function: Send a presence stanza.
         *  
         *  Parameters:
         *    (boolean) avail - False to send a presence stanza of type 'unavailable'. In this
         *                      case any other parameters will be ignored.
         *    (String) show - One of: away, chat, dnd, xa. Default is 'available'. (optional).
         *    (String) msg - The presence status message. (optional).
         */
        setPresence: function(avail, show, msg)
        {
            var pres;

            if (avail === undefined)
            {
                avail = this.avail;
                show  = this.show;
                msg   = this.msg;
            }

            if (!avail)
            {
                pres = $pres({from: this.jid, type: "unavailable"});
                this.avail = false;
                this.show  = 'xa';
            }
            else 
            {
                pres = $pres({from: this.jid});

                if (show == 'away' || show == 'chat' || show == 'dnd' || show == 'xa')
                {
                    pres.c('show').t(show).up();
                    this.show = show;
                }
                else
                {
                    this.show = '';
                }

                pres.c('priority').t("5").up();
                this.avail = true;
            }

            if (msg && msg != "") 
            { 
                pres.c('status').t(msg).up();
                this.msg = msg;
            }

            this.connection.send(pres.tree());
        },

        /** Function: Convenience function for for sending an 'available' presence stanza.  */
        setOnline: function(msg)
        {
            this.setPresence(true, 'chat', msg);
        },

        /** Function: Convenience function for for sending an 'unavailable' presence stanza.  */
        setOffline: function()
        {
            this.setPresence(false);
        },

        getDomain: function()
        {
            return Strophe.getDomainFromJid(this.jid);
        },

        setCookies: function()
        {
            jQuery.cookie("XMPP_SID", this.connection.sid, { path: "/" });
            jQuery.cookie("XMPP_RID", this.connection.rid, { path: "/" });
            jQuery.cookie("XMPP_JID", this.jid, { path: "/" });
        },

        setHandlers: function()
        {
            
            this.connection.addHandler(function(msg) {
                    var manager = Liferay.Chat.Manager;
                    var from  = msg.getAttribute('from');
                    var type  = msg.getAttribute('type');
                    var elems = msg.getElementsByTagName('body');
                    var body  = elems[0];

                    if (type == 'chat' && manager)
                    {
                        var chatWin = manager._createChatFromScreenName(from.substring(0, from.indexOf('@')));

                        if (chatWin)
                        {
                            chatWin._updateMessageWindowIncoming(
                                {
                                    content: Strophe.getText(body),
                                    createDate: Liferay.Chat.Util.getCurrentTimestamp()
                                }
                            );
                        }
                    }

                    return true;
                }, null, 'message', null, null,  null);

            this.connection.addHandler(function(msg) {
                    var manager = Liferay.Chat.Manager;
                    var show = jQuery(msg).children('show').text();
                    var from = msg.getAttribute('from');
                    var type = msg.getAttribute('type');
                    var fromSimple = from.substring(0, from.indexOf('@'));
                    var jid = jQuery.cookie("XMPP_JID");

                    // If the presence is from the user himself we ignore.
                    if (jid.startsWith(fromSimple)) { return true; }

                    // Slight misuse of show to control what happens...
                    if (type == "unavailable") { show = "unavailable"; }

                    // A missing 'show' means 'available'.
                    if (show == "") { show = "available"; }

                    if (show == 'available' || show == 'away' || show == 'dnd' || 
                        show == 'xa' || show == 'chat') 
                    {
                        // Go through the array to see if the user is already in the list
                        for (var i=0; i < manager.myBuddies.length; i++)
                        {
                            if (manager.myBuddies[i].match(new RegExp(fromSimple)))
                            {
                                if (show == 'available' || show == 'chat') { 
                                    manager.myBuddies[i] = fromSimple; }
                                else {
                                    manager.myBuddies[i] = "<i style='color:#aaa'>" + fromSimple + "</i>"; }

                                break;
                            }
                        }

                        // If we iterated through the whole array and didn't find the user
                        // then we need to add it to the end.
                        if (i == manager.myBuddies.length)
                        {
                            if (show == 'available') { 
                                manager.myBuddies.push(fromSimple); }
                            else {
                                manager.myBuddies.push("<i style='color:#aaa'>" + fromSimple + "</i>"); }

                        }

                        manager.myBuddies.sort(); // Default is alphabetical
                    }
                    else
                    {
                        var new_list = [];

                        // Build up a new list as that does not contain the user.
                        for (var i=0; i < manager.myBuddies.length; i++)
                        {
                            if (manager.myBuddies[i] != fromSimple &&
                                manager.myBuddies[i] != "<i style='color:#aaa'>" + fromSimple + "</i>")
                            {
                                new_list.push(manager.myBuddies[i]);
                            }
                        }

                        manager.myBuddies = new_list;
                    }

                    manager._updateBuddyList();
                    return true;
                }, null, 'presence', null, null,  null);
        }
    };
    
    if (callback) 
    { 
        callback(Palantiri);
    }

})(function () { 
    window.Palantiri = arguments[0]; 
});

