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
                //    }
                //);

                Ext.Ajax.request({
                   url: 'index.php?fuse=clients&action=conversationSendMessage',
                   params: {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.userCount = 0;
        this.userTpl = new Ext.Template(
          '<li class="{color}" id="onlineUser{id}" email="{email}" usertype="{type}" userstatus="{status}" 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}" email="{email}" usertype="{type}" 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) {
        $('#onlineusers li').each(function(index){
            if(id != "onlineUser"+id) {
                var tip = Ext.getCmp('onlineUserTips' + id)
                if (tip != undefined) tip.hide();
            }
        });
    }

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

    //determines if an id we pass exists in the new offline users list
    function isMyDomIdInOfflineUsers(e,id) {
        if (!e.offlineusers) return false;
        for (j = 0; j < e.offlineusers.length; j++) {
            if(id == "offlineUser"+e.offlineusers[j].id) {
                var obj=new Array();
                obj[0] = j;
                return obj;
            }
        }
        return false;
    }

    //determines if an id we pass exists in the new online users list
    function isMyDomIdInOnlineUsers(e,id) {
        if (!e.users) return false;
        for (j = 0; j < e.users.length; j++) {
            if(id == "onlineUser"+e.users[j].id) {
                var obj=new Array();
                obj[0] = j;
                return obj;
            }
        }
        return false;
    }

    CEChat.prototype.processOffline = function(e){
        try{

            if (!e.offlineusers) return;

            // Loop through the userList to see if they are in poll result
            $('#offlineusers li').each(function(index){
                 offlineuserindex = isMyDomIdInOfflineUsers(e,this.id);
                 if (offlineuserindex) {
                     e.offlineusers.splice(offlineuserindex[0],1);
                 } else {
                     document.getElementById(this.id).parentNode.removeChild(document.getElementById(this.id));
                 }
            });

            // 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') {
                    if (e.superadmin == 1) profilelink = 'index.php?fuse=admin&amp;view=EditAddAdminAccount&amp;adminid=' + e.offlineusers[i].id;
                }else {
                    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.insertFirst("offlineusers", e.offlineusers[i]);
            }
            
        } catch(ex) {
            ce.log(1, ex)
        }
    }

    CEChat.prototype.processOnline = function(e){
        try{

        if (!e.users) return;

        // Only show online users alerts if this isn't the first load
        var showAlerts = false;
        var usersViewingSamePage="";
        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
        $('#onlineusers li').each(function(index){
             onlineuserindex = isMyDomIdInOnlineUsers(e,this.id);
             if (onlineuserindex) {
                 //update if someone is viewing our view
                if ( (e.users[onlineuserindex[0]].id != e.self) && (gFuse==e.users[onlineuserindex[0]].lastview['m']) && (gView==e.users[onlineuserindex[0]].lastview['v']) ) {
                    if (e.users[onlineuserindex[0]].lastview['t']=="") {
                        usersViewingSamePage += e.users[onlineuserindex[0]].name + ", ";
                    } else {
                        m = e.users[onlineuserindex[0]].lastview['t'].split('|');
                        if (eval(m[0]) == m[1]) {
                            usersViewingSamePage += e.users[onlineuserindex[0]].name + ", ";
                        }
                    }
                }
                // if they are in the poll result, update their information
                if ($(this.id).attr('userstatus') != e.users[onlineuserindex[0]].status) {
                    document.getElementById(this.id).className = e.users[onlineuserindex[0]].color;
                }
                if (e.users[onlineuserindex[0]].id == e.self) {
                    ceChat.me = e.users[onlineuserindex[0]]; //had to change from this.. since now this means jquery li element
                }
                e.users.splice(onlineuserindex[0],1);
             } else {
                 if ( (showAlerts) && ($('#'+this.id).attr('usertype')=="staff") ) {
                    ce.showNewEvent($('#'+this.id+' a span').html() + ' has logged off','Login System',$('#'+this.id).attr('email'));
                 }
                 document.getElementById(this.id).parentNode.removeChild(document.getElementById(this.id));
             }
        });

        // 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') ) {
                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>'

                    //update if someone is viewing our view
                    if ( (gFuse==e.users[i].lastview['m']) && (gView==e.users[i].lastview['v']) ) {
                        if (e.users[i].lastview['t']=="") {
                            usersViewingSamePage += e.users[i].name + ", ";
                        } else {
                            m = e.users[i].lastview['t'].split('|');
                            if (eval(m[0]) == m[1]) {
                                usersViewingSamePage += e.users[i].name + ", ";
                            }
                        }
                    }
                } 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]);

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

            //only add to userlist the guys who are online

            if (showAlerts) ce.showNewEvent(e.users[i].name + " has logged in", "Login System", e.users[i].email);
            // 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) + document.getElementById("dragOnlineUser" + e.users[i].id).innerHTML + html.substring(html.length-6, html.length);
        }

        //todo add setting to determine if we want this at all in team settings
        if (usersViewingSamePage!="") {
            usersViewingSamePage = lang("Also viewing: ") + usersViewingSamePage.substring(0, usersViewingSamePage.length-2);
            document.getElementById('alsoviewing').innerHTML = usersViewingSamePage;
            document.getElementById('breadcrumb').style.display = '';
        } else {
            document.getElementById('alsoviewing').innerHTML = "";
            document.getElementById('breadcrumb').style.display = 'none';
        }

        }catch(ex){
            ce.log(1, ex)
        }
        Ext.QuickTips.init();

    }

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

        this.processOnline(e);


        // Update the online user status select dropdown
        if (this.me != -1) {
            var myStatus = document.getElementById('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
                document.getElementById("chatbar" + this.chatbarList[i].id).parentNode.removeChild(document.getElementById("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) {
                    document.getElementById("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 {
                    document.getElementById("chatbarCount" + this.chatbarList[i].id).innerHTML = '';
                }
                document.getElementById("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) {
                document.getElementById("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) {
                 document.getElementById("chatbar" + this.chatbarList[i].id).parentNode.removeChild(document.getElementById("chatbar" + this.chatbarList[i].id));
                 this.chatbarList.splice(i, 1);
                 //new Ajax.Request(   'index.php?fuse=clients&action=conversationEnd',
                 //{
                 //    postBody    : 'chatId='+chatid
                 //});
                 Ext.Ajax.request({
                   url: 'index.php?fuse=clients&action=conversationEnd',
                   params: {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;
            }
        }
        document.getElementById("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;
            }
        }
        document.getElementById("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',
                        params: {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
                //    }
                //);
                Ext.Ajax.request({
                   url: 'index.php?fuse=clients&action=conversationSetTyping',
                   params: {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
                //    }
                //);
                Ext.Ajax.request({
                   url: 'index.php?fuse=clients&action=conversationAddUser',
                   params: {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;

            document.getElementById("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',{});
    Ext.Ajax.request({
       url: '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 */
    pollProvider = new Ext.direct.PollingProvider({
        id: 'onlineUserAndChatBarPoller',
        type: 'polling',
        url: 'index.php?fuse=clients&action=ConversationsPoll',
        interval: 10000
    });
    Ext.Direct.addProvider(pollProvider);
    
    Ext.Direct.on('ConversationsPoll', function(e) {
        ceChat.process(e);
        ce.updateWhoIsOnlineCache();
    });
    // 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: document.getElementById('onlineStatus').value},
        success: changeChatStatusSuccess
    });
}

// Handle chat status update callback
function changeChatStatusSuccess(response, opts) {
    var data = response.responseText.split("|");
    document.getElementById('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();
