var ceChat;

// Override the default TextArea to handle enter for submit
ChatTextArea = Ext.extend(Ext.form.TextArea, {
    constructor: function(config) {
        ChatTextArea.superclass.constructor.apply(this, arguments);
    },
    fireKey: function (e, t) {
        if (e.getKey() == e.ENTER && !e.shiftKey) {
            // only send if the user typed a message
            if (t.value != '') {
                new Ajax.Request(   'index.php?fuse=clients&action=conversationSendMessage',
                    {
                        postBody    : 'conversation_id='+t.id.substr("message".length)+'&message='+t.value
                    }
                );
                // After sending a message, automatically refresh messages so the interface feels snappy.
                ceChat.fetchMessagesTask(t.id.substr("message".length));
                t.value = '';
                e.stopEvent();
            }
        }
    },
    onKeyUp: function (e,t) {
        if (!(e.getKey() == e.ENTER && !e.shiftKey))
        {
            ceChat.processOnKeyUp(t.id.substr("message".length), t.value.length);
        }
    }
});

/*
// Define some variable for the title updater
var titleUpdates = new Array();
titleUpdates[0] = document.title; // Add the default title to the array
var titleMappings = new Array();
var mC = 0;

function updateTitleBar() {

	// Count how many titles are in rotation
	var count = titleUpdates.length;

	// Pointless updating the title if theres only the default one
	if(count != 1) {

		// Check if we have or are about to exceed the count
		if(mC > count-1) {mC = 0;}

		// Check if this title hasn't been removed
		if(titleUpdates[mC]) {

			// Update the title bar
			document.title=titleUpdates[mC];
		}

		// Increment the message count
		mC++;
	}

	// Set a timer to update again
	sT=setTimeout("updateTitleBar()", 1500);
}
*/


Ext.onReady(function() {

    // START CLASS DEFINITION

    function CEChat ()
    {
        this.DELAY_MIN = 2500; // 2.5 sec
        this.DELAY_MAX = 20000; // 20 secs
        this.DELAY_FACTOR = 2;
        this.DELAY_INCR_IF_INACTIVE = 5; // after 5 inactive polls

        /* Online User List */
        this.userList = [];
        this.userCount = 0;
        this.offlineuserList = [];
        this.offlineuserCount = 0;
        this.userTpl = new Ext.Template(
          '<li class="{color}" id="onlineUser{id}" onmouseover="ceChat.hideUserTips({id});">',
            '<span class="when" id="when{id}">{chatlink}</span>',
            '<a href="{link}"><span id="dragOnlineUser{id}" style="{namestyle}">{name}</span></a>',
          '</li>'
        );

        this.userOfflineTpl = new Ext.Template(
          '<li class="{color}" id="offlineUser{id}" onmouseover="ceChat.hideUserTips({id});">',
            '<a href="{link}"><span qtip="'+lang("Logged Off")+' {time}&nbsp;'+lang("ago")+'" style="{namestyle}">{name}</span></a>',
          '</li>'
        );

        /* Chat Bar Vars */
        this.chatbarList = [];
        this.chatbarTpl = new Ext.Template(
          '<li id="chatbar{id}">',
            '<a href="javascript:ceChat.launchChat({id}, \'{title}\');" id="chatbarlink{id}">{title}</a> ',
            '&nbsp;<span id="chatbarCount{id}" style="color:red;font-size:10px;" ></span>',
          '</li>'
        );

        /* Chats To AutoLaunch */
        this.chatsToLaunch = [];

        /* Tracker for where to place the next open chat window */
        this.nextPosition = 0;

        /* Messages Vars */
        this.chatInfo = [];
        this.messageTpl = new Ext.Template(
          '<div class="chat-message">',
            '<span class="when">{time}</span>',
            '<span class="bold-item" style="color:{color}">{name}</span><br/>',
            '{message}',
          '</div>'
        );

        /* My Information */
        this.me = -1;
    }

    // Get position for next chat window
    CEChat.prototype.getNextWindowPostion = function() {
        this.nextPosition = (this.nextPosition + 50) % 400;
        return this.nextPosition;
    }

    // Get all user ids
    CEChat.prototype.hideUserTips = function(id) {
        for (i = 0; i < this.userList.length; i++) {
           if (this.userList[i].id != id) {
               var tip = Ext.getCmp('onlineUserTips' + this.userList[i].id)
               if (tip != undefined) tip.hide();
           }
        }
    }

    // Process the latest poll result
    CEChat.prototype.process = function(e) {
        this.processUsers(e);
        this.processChatBar(e);
    }


    CEChat.prototype.processOffline = function(e){
        try{
            // Update the count if it has changed
            if (this.offlineuserCount != e.offlinecount) {
                //we only want userCount to be online users
                this.offlineuserCount = e.offlinecount;
            }

            // Loop through the userList to see if they are in poll result
            // NOTE: looping backwards so the indices aren't broken when we remove from the list
            for (i = this.offlineuserList.length - 1; i >= 0 ; i--) {
                var index = -1;
                for (j = 0; j < e.offlineusers.length; j++) {
                    if (e.offlineusers[j].id == this.offlineuserList[i].id) {
                        index = j;
                        break;
                    }
                }
                if (index == -1) {
                    // if they are not in the poll result, remove them
                    $("offlineUser" + this.offlineuserList[i].id).parentNode.removeChild($("offlineUser" + this.offlineuserList[i].id));
                    this.offlineuserList.splice(i, 1);
                } else {
                    // if they are in the poll result, update their information
                    if (this.offlineuserList[i].status != e.offlineusers[index].status) {
                        // show message saying the user status has changed
                        // TODO
                        //msg(this.userList[i].name + ' is now available.')
                        $('offlineUser' + this.offlineuserList[i].id).className = e.offlineusers[index].color;
                    }
                    this.offlineuserList[i] = e.offlineusers[index];
                    if (e.offlineusers[index].id == e.self) this.me = e.offlineusers[index];
                    e.offlineusers.splice(index, 1);
                }
            }

            // Now process any remaining users in the poll result
            // These are new users that have logged on.
            for (i = 0; i < e.offlineusers.length; i++) {
                profilelink = "";
                if(e.offlineusers[i].type == 'staff') {
                    //e.offlineusers[i].namestyle = "font-weight:bold;";
                    if (e.superadmin == 1) profilelink = 'index.php?fuse=admin&amp;view=EditAddAdminAccount&amp;adminid=' + e.offlineusers[i].id;
                }else {
                    //e.offlineusers[i].color = "none";
                    e.offlineusers[i].color = "";
                    profilelink = 'index.php?fuse=clients&amp;view=Admin_Profile_Contact&amp;frmClientID=' + e.offlineusers[i].id;
                }
                e.offlineusers[i].link = (profilelink == '')? 'javascript:void(0);' : profilelink;
                this.userOfflineTpl.append("offlineusers", e.offlineusers[i]);
                this.offlineuserList[this.offlineuserList.length] = e.offlineusers[i];
            }
        }catch(ex){
            ce.log(1, ex)
        }
    }

    CEChat.prototype.processOnline = function(e){
        try{
        // Only show online users alerts if this isn't the first load
        var showAlerts = false;
        if (this.userCount > 0) showAlerts = true;


        // Update the count if it has changed
        if (this.userCount != e.count) {
            //we only want userCount to be online users
            this.userCount = e.count;
        }

        // Loop through the userList to see if they are in poll result
        // NOTE: looping backwards so the indices aren't broken when we remove from the list
        for (i = this.userList.length - 1; i >= 0 ; i--) {
            var index = -1;
            for (j = 0; j < e.users.length; j++) {
                if (e.users[j].id == this.userList[i].id) {
                    index = j;
                    break;
                }
            }
            if (index == -1) {
                // if they are not in the poll result, remove them
                if (showAlerts) msg(this.userList[i].name + ' has logged off', '');
                $("onlineUser" + this.userList[i].id).parentNode.removeChild($("onlineUser" + this.userList[i].id));
                this.userList.splice(i, 1);
            } else {
                // if they are in the poll result, update their information
                if (this.userList[i].status != e.users[index].status) {
                    // show message saying the user status has changed
                    // TODO
                    //msg(this.userList[i].name + ' is now available.')
                    $('onlineUser' + this.userList[i].id).className = e.users[index].color;
                }
                this.userList[i] = e.users[index];
                if (e.users[index].id == e.self) this.me = e.users[index];

                //$("when" + this.userList[i].id).innerHTML = this.userList[i].time;
                e.users.splice(index, 1);
            }
        }

        // Now process any remaining users in the poll result
        // These are new users that have logged on.

        for (i = 0; i < e.users.length; i++) {
            var profilelink = '';
            var emaillink = '';
            var chatlink = '';
            if ( (e.users[i].type == 'staff') ) {
                //e.users[i].namestyle = "font-weight:bold;";
                if (e.superadmin == 1) {
                    profilelink = 'index.php?fuse=admin&amp;view=EditAddAdminAccount&amp;adminid=' + e.users[i].id;
                }
                // only show the chatlink for staff for this release
                if (e.users[i].id != e.self) {
                    chatlink = '<a href="javascript:void(0);" onclick="startConversation(' + e.users[i].id + ');"><img src="../templates/admin/images/comment.png" alt="Chat"/></a>'
                } else {
                    //you might want to show yourself as a different color
                    e.users[i].namestyle = "font-weight:bold;";
                }
            }else {
                //e.users[i].color = "none";
                e.users[i].color = "";
                profilelink = 'index.php?fuse=clients&amp;view=Admin_Profile_Contact&amp;frmClientID=' + e.users[i].id;
                emaillink = 'index.php?fuse=clients&amp;view=ShowEmail&amp;frmClientID=' + e.users[i].id;
            }
            e.users[i].link = (profilelink == '')? 'javascript:void(0);' : profilelink;
            e.users[i].chatlink = chatlink;
            this.userTpl.append("onlineusers", e.users[i]);

            //only add to userlist the guys who are online
            if (showAlerts) msg(e.users[i].name + " has logged in", "");
            this.userList[this.userList.length] = e.users[i];

            // Handle yourself differently
            if (e.users[i].id == e.self) {
                this.me = e.users[i];
                continue;
            }

            // Create tooltip with profile, email and chat links
            var width = 0;
            if (profilelink != '') width += 27;
            if (emaillink != '') width += 35;
            if (chatlink != '') width += 27;

            // Allow the online user to be invited to conversations by dragging them to the window.
                var dragSource = new Ext.dd.DragSource("onlineUser" + e.users[i].id, {
                    dragData:
                    {
                        id: e.users[i].id
                    },
                    ddGroup: 'onlineUsers'
                });
                // hack to change the draggable html, ugly but seems to work
                var html = dragSource.getDragEl().innerHTML;
                dragSource.getDragEl().innerHTML = html.substring(0, html.length-6) + $("dragOnlineUser" + e.users[i].id).innerHTML + html.substring(html.length-6, html.length);
        }
        }catch(ex){
            ce.log(1, ex)
        }
        Ext.QuickTips.init();

    }

    CEChat.prototype.processUsers = function(e) {
        var hideLastSeen = false;
        if(showLastSeen){
            $('lastxseen').style.display='';
            if(e.offlineusers!=undefined){
                this.processOffline(e);
            }else{
                hideLastSeen = true;
            }
        }
        if(!showLastSeen || hideLastSeen){
            $('lastxseen').style.display='none';
        }else{
            $('lastxseen').style.display='';
        }

        this.processOnline(e);


        // Update the online user status select dropdown
        if (this.me != -1) {
            var myStatus = $('onlineStatus');
            if (myStatus.value != this.me.status) {
                for (i = 0; i < myStatus.options.length; i++) {
                    if (myStatus.options[i].value == this.me.status) {
                        myStatus.options[i].selected = true;
                        break;
                    }
                }
            }
        }
    }

    // Process the latest chat list poll result
    CEChat.prototype.processChatBar = function(e) {


        for (i = this.chatbarList.length - 1; i >= 0; i--) {
            var index = -1;
            for (j = 0; j < e.chats.length; j++) {
                if (e.chats[j].id == this.chatbarList[i].id) {
                    index = j;
                    break;
                }
            }
            if (index == -1) {
                // if they are not in the poll result, remove them
                $("chatbar" + this.chatbarList[i].id).parentNode.removeChild($("chatbar" + this.chatbarList[i].id));
                this.chatbarList.splice(i, 1);
            } else {
                // if they are in the poll result, update their information

                this.chatbarList[i] = e.chats[index];
                if (this.chatbarList[i].count > 0) {
                    $("chatbarCount" + this.chatbarList[i].id).innerHTML = '(' + this.chatbarList[i].count + ')';

/*
                    if(e.chats[i].title.charAt(0) != "<") {
                        // Check if this chat already has a message in rotation
                        if(!titleUpdates[titleMappings[this.chatbarList[i].id]]) {

                                // Add a new mapping for the chat ID to the title messagae ID
                            // This is to avoid having to increment through 1000+ id's if many chats have been had.
                                titleMappings[this.chatbarList[i].id] = titleUpdates.length;

                                // Add the title message
                                titleUpdates[titleUpdates.length]="New Message from " + this.chatbarList[i].title;
                        }
                    }
                    */
                } else {
                    $("chatbarCount" + this.chatbarList[i].id).innerHTML = '';
                }
                $("chatbarlink" + this.chatbarList[i].id).innerHTML = this.chatbarList[i].title;
                e.chats.splice(index, 1);
            }
        }

        // anything that is left is a new conversation
        for (i = 0; i < e.chats.length; i++) {

            var isAutoLaunch = ceChat.isChatAutoLaunch(e.chats[i].id);

            if ((hasAudio) &&(!isAutoLaunch)) {
                //gets called on new start chat
                //and new message - so I could do ring instead
                //alert(dump(ceChat.isChatAutoLaunch(e.chats[i].id)));
                var sound = new Audio("../images/incoming.ogg");
                sound.play();
            }

            this.chatbarTpl.append("activechats", e.chats[i]);
            if (e.chats[i].count > 0 && !isAutoLaunch) {
                $("chatbarCount" + e.chats[i].id).innerHTML = '(' + e.chats[i].count + ')';
/*
                // Check if the chat title has <del in it
                if(e.chats[i].title.charAt(0) != "<") {

                    // Check if we have an existing mapping for this chat
                    if(!titleMappings[e.chats[i].id]) {

                            // Add a new mapping for the chat ID to the title messagae ID
                            // This is to avoid having to increment through 1000+ id's if many chats have been had.
                            titleMappings[e.chats[i].id] = titleUpdates.length;

                            // Add the title message
                            titleUpdates[titleUpdates.length]="New Message from " + e.chats[i].title;
                    }
                } */
            }
            this.chatbarList[this.chatbarList.length] = e.chats[i];
            if (isAutoLaunch) {
                ceChat.launchChat(e.chats[i].id, e.chats[i].title);
            }
        }
    }

    // Add a chat to autolaunch
    CEChat.prototype.addChatToAutoLaunch = function(id) {
        this.chatsToLaunch[this.chatsToLaunch.length] = id;
    }

    // Determine if a chat window should autolaunch
    CEChat.prototype.isChatAutoLaunch = function(id) {
        for (var j = 0; j < this.chatsToLaunch.length; j++) {
            if (this.chatsToLaunch[j] == id) return true;
        }
        return false;
    }

    // Quit the chat and clean up the resources
    CEChat.prototype.quitChat = function(chatid) {
        for (i = 0; i < this.chatbarList.length; i++) {
            if (this.chatbarList[i].id == chatid) {
                 $("chatbar" + this.chatbarList[i].id).parentNode.removeChild($("chatbar" + this.chatbarList[i].id));
                 this.chatbarList.splice(i, 1);
                 new Ajax.Request(   'index.php?fuse=clients&action=conversationEnd',
                 {
                     postBody    : 'chatId='+chatid
                 });
                 break;
            }
        }
        for (i = 0; i < this.chatInfo.length; i++) {
            if (this.chatInfo[i].id == chatid) {
                Ext.TaskMgr.stop(this.chatInfo[i].task);
                this.chatInfo.splice(i, 1);
                break;
            }
        }
        removeChatFromCookie(id);
    }

    // When a chat is minimized we can stop the fetch messages task
    CEChat.prototype.minimizeChat = function(id) {
        for (i = 0; i < this.chatInfo.length; i++) {
            if (this.chatInfo[i].id == id) {
                Ext.TaskMgr.stop(this.chatInfo[i].task);
                break;
            }
        }
        $("chatbar" + id).className = "";
        removeChatFromCookie(id);
    }

    // When a chat is restored we can restart the fetch messages task
    CEChat.prototype.restoreChat = function(id) {
        for (i = 0; i < this.chatInfo.length; i++) {
            if (this.chatInfo[i].id == id) {
                Ext.TaskMgr.start(this.chatInfo[i].task);
                break;
            }
        }
        $("chatbar" + id).className = "chatbar-clicked";
        addChatToCookie(id);
    }

    CEChat.prototype.fetchMessagesTask = function(id) {
        for (i = 0; i < this.chatInfo.length; i++) {
            if (this.chatInfo[i].id == id) {
                // only fetch more messages if the previous task has completed
                if (this.chatInfo[i].working == false) {
                    Ext.Ajax.request({
                        url: 'index.php?fuse=clients&action=Conversation_GetMessages&conversation_id=' + id + '&largestMsg=' + this.chatInfo[i].largestMsg,
                        success: fetchMessagesTaskSuccess
                    });
                }
                break;
            }
        }
    }

    CEChat.prototype.processFetchMessages = function(response) {
        var data = Ext.util.JSON.decode(response.responseText);
        var msgPanel = Ext.ComponentMgr.get('messagePanel' + data.id);
        var d = msgPanel.body.dom;
        var scrollDown = false;

        var chatIndex = 0;
        for (i = 0; i < this.chatInfo.length; i++) {
            if (this.chatInfo[i].id == data.id) {
                chatIndex = i;
                break;
            }
        }

        // prevent any more http requests from being sent until this one finishes processing
        this.chatInfo[chatIndex].working = true;

        // Only auto scroll down if we are scrolled all the way to the bottom
        // This allows users to scroll up and read old messages without being
        // auto scrolled back to the bottom.  This test must be done BEFORE
        // we add any new messages to the panel or the calculation will fail.
        if (d.scrollTop >= d.scrollHeight - d.offsetHeight) scrollDown = true;

        // Process the new messages
        var nametocompare="";
        for (i = 0; i < data.messages.length; i++) {
            // Ensure that the id is numeric or comparisons fail
            data.messages[i].id = parseInt(data.messages[i].id);

            if (data.messages[i].id > this.chatInfo[chatIndex].largestMsg) {
                this.chatInfo[chatIndex].largestMsg = data.messages[i].id;
            } else {
                // Prevents showing a message multiple times
                continue;
            }
            this.messageTpl.append(msgPanel.body, data.messages[i]);

            if(hasAudio){
                //do not play sound when just loaded .. only new msgs
                nametocompare = this.me.name.split(" ");
                nametocompare = (nametocompare[0]+" "+nametocompare[1].charAt(0)+".");
                if ((data.messages[i].name == "System") || (nametocompare == data.messages[i].name) ) {
                   //do nothing as it is a system message or us
                }else{
                    var sound = new Audio("../images/incoming.ogg");
                    sound.play();
                }
            }
        }

        if (data.messages.length > 0 && scrollDown) {
            d.scrollTop = d.scrollHeight - d.offsetHeight;
        }

        Ext.ComponentMgr.get('typingUsers' + data.id).getEl().dom.innerHTML = '&nbsp;&nbsp;' + data.typing;
        Ext.ComponentMgr.get('participants' + data.id).getEl().dom.innerHTML = '&nbsp;&nbsp;' + data.participants;

        // Chat polling backoff handling for performance reasons
        // if we have a new message reset the poll backoff
        // if we don't have any messages, increment the backoff counter
        // and if needed increase the poll delay
        if (data.messages.length > 0) {
            // We have new messages
            this.chatInfo[chatIndex].delay = this.DELAY_MIN;
            this.chatInfo[chatIndex].inactivePolls = 0;
        } else {
            // No new messages increase delay if needed and allowed
            this.chatInfo[chatIndex].inactivePolls++;
            if (this.chatInfo[chatIndex].inactivePolls >= this.DELAY_INCR_IF_INACTIVE
                && this.chatInfo[chatIndex].delay * this.DELAY_FACTOR <= this.DELAY_MAX) {
                // increase the delay
                this.chatInfo[chatIndex].inactivePolls = 0;
                this.chatInfo[chatIndex].delay = this.chatInfo[chatIndex].delay * this.DELAY_FACTOR;
            }
        }
        this.chatInfo[chatIndex].task.interval = this.chatInfo[chatIndex].delay;

        this.chatInfo[chatIndex].working = false;
    }

    // This manages detecting when users start/stop typing
    CEChat.prototype.processOnKeyUp = function (id, length) {
        var i = this.getChatInfoIndex(id);
        if (i != -1) {
            var typing = -1;
            // transition from < 3 to 3+ mean the user is typing
            if (length > 2 && this.chatInfo[i].typingLength < 3) {
                typing = 1;
            // transition to < 3 from 3+ means the user has erased the content is stop typing
            } else if (length < 3 && this.chatInfo[i].typingLength > 2) {
                typing = 0;
            }
            this.chatInfo[i].typingLength = length;
            if (typing != -1) {
                // User has added or removed text, update their typing status
                new Ajax.Request(   'index.php?fuse=clients&action=conversationSetTyping',
                    {
                        postBody    : 'conversation_id='+id+'&typing='+typing
                    }
                );
            }
        }
    }

    CEChat.prototype.getChatInfoIndex = function (id) {
        for (i = 0; i < this.chatInfo.length; i++) {
            if (this.chatInfo[i].id == id) {
                return i;
            }
        }
        return -1;
    }

    // Open a chat window
    CEChat.prototype.launchChat = function(id, winTitle) {

    	// Remove the new message alert from the title message array
    	//delete titleUpdates[titleMappings[id]];

        if (!Ext.WindowMgr.get('conversation'+id)) {

            var xyPos = ceChat.getNextWindowPostion();

            var inputArea = new ChatTextArea({
                                id:"message"+id,
                                height:50,
                                width: '100%',
                                hideLabel: true,
                                border: false,
                                enableKeyEvents: true
                             });

            var chatbar = new Ext.form.FormPanel({
                region: 'center',
                split: true,
                items: inputArea,
                height: 50,
                margins:'0 3 3 3',
                cmargins:'0 3 3 3'
            });

            // Typing users notifcation area
            var typingUsers = new Ext.BoxComponent({
                id:'typingUsers' + id,
                region: 'south',
                height:15
            });

            var bottomPanel = new Ext.Panel({
                layout: 'border',
                region: 'south',
                border: false,
                height: 65,
                items: [chatbar,typingUsers]
            });

            // Messages panel
            var messages = new Ext.Panel({
                id: 'messagePanel' + id,
                region: 'center',
                split: true,
                autoScroll: true,
                margins:'3 3 0 0',
                cmargins:'3 3 0 3',
                html: ''
            });

            // Participants panel
            var participants = new Ext.BoxComponent({
                id:'participants' + id,
                region: 'north',
                height:15
            });

            var topPanel = new Ext.Panel({
                layout: 'border',
                region: 'center',
                border: false,
                height: 65,
                items: [messages,participants]
            });

            var win = new Ext.Window({
                id          : 'conversation'+id,
                title       : winTitle,
                layout      : 'border',
                width       : 400,
                height      : 350,
                x           : xyPos,
                y           : xyPos,
                closeable   : true,
                minimizable : true,
                plain       : true,
                items       : [topPanel, bottomPanel]
            });

            win.on({
            	'minimize': {
            		fn: minimizeWin
            	},
            	'beforeClose': {
            		fn: closeWin
            	}
            });

            win.show();

            var droptarget=new Ext.dd.DropTarget(win.getId(),{
            ddGroup: 'onlineUsers'
            });
            droptarget.notifyDrop = function (dd, e, data) {
                new Ajax.Request(   'index.php?fuse=clients&action=conversationAddUser',
                    {
                        postBody    : 'conversation_id=' + id + '&user_id=' + data.id
                    }
                );
                ceChat.fetchMessagesTask(id);
            }

            // Create a chatInfo object for storing the last read time and task.
            var chatInfo = new Object();
            chatInfo.largestMsg = 0;
            chatInfo.id = id;
            chatInfo.task = undefined;
            chatInfo.working = false; // set when processing messages
            chatInfo.typingLength = 0;
            chatInfo.delay = this.DELAY_MIN;
            chatInfo.inactivePolls = 0;

            chatInfoIndex = this.chatInfo.length;

            this.chatInfo[chatInfoIndex] = chatInfo;

            // Start a simple clock task that updates the chat contents
            var task = {
                id: 'messageTask' + id,
                run: function(){
                    ceChat.fetchMessagesTask(id);
                },
                interval: this.DELAY_MIN
            }
            Ext.TaskMgr.start(task);

            // store the task so it can be stopped later
            this.chatInfo[chatInfoIndex].task = task;

            $("chatbar" + id).className = "chatbar-clicked";
            addChatToCookie(id);
        } else {
            var chatwin = Ext.WindowMgr.get('conversation'+id);
            if (chatwin.hidden) {
                Ext.WindowMgr.get('conversation'+id).show();
                ceChat.restoreChat(id);
            } else {
                minimizeWin(chatwin);
            }
        }
    }

    // END CLASS DEFINITION

    ceChat = new CEChat();

    // Clear all typing requests when a new page loads
    // TODO: This should probably be moved to a system event later
    // instead of making an extra ajax request.
    new Ajax.Request('index.php?fuse=clients&action=conversationSetTyping',{});

    // Load the open chat cookie so we know which windows to autolaunch
    processOpenChatCookie();
    // MJL START COMMENT
    /* Online Users and Chat List Polling */
    Ext.Direct.addProvider({
        id: 'onlineUserAndChatBarPoller',
        type: 'polling',
        url: 'index.php?fuse=clients&action=ConversationsPoll',
        interval: 10000
    });

    Ext.Direct.on('ConversationsPoll', function(e) {
        ceChat.process(e);
    });
    // MJL END COMMENT
});

function fetchMessagesTaskSuccess(response) {
    ceChat.processFetchMessages(response);
}


// Update the user chat status
function changeChatStatus() {
    Ext.Ajax.request({
        url: 'index.php?fuse=clients&action=conversationUpdateStatus',
        params: 'status=' + $('onlineStatus').value,
        success: changeChatStatusSuccess
    });
}

// Handle chat status update callback
function changeChatStatusSuccess(response, opts) {
    var data = response.responseText.split("|");
    $('onlineUser' + data[0]).className = data[1];
}

// Minimizes a chat window
function minimizeWin(win){
    win.hide();
    ceChat.minimizeChat(win.id.substr("conversation".length));
}

// Used for confirming that a user wants to close a window.
function closeWin(win){

    Ext.MessageBox.confirm(
        'Close Chat',
        'Are you sure you would like to end this chat session?',
         function(btn) {
             if (btn == "yes") {
                 var chatId = win.id.substr("conversation".length);
                 win.hide(null);
                 win.destroy();
                 ceChat.quitChat(chatId);
             }
    });
    return false;
}

function startConversation(user)
{
    Ext.Ajax.request({
        url: 'index.php?fuse=clients&action=conversationStart',
        params: 'userId='+user,
        success: startConversationSuccess
    });
}

function startConversationSuccess(response)
{
    // This allows the chat to popup automatically.
    ceChat.addChatToAutoLaunch(response.responseText);

    // Force the poll to refresh instantly so it feels very responsive.
    var poll = Ext.Direct.getProvider('onlineUserAndChatBarPoller');
    poll.disconnect();
    poll.connect();
}

function addChatToCookie(id)
{
    var openChats = Ext.util.Cookies.get("CE_OpenChats");
    if (openChats == null) {
        openChats = id;
    } else {
        openChats = openChats + "," + id;
    }
    Ext.util.Cookies.set("CE_OpenChats", openChats);
}

function removeChatFromCookie(id)
{
    var openChats = Ext.util.Cookies.get("CE_OpenChats");
    if (openChats == null) {
        return;
    } else {
        var openChatsArr = openChats.split(",");
        var newOpenChats = '';
        for (var i = 0; i < openChatsArr.length; i++)
        {
            if (openChatsArr[i] != '' && openChatsArr[i] != id) {
                if (newOpenChats == '') newOpenChats = openChatsArr[i];
                else newOpenChats = newOpenChats + "," + openChatsArr[i];
            }
        }
        Ext.util.Cookies.set("CE_OpenChats", newOpenChats);
    }
}

function processOpenChatCookie()
{
    var openChats = Ext.util.Cookies.get("CE_OpenChats");
    if (openChats == null) {
        return;
    } else {
        var openChatsArr = openChats.split(",");
        for (var i = 0; i < openChatsArr.length; i++)
        {
            if (openChatsArr[i] != '') {
                ceChat.addChatToAutoLaunch(openChatsArr[i]);
            }
        }
    }
}
// Start the title poller
//updateTitleBar();
