// JavaScript Document
var customfilterwin;
var helpContent;
var wikistore;
var hasAudio = !!(document.createElement('audio').canPlayType);

Ext.Ajax.timeout = 120000; //2 minutes
Ext.BLANK_IMAGE_URL = '../javascript/ext/images/gray/s.gif';

function highlightCount(id, highlight) {
    id = '#'+id+'_count';
    if (highlight) {
        $(id).css('background-color','#555555');
        $(id).children().css('color','white');
    } else {
        $(id).css('background-color','#DFDFDF');
        $(id).children().css('color','#333333');
    }
}

$(document).ready(function() {

    jQuery('#nav ul.sf-menu').superfish({delay: 200,animation: {opacity:'show', height:'show'},speed: 'fast',autoArrows: false, dropShadows: false});
    if (clientexec.runTicketSummaries) clientexec.getTicketSummaries();
    clientexec.getSelectedProfileAndAvailableActions = function(){
        $('#selectedcustomernav').load('index.php?fuse=admin&view=availableActions');
    }
    processOnLoadFunctions();
    $('a[href="index.php?fuse=home&view=ViewEvents"]').parent().append('<div style="position:absolute;top: 114px;right: 4px;"><div class="eventcounts"><div id="session_count">'+clientexec.cache_eventcount_session+'</div><div id="day_count">'+clientexec.cache_eventcount_day+'</div></div></div>')
    getEventCounts();
    $('#searchquerytextfield').focus(function() {
        $('#searchquerytextfield').val('');
        $('#searchquerytextfield').css("color","white");
    });

    $('#profilepicture').attr('src',ce.getGravatarUrl(clientexec.admin_email));

    $('#offlineusers span').tipsy({gravity: 'e',fade:true, live: true});
    $('#recenttoggle_options a').tipsy({title:'qtip',gravity: 'w',fade: true, live: true});
	$('a[qtip].elapsed-time').tipsy({title:'qtip',html:true, gravity: 's',fade: true, live: true});

	$('a[qtip],span[qtip],div[qtip],img[qtip]').tipsy({title:'qtip',html:true, gravity: 'e',fade: true, live: true});
	//tips bound to the bottom of element
	$('a[qtip-s],span[qtip-s],div[qtip-s],img[qtip-s]').tipsy({title:'qtip-s',html:true, gravity: 'n',fade: true, live: true});

	//bind tabs
	$('.rightbartab').bind('click',function(e){
		$('.rightbartab').removeClass('active');
		$('.rightbardiv').hide();
		if ($(this).hasClass('onlineuserstab')) {
			ce.updateSessionVar('sidebar_activetab',1);
			$('#whoisonline').show();
		} else if ($(this).hasClass('kbsearchtab')) {
			ce.updateSessionVar('sidebar_activetab',2);
			$('#kbsearchdiv').show();
		} else if ($(this).hasClass('activecustomertab')) {
			ce.updateSessionVar('sidebar_activetab',0);
			clientexec.getSelectedProfileAndAvailableActions();
			$('#selectedcustomernav').show();
		}
		$(this).addClass('active');

	});

	clientexec.popupKBArticle = function(id,title)
	{
		if (typeof(title) === "undefined") title = "Knowledgebase Article";
		else {
			if (title.length > 45) title = title.substr(0,43)+"…";
		}
	    clientexec.kbarticle = new RichHTML.window({
	    	height: '400',
	    	width: '550',
	    	url: 'index.php?fuse=knowledgebase&view=KB_ArticlePopup&articleId='+id,
	    	actionUrl: 'index.php?action=saveCannedResponse&fuse=support',
	    	title: title
	    });
	    clientexec.kbarticle.show();
	}

	clientexec.searchKB = function() {
	    $('#kbsearchcontainer #kbsearchresults').html("<img style='margin:20px;padding-left:50px;' class='kbsearchresult-icon-article' src='../images/loader.gif'>");
	    var kbarticletemplate = "",prevDisabled="",nextDisabled="";
		$.ajax({
	          url: "index.php?fuse=knowledgebase&action=getAutoSuggetArtices",
		      dataType: 'json',
		      data: {start:clientexec.searchKB_start,subject: clientexec.searchKB_query},
		      success: function(json) {
				kbarticletemplate = "Results <span class='color:#888;'>("+json.total_entries+")</span> <div style='border-top:1px solid #ddd; width:175px;margin:5px 0px 0px 0px;'></div>";
		      	if (json.total_entries == 0) {
		      		$('#kbsearchcontainer #kbsearchresults').html(kbarticletemplate+"No articles found").show();
		      	} else {
		      		kbarticletemplate +="{{#entries}}<div class='kbsearchresult-article'><img class='kbsearchresult-icon-article' src='../templates/default/images/public/icon_article.png'><a qtip='{{excerpt}}' target='_blank' class='articleresult_access_{{access}}' onclick='clientexec.popupKBArticle({{id}},\"{{title}}\")'>{{title}}</a></div>{{/entries}}";
		      		if (json.total_entries > 5) {
		      			prevDisabled = (clientexec.searchKB_start==0) ? "disabled='disabled'": "";
		      			nextDisabled = (clientexec.searchKB_start + 5 >= json.total_entries) ? "disabled='disabled'": "";
		      			kbarticletemplate += "<div id='kbsearchresultsmore' class='richgrid-pagenavi'><span class='previouspostslink' "+prevDisabled+"></span><span class='nextpostslink' "+nextDisabled+"></span></div>";
		      		} else {
		      			kbarticletemplate += "<br/>";
		      		}

					$('#kbsearchcontainer #kbsearchresults').html(Mustache.render(kbarticletemplate, json)).show();
					clientexec.bindSearchResultClicks();
				}

				$.ajax({
			        url: 'index.php?fuse=clients&action=updateSessionCaches',
			        type: 'POST',
			        data: {KB_Searchquery:clientexec.searchKB_query,KB_Searchstart: clientexec.searchKB_start, KB_SearchResults:$('#kbsearchcontainer #kbsearchresults').html()},
			        success: function(xhr) {console.debug('here');}
			    });

		      }
	      });
	}

	clientexec.bindSearchResultClicks = function() {
		//we do this outside so that cached data will still benefit from this binding
		$('#kbsearchresultsmore .previouspostslink').bind('click',function(event) {
	    	if ($(this).attr('disabled')) {return false;}
	    	clientexec.searchKB_start = clientexec.searchKB_start-5;
	    	clientexec.searchKB();
		});

		$('#kbsearchresultsmore .nextpostslink').bind('click',function(event) {
	    	if ($(this).attr('disabled')) {return false;}
	    	clientexec.searchKB_start = clientexec.searchKB_start+5;
			clientexec.searchKB();
		});
	}
	clientexec.bindSearchResultClicks();


	$('#kbsearchcontainer #kbquery').bind('keypress',function(event){
	  if ( event.which == 13 ) {
	     event.preventDefault();
	     clientexec.searchKB_start = 0;
	     clientexec.searchKB_query = $('#kbsearchcontainer #kbquery').val();
		 clientexec.searchKB();
	  }
	});

	//getAutoSuggetArtices

	$('.toggleLink').bind('click',function(e){
		$('#right').toggle();
		$('.branding').toggle();
		$('.maincontainer').toggleClass('withrightpanel');
		$('.toggleLink').toggleClass('withrightpanel');

		//we need to save the setting
		$.ajax({
	        url: "index.php?fuse=clients&action=Admin_SaveCustomField",
	        type: 'POST',
	        data: {
	            newvalue: ($('.toggleLink').hasClass('withrightpanel')) ? "none" : "",
	            customfieldname: 'Sidebar_Position'
	        }
	    });

	});

	//if we are viewing the activecustomers lets call to update
	//selected customer in the event we changed it.
	if ($('.rightbartab.activecustomertab').hasClass('active')) {
		clientexec.getSelectedProfileAndAvailableActions();
	}

        $('.change-grid-showrecords').change(function(){
            $.ajax({
                url: "index.php?fuse=clients&action=Admin_SaveCustomField",
                type: 'POST',
                data: {
                    newvalue: $(this).val(),
                    customfieldname: 'Records per page'
                }
            });
        });

        $('.change-grid-showrecords').val(clientexec.records_per_view);

        //Prepare History Obj
        var History = window.History; // Note: We are using a capital H instead of a lower h
        if ( !History.enabled ) {
             // History.js is disabled for this browser.
             // This is because we can optionally choose to support HTML4 browsers or not.
            return false;
        }
        // Bind to StateChange Event
        History.Adapter.bind(window,'statechange',function(){ // Note: We are using statechange instead of popstate
            var State = History.getState(); // Note: We are using History.getState() instead of event.state
            History.log(State.data, State.title, State.url);
        });

});

//process clicking of filters from side bar
//will determine if we need a page refresh or not
processFilterClick = function(searchfilter, name, custom) {
	if (typeof(custom) === "undefined") custom = false;
    if ( (gView == 'ViewViewTickets') && (gFuse == "support") ){
        ticketlist.searchfilter = searchfilter;
        ticketlist.searchcustomerid = undefined;
        ticketlist.searchquery = "";
        ticketlist.PopulateTicketFilters(name,custom,true);
    } else {
        window.location.href = "index.php?fuse=support&view=ViewTickets&searchfilter="+searchfilter;
    }
}

function lazyLoadEmailCustomer() {
    if(typeof emailCustomer == 'function') {
        emailCustomer();
    } else {
        ce.lazyLoad(['../templates/admin/views/clients/EmailCustomer.js'], function () {
            emailCustomer();
        });
    }
}

function lazyLoadSupportTicket(a1,a2) {
    if(typeof addSupportTicket == 'function') {
        addSupportTicket(a1,a2);
    } else {
        ce.lazyLoad(['../javascript/customfields.js', '../templates/admin/views/support/AddTicket.js'], function () {
            addSupportTicket(a1,a2); // Generic function that can load ExtJS elements
        });
    }
}

function loadSplahScreen() {
    ce.lazyLoad(
        "../javascript/jquery.simplemodal.min.js",
        function(){
            // Display an external page using an iframe
            var src = "https://www.clientexec.com/promo/index.php?version="+gVer;
            $.modal('<iframe src="' + src + '" height="360" width="960" style="border:0" scrolling="no"></iframe><div id="splashscreencb-div"><input id="splashscreencb" type="checkbox" checked="checked" />&nbsp;&nbsp;Show this screen next time I log in</div>', {
                    containerCss:{backgroundColor:"#fff", borderColor:"#fff", height:383, padding:0, width:960},
                    overlayClose:true,
                    opacity:70
            });
            $('#splashscreencb').click(function(){
                if ($('#splashscreencb').is(':checked')) {
                    updateSplashScreenValue(1,gStaffUserId)
                } else {
                    updateSplashScreenValue(0,gStaffUserId);
                }
            });
        }
    );
}


function updateSplashScreenValue(showNextLogin,userId) {
    Ext.Ajax.request({
       url: 'index.php?fuse=admin&action=updateSplashScreenValue',
       success: function(xhr) {
            var data = Ext.decode(xhr.responseText);
       },
       params: {show : showNextLogin,
				userid: userId}
    });
}

function getEventCounts() {
    // Set a timer to delay the call
    if($('#session_count').html()==".."){
        setTimeout("callEventPolling()", 1500);
    }
    setInterval("callEventPolling()", 20000);
}

function callEventPolling()
{
    Ext.Ajax.request({
        url: 'index.php?fuse=admin&action=getEventNotifications',
        success: function(xhr) {
            ce.checkRedirectLogin(xhr);
            var updateCache = false;
            var e = Ext.decode(xhr.responseText);
            //check to see if new counts are diff if diff then lets force save
            if ($('#session_count').html() != e.eventCounts.session) {
                updateCache = true;
            }
            $('#session_count').html(e.eventCounts.session);
            $('#day_count').html(e.eventCounts.day);
            if (updateCache) ce.updateEventCache();

            var newEventCount = e.eventCounts.newEvents.length;
            if (newEventCount > 0) {
                for(var x=0; x < newEventCount; x++) {
                    //only show events we didn't cause
                    if (e.eventCounts.newEvents[x].userid != ceChat.me.id) {
                        ce.showNewEvent(e.eventCounts.newEvents[x].subject,e.eventCounts.newEvents[x].fullName,e.eventCounts.newEvents[x].email);
                    }
                }

            }
        }
    });
}

clientexec.getTicketSummaries = function()
{
    // Set a timer to delay the call
    if($('#supportticketsummary').html()==""){
        setTimeout("callTicketSummaries()", 1000);
    } else {
    	setInterval("callTicketSummaries()", 15000);
    }
}

function callTicketSummaries()
{
	$('#supportticketsummary').load('index.php?fuse=support&view=SideBarTicketSummary', function() {
        ce.updateTicketsCache();
	});
}

function ceHelpPopup()
{
	var cssId = 'helpcss';  // you could encode the css path itself to generate id..
	if (!document.getElementById(cssId))
	{
	    var head  = document.getElementsByTagName('head')[0];
	    var link  = document.createElement('link');
	    link.id   = cssId;
	    link.rel  = 'stylesheet';
	    link.type = 'text/css';
	    link.href = 'https://www.clientexec.com/members/newedge/utilities/min/index.php?g=supportwidgetcss';
	    link.media = 'all';
	    head.appendChild(link);
	}

	if (typeof(CESupportWidget) == "undefined") {
		ce.lazyLoad("https://www.clientexec.com/members/newedge/utilities/min/index.php?g=supportwidgetjs",
	      function(){
			if (typeof(CESupportWidget) !== "undefined") {
			  CESupportWidget.init({
			    url:         "https://www.clientexec.com/members",
			    tabPosition: "left",
			    hide_tab: true,
			    tabId:       "ask-us",
			    forceSuggestions: true,
			    ticketTypeId: 22
			    //requester_email: "admin@yourinstall.com",
			    //requester_name: "admin name",
			  });
			}
			window.CESupportWidget.show();
	      }
	    );
	}else{
		window.CESupportWidget.show();
	}

//<link href="https://www.clientexec.com/members/newedge/utilities/min/index.php?g=supportwidgetcss" media="screen" rel="stylesheet" type="text/css">
}

function createNewFilter()
{
    customfilterwin = new Ext.Window({
        id          : 'customfilter-win',
        autoLoad: {
            url: 'index.php?fuse=admin&view=viewAddTicketFilter',
            scripts: true
        },
        title       : lang('Add Ticket Filter'),
        width       : 500,
        autoHeigh   : true,
        closeable   : true,
        modal       : true,
        minimizable : false,
        plain       : true
    });
    customfilterwin.show();
}

function moveGuestToCustomer(id,fuse,action)
{
    oldurl = window.location.href;
    //need to see if we are in tickets
    var aPosition = oldurl.indexOf("frmClientID=");
    if(aPosition > -1){
        newurl = oldurl.substring(0,aPosition);
    }else{
        newurl = oldurl+"&";
    }
    document.getElementById(id).innerHTML = lang("Migrate to user ID:") + "<form style='display:inline;padding-left:27px;' method='post' action='index.php?fuse="+ fuse +"&action=" + action + "'><input type='hidden' name='sessionHash' value='"+gHash+"' /><input type='hidden' name='oldurl' value='"+newurl+"' /><input type='text' size='10' name='userId' value='' /> <input style='position:relative;top:-2px;' type='submit' value='" + lang("go") + "' class='button_small' onclick='return confirmChangeOwnership();' /></form>";
//document.getElementById('userid').focus();
}



// users dropdown list //used in billing module and other places that requires client list.. don't delete'
allclientsstore = new Ext.data.JsonStore({
    id: "allclientsstore",
    root: 'clients',
    totalProperty: 'totalcount',
    idProperty: 'id',
    remoteSort: true,
    fields: [
    'id','firstname','lastname', 'fullname','isOrganization','email','dateactivated','status','statusname','clienttype','clienttypename','clienttypebgcolor'
    ],
    // load using script tags for cross domain, if the data in on the same domain as
    // this page, an HttpProxy would be better
    proxy: new Ext.data.HttpProxy({
        url: 'index.php?fuse=clients&action=GetClientList&comma=yes&onlyactiveinactive=yes'
    })
});
allclientsstore.setDefaultSort('lastname', 'asc');

clientexec.bindCustomerDropdown = function() {
    document.getElementById('remote-users').style.display='';
    var customerDropDownWithTooltip = new Ext.form.ComboBox({
        tpl: '<tpl for="."><div qtip="<div style=\'text-align:left;\'>id: {id}<br/>contact: {firstname} {lastname}<br/>e-mail: {email}<br/>status: {statusname}<br/>type: {clienttypename}</div>" class="customer-dropdown-item x-combo-list-item"><span style="text-transform:capitalize;">{fullname}</span></div></tpl>',
        store: allclientsstore,
        mode: 'remote',
        lazyRender: false,
        editable:false,
        triggerAction: 'all',
        selectOnFocus:true,
        applyTo: 'remote-users',
        width: '156',
        onSelect: function(record){
            window.location = String.format('index.php?fuse=clients&view=Admin_Profile_Contact&frmClientID={0}', record.data.id);
        }
    });
    customerDropDownWithTooltip.setValue(lang('Select a customer')+' ...');
}

Ext.onReady(function(){

    var ds = new Ext.data.Store({
        proxy: new Ext.data.HttpProxy({
            url: 'index.php?fuse=admin&action=GetSearchResults'
        }),
        reader: new Ext.data.JsonReader({
            root: 'results',
            totalProperty: 'totalcount',
            id: 'id'
        }, [
        {
            name: 'name'
        },

        {
            name: 'type'
        },

        {
            name: 'tooltip'
        },

        {
            name: 'match'
        },

        {
            name: 'url'
        }
        ])
    });

    // Custom rendering Template
    var resultTpl = new Ext.XTemplate(
        '<tpl for="."><div class="search-item" title="{tooltip}">',
        '<h3><span>{type}</span>{name}</h3>',
        '{match}',
        '</div></tpl>'

        );

    var search = new Ext.form.ComboBox({
        store: ds,
        typeAhead: false,
        loadingText: lang('Searching')+'...',
        width: 194,
        height:5,
        minChars:3,
        handleHeight:5,
        value: lang("Live search"),
        pageSize:10,
        listWidth:300,
        listClass: 'searchresultlist',
        autoHeight:false,
        y:-1,
        hideTrigger:true,
        tpl: resultTpl,
        applyTo: 'searchquerytextfield',
        itemSelector: 'div.search-item',
        onSelect: function(record){ // override default onSelect to do redirect
            window.location =
            String.format('{0}', record.data.url);
        },
        listeners: {
            'collapse' : function (combo){
                if (combo.store.data.length==0) {
                    ce.msg('No Match Found');
                } else {
                    $('#searchquerytextfield').val(lang('Live search'));
                    $('#searchquerytextfield').css("color","#444");
                }
            },
            'blur' : function (combo) {
                if (combo.store.data.length==0) {
                    $('#searchquerytextfield').val(lang('Live search'));
                    $('#searchquerytextfield').css("color","#444");
                }
            }
        }
    });

    items = [];
    if (features.accounts) {
        items.push({
            id: 'showdropdownlist',
            boxLabel:'Show customer dropdown list',
            checked: true
        });
    }
    items.push({
        id: 'showsupportticketlinks',
        boxLabel:'Show support ticket links',
        checked: true
    });
    items.push({
        id: 'showonlinecustomers',
        boxLabel:'Show last seen',
        checked: true
    });
});

function HideShowAndUpdateCustomField(which,imgid,customfieldname,whichopposite){

    style = "";
    if (!document.getElementById)  return false;
    if (which.style.display=="none"){
        which.style.display="";

        if (typeof(whichopposite)!="undefined") {
            whichopposite.style.display="none";
        }

        if(document.images[imgid] != null){
            document.images[imgid].src= relativePath + "images/collapse.gif";
        }
    }else{

        style = "none";
        which.style.display="none";

        if (typeof(whichopposite)!="undefined") {
            whichopposite.style.display="";
        }

        if(document.images[imgid] != null){
            document.images[imgid].src= relativePath + "images/expand.gif";
        }
    }

    Ext.Ajax.request({
        url: "index.php?fuse=clients&action=Admin_SaveCustomField",
        success: function(xhr) {
            var data = Ext.util.JSON.decode(xhr.responseText);
            if(data.error){
                //we do not need to repopulate the filters if there was a validation error
                msg(lang("There was an error when updating your custom field"));
            }
        },
        failure: function() {
        },
        params: {
            newvalue: style,
            customfieldname: customfieldname
        }
    });


    return style;
}

function toggleTicketParent(id,customfieldname){

    style = "";

    if(document.getElementById(id+'_options').style.display == "none"){
        document.getElementById(id+'_options').style.display = "";
        document.getElementById(id).className = "toggleopen";
    }else{
        style = "none";
        document.getElementById(id+'_options').style.display = "none";
        document.getElementById(id).className = "toggle";
    }

    Ext.Ajax.request({
        url: "index.php?fuse=clients&action=Admin_SaveCustomField",
        success: function(xhr) {
            var data = Ext.util.JSON.decode(xhr.responseText);
            if(data.error){
                //we do not need to repopulate the filters if there was a validation error
                msg(lang("There was an error when updating your custom field"));
            }
        },
        failure: function() {
        },
        params: {
            newvalue: style,
            customfieldname: customfieldname
        }
    });

}

/*
 * The following override for automatically sizing a combo boxes contents
 * Replaces the previous one based on code at:
 * http://www.extjs.com/forum/showthread.php?63851-DISCUSS-ComboBox-should-allow-quot-auto-quot-as-its-listWidth-setting.-*Saves*-code.&p=367041#post367041
 *
 * This code is based on a plugin at:
 * http://www.extjs.com/forum/showthread.php?94641-Plugin-to-allow-auto-sizing-of-the-combo-s-list&p=459687#post459687
 *
 * Since we originally had an override in place, in order to apply new code in one location
 * instead of having to add a plugins option to 140+ ComboBox configugations, the plugin
 * was converted to an override
 *
 * expand seems the appropriate method to override (as opposed to initList as previously)
 * as the lines of code that setWidth on list and innerList do not have any effect before
 * the original expand is called but do work as expected after the original expand is called
 */
(function() {
    var originalComboBoxExpand = Ext.form.ComboBox.prototype.expand;

    Ext.override(Ext.form.ComboBox, {
        expand: function() {
            //prevent expand event from being fired when invoking original function
            this.suspendEvents();
            originalComboBoxExpand.apply(this, arguments);
            this.resumeEvents();

            if (this.innerList && this.list && !this.list.autosized) {
                //this.list.autosized is a new property for the purposes of managing state

                var itemEl = this.view && this.view.getEl()
                && this.view.getEl().child(this.itemSelector || ".x-combo-list-item");

                if (itemEl) {
                    var store = this.getStore();
                    var listenerFunc = function() {
                        this.list.autosized=false;
                    };

                    /*
                     * store.events.load/update.autosizeListenerAdded are new state mgmt properties
                     * so that the necessary events for performing resizing when the underlying store
                     * is changed, only get added once
                     */
                    if (store.events && store.events.load && !store.events.load.autosizeListenerAdded) {
                        store.on('load', listenerFunc, this);
                        store.events.load.autosizeListenerAdded = true;
                    }

                    if (store.events && store.events.update && !store.events.update.autosizeListenerAdded) {
                        store.on('update', listenerFunc, this);
                        store.events.update.autosizeListenerAdded = true;
                    }

                    var autoWidth = Math.max(this.minListWidth, this.getWidth());
                    var defaultWidth = autoWidth;

                    var textMetrics = Ext.util.TextMetrics.createInstance(itemEl);

                    store.each(function(record) {
                        autoWidth = Math.max(autoWidth, textMetrics.getWidth(record.get(this.displayField)));
                    }, this);

                    if (autoWidth > defaultWidth) {
                        autoWidth = Math.ceil(autoWidth * 1.15); //consider different approach
                        this.list.setWidth(autoWidth);
                        this.innerList.setWidth(autoWidth - this.list.getFrameWidth("lr"));
                        this.list.alignTo(this.wrap, this.listAlign);
                    }

                    this.list.autosized = true;
                }
            }

            //invoke original expand event at very end just as in original method
            this.fireEvent('expand', this);
        }
    });
}());

/**
* Lazy load to add notes
*/
CE.prototype.addNote = function() {
    if(typeof CE.prototype.showClientNotes == 'function') {
        CE.prototype.showClientNotes();
    } else {
        ce.lazyLoad(['../templates/admin/views/clients/profile/Notes_Add.js'], function () {
            CE.prototype.showClientNotes();
        });
    }
}

function togglePackageListType(type) {
    if (type == 'domain') {
        window.location = 'index.php?fuse=domains&view=ViewDomainsList';
    } else if (type == 'hosting') {
        window.location = 'index.php?fuse=clients&view=ViewPackagesList';
    } else if (type =='general') {
        window.location = 'index.php?fuse=clients&view=ViewGeneralPackagesList';
    } else if (type =='ssl') {
        window.location = 'index.php?fuse=clients&view=ViewSSLPackagesList';
    }
}

/* Old chat.js - now handles online users*/
var ceChat;

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 title="'+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 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);
        $('#cemyticketscount').text(e.tickets.mytickets);
    }

    //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) {
					 $('#'+this.id +' span').attr('original-title',lang("Logged Off")+' '+ e.offlineusers[offlineuserindex]['time']+ ' '+lang("ago"));
                     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) && gShowAlsoViewing && (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>'
                    chatlink = '';

                    //update if someone is viewing our view
                    if (gShowAlsoViewing && (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)
        }

    }

    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');
            var myStatus = 0;
            /*
            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;
                    }
                }
            }*/
        }
    }

    // END CLASS DEFINITION

    ceChat = new CEChat();

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



// tipsy, facebook style tooltips for jquery
// version 1.0.0a
// (c) 2008-2010 jason frame [jason@onehackoranother.com]
// released under the MIT license

(function($) {

    function maybeCall(thing, ctx) {
        return (typeof thing == 'function') ? (thing.call(ctx)) : thing;
    };

    function Tipsy(element, options) {
        this.$element = $(element);
        this.options = options;
        this.enabled = true;
        this.fixTitle();
    };

    Tipsy.prototype = {
        show: function() {
            var title = this.getTitle();
            if (title && this.enabled) {
                var $tip = this.tip();

                $tip.find('.tipsy-inner')[this.options.html ? 'html' : 'text'](title);
                $tip[0].className = 'tipsy'; // reset classname in case of dynamic gravity
                $tip.remove().css({top: 0, left: 0, visibility: 'hidden', display: 'block'}).prependTo(document.body);

                var pos = $.extend({}, this.$element.offset(), {
                    width: this.$element[0].offsetWidth,
                    height: this.$element[0].offsetHeight
                });

                var actualWidth = $tip[0].offsetWidth,
                    actualHeight = $tip[0].offsetHeight,
                    gravity = maybeCall(this.options.gravity, this.$element[0]);

                var tp;
                switch (gravity.charAt(0)) {
                    case 'n':
                        tp = {top: pos.top + pos.height + this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
                        break;
                    case 's':
                        tp = {top: pos.top - actualHeight - this.options.offset, left: pos.left + pos.width / 2 - actualWidth / 2};
                        break;
                    case 'e':
                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth - this.options.offset};
                        break;
                    case 'w':
                        tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width + this.options.offset};
                        break;
                }

                if (gravity.length == 2) {
                    if (gravity.charAt(1) == 'w') {
                        tp.left = pos.left + pos.width / 2 - 15;
                    } else {
                        tp.left = pos.left + pos.width / 2 - actualWidth + 15;
                    }
                }

                $tip.css(tp).addClass('tipsy-' + gravity);
                $tip.find('.tipsy-arrow')[0].className = 'tipsy-arrow tipsy-arrow-' + gravity.charAt(0);
                if (this.options.className) {
                    $tip.addClass(maybeCall(this.options.className, this.$element[0]));
                }

                if (this.options.fade) {
                    $tip.stop().css({opacity: 0, display: 'block', visibility: 'visible'}).animate({opacity: this.options.opacity});
                } else {
                    $tip.css({visibility: 'visible', opacity: this.options.opacity});
                }
            }
        },

        hide: function() {
            if (this.options.fade) {
                this.tip().stop().fadeOut(function() {$(this).remove();});
            } else {
                this.tip().remove();
            }
        },

        fixTitle: function() {
            var $e = this.$element;
            if ($e.attr('title') || typeof($e.attr('original-title')) != 'string') {
                $e.attr('original-title', $e.attr('title') || '').removeAttr('title');
            }
        },

        getTitle: function() {
            var title, $e = this.$element, o = this.options;
            this.fixTitle();
            var title, o = this.options;
            if (typeof o.title == 'string') {
                title = $e.attr(o.title == 'title' ? 'original-title' : o.title);
            } else if (typeof o.title == 'function') {
                title = o.title.call($e[0]);
            }
            title = ('' + title).replace(/(^\s*|\s*$)/, "");
            return title || o.fallback;
        },

        tip: function() {
            if (!this.$tip) {
                this.$tip = $('<div class="tipsy"></div>').html('<div class="tipsy-arrow"></div><div class="tipsy-inner"></div>');
            }
            return this.$tip;
        },

        validate: function() {
            if (!this.$element[0].parentNode) {
                this.hide();
                this.$element = null;
                this.options = null;
            }
        },

        enable: function() {this.enabled = true;},
        disable: function() {this.enabled = false;},
        toggleEnabled: function() {this.enabled = !this.enabled;}
    };

    $.fn.tipsy = function(options) {

        if (options === true) {
            return this.data('tipsy');
        } else if (typeof options == 'string') {
            var tipsy = this.data('tipsy');
            if (tipsy) tipsy[options]();
            return this;
        }

        options = $.extend({}, $.fn.tipsy.defaults, options);

        function get(ele) {
            var tipsy = $.data(ele, 'tipsy');
            if (!tipsy) {
                tipsy = new Tipsy(ele, $.fn.tipsy.elementOptions(ele, options));
                $.data(ele, 'tipsy', tipsy);
            }
            return tipsy;
        }

        function enter() {
            var tipsy = get(this);
            tipsy.hoverState = 'in';
            if (options.delayIn == 0) {
                tipsy.show();
            } else {
                tipsy.fixTitle();
                setTimeout(function() {if (tipsy.hoverState == 'in') tipsy.show();}, options.delayIn);
            }
        };

        function leave() {
            var tipsy = get(this);
            tipsy.hoverState = 'out';
            if (options.delayOut == 0) {
                tipsy.hide();
            } else {
                setTimeout(function() {if (tipsy.hoverState == 'out') tipsy.hide();}, options.delayOut);
            }
        };

        if (!options.live) this.each(function() {get(this);});

        if (options.trigger != 'manual') {
            var binder   = options.live ? 'live' : 'bind',
                eventIn  = options.trigger == 'hover' ? 'mouseenter' : 'focus',
                eventOut = options.trigger == 'hover' ? 'mouseleave' : 'blur';
            this[binder](eventIn, enter)[binder](eventOut, leave);
        }

        return this;

    };

    $.fn.tipsy.defaults = {
        className: null,
        delayIn: 0,
        delayOut: 0,
        fade: false,
        fallback: '',
        gravity: 'n',
        html: false,
        live: false,
        offset: 0,
        opacity: 0.8,
        title: 'title',
        trigger: 'hover'
    };

    // Overwrite this method to provide options on a per-element basis.
    // For example, you could store the gravity in a 'tipsy-gravity' attribute:
    // return $.extend({}, options, {gravity: $(ele).attr('tipsy-gravity') || 'n' });
    // (remember - do not modify 'options' in place!)
    $.fn.tipsy.elementOptions = function(ele, options) {
        return $.metadata ? $.extend({}, options, $(ele).metadata()) : options;
    };

    $.fn.tipsy.autoNS = function() {
        return $(this).offset().top > ($(document).scrollTop() + $(window).height() / 2) ? 's' : 'n';
    };

    $.fn.tipsy.autoWE = function() {
        return $(this).offset().left > ($(document).scrollLeft() + $(window).width() / 2) ? 'e' : 'w';
    };

    /**
     * yields a closure of the supplied parameters, producing a function that takes
     * no arguments and is suitable for use as an autogravity function like so:
     *
     * @param margin (int) - distance from the viewable region edge that an
     *        element should be before setting its tooltip's gravity to be away
     *        from that edge.
     * @param prefer (string, e.g. 'n', 'sw', 'w') - the direction to prefer
     *        if there are no viewable region edges effecting the tooltip's
     *        gravity. It will try to vary from this minimally, for example,
     *        if 'sw' is preferred and an element is near the right viewable
     *        region edge, but not the top edge, it will set the gravity for
     *        that element's tooltip to be 'se', preserving the southern
     *        component.
     */
     $.fn.tipsy.autoBounds = function(margin, prefer) {
		return function() {
			var dir = {ns: prefer[0], ew: (prefer.length > 1 ? prefer[1] : false)},
			    boundTop = $(document).scrollTop() + margin,
			    boundLeft = $(document).scrollLeft() + margin,
			    $this = $(this);

			if ($this.offset().top < boundTop) dir.ns = 'n';
			if ($this.offset().left < boundLeft) dir.ew = 'w';
			if ($(window).width() + $(document).scrollLeft() - $this.offset().left < margin) dir.ew = 'e';
			if ($(window).height() + $(document).scrollTop() - $this.offset().top < margin) dir.ns = 's';

			return dir.ns + (dir.ew ? dir.ew : '');
		}
	};

})(jQuery);
