/**
* @package JLive! Chat
* @version 3.5.4
* @copyright (C) Copyright 2008 CMS Fruit, CMSFruit.com. All rights reserved.
* @license GNU/LGPL http://www.gnu.org/licenses/lgpl-3.0.txt

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3 of the License, or (at your
option) any later version.

This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

You should have received a copy of the GNU Lesser General Public License
along with this program.  If not, see http://www.gnu.org/licenses/.
*/

var liveChatUri = 'index.php?option=com_livechat&view=popup';
var liveChatWindow = null;

var client = null;
var config = new Array();
var chatSessionId = null;
var chatSessionActive = 0;
var chatSessionMdate = 0;
var chatClientName = null;

var refreshTimer = null;
var refreshTimerDelay = 3; // in seconds

var preChat = null;
var inChat = null;

var msgInput = null;
var sessionDisplay = null;
var name = null;
var errorLayer = null;
var introLayer = null;
var msgLayer = null;
var nameLayer = null;
var continueLayer = null;
var closeLayer = null;
var continueBtn = null;
var nameInput = null;

var preChatSelector = 'pre-chat';
var inChatSelector = 'in-chat';
var msgInputSelector = 'msg-input';
var sessionDisplaySelector = 'session-content-display';
var nameSelector = 'name';
var errorWrapperSelector = 'error-wrapper';
var introWrapperSelector = '.intro-wrapper';
var msgWrapper = 'msg-wrapper';
var nameContainerSelector = 'name-container';
var continueLayerSelector = '.continue-wrapper';
var closeWrapperSelector = 'p.close-wrapper';
var sendBtnSelector = '#in-chat .send-button';

var processingSomething = false;
var chatIsOffline = false;

function requestLiveChat(popupUri)
{
    var w = 480, h = 340;

    if(screen.availWidth && screen.availHeight) {
        w = screen.availWidth;
        h = screen.availHeight;
    }
	
    var popW = 340;
    var popH = 300;
	
    if(window.webkit)
    {
        //	Safari popup window should be about 10px more
        popW = 350;
        popH = 310;
    }
	
    var leftPos = (w-popW)/2, topPos = (h-popH)/2;

    liveChatWindow = window.open(popupUri,'LiveChatWindow','menubar=0,scrollbars=0,status=0,resizable=0,location=0,toolbar=0,height='+popH+',width='+popW+',left='+leftPos+',top='+topPos);
	
    if (window.focus) {
        liveChatWindow.focus();
    }

    return false;
}

function initLayers()
{
    loadConfig();
	
    preChat = $(preChatSelector);
    inChat = $(inChatSelector);
	
    msgInput = $(msgInputSelector);
    sessionDisplay = $(sessionDisplaySelector);
    name = $(nameSelector);
    errorLayer = $(errorWrapperSelector);
    introLayer = $$(introWrapperSelector);
    msgLayer = $(msgWrapper);
    nameLayer = $(nameContainerSelector);
    continueLayer = $$(continueLayerSelector);
    closeLayer = $$(closeWrapperSelector);
	
    sendBtn = $$(sendBtnSelector);
	
    continueBtn = $$(continueLayerSelector).getElement('input[type=image]');
    nameInput = $(nameContainerSelector).getElement('input[type=text]');
    closeBtn = $$(closeWrapperSelector).getElement('input[type=image]');
	
    if(nameInput)
    {
        nameInput.addEvent('keydown', function (event) {
            if(event.keyCode == 13)
            {
                //	user pressed enter on the keyboard
                initChatSession();
				
                return false;
            }
        });
    }
	
    if($(msgInputSelector))
    {
        $(msgInputSelector).addEvent('keydown', function (event) {
            if(event.keyCode == 13)
            {
                //	user pressed enter on the keyboard
                sendMsg();
            }
        });
    }
	
	
    $(nameSelector).setStyle('width', '91%');
    $(nameSelector).setStyle('border', '1px solid #725742');
    $(nameSelector).setStyle('margin-top', '3px');
    $(nameSelector).setStyle('padding', '5px 3px');
    $(nameSelector).setStyle('font-size', '14px');
    $(nameSelector).setStyle('font-family', 'arial');
	
    $(msgInputSelector).setStyle('width', '91%');
    $(msgInputSelector).setStyle('height', '40px');
    $(msgInputSelector).setStyle('font-family', 'arial');
    $(msgInputSelector).setStyle('font-size', '12px');
    $(msgInputSelector).setStyle('background-color', 'white');
    $(msgInputSelector).setStyle('color', '#313528');
    $(msgInputSelector).setStyle('display', 'block');
    $(msgInputSelector).setStyle('clear', 'both');
    $(msgInputSelector).setStyle('float', 'none');
    $(msgInputSelector).setStyle('margin-bottom', '5px');
}

function sendMsg()
{
    var sendTxt = $(msgInputSelector).getValue();
	
    var options = {
        method: 'get',
        onSuccess: function(response) {
            //	Clear Box
            $(msgInputSelector).setProperty('value', '');
						
            refreshSession(false);
        }
    };
			
    var uriVars = 'task=send_message&s='+chatSessionId+'&m='+URLEncode(sendTxt)+'&n='+URLEncode(chatClientName)+'&t='+$time();
	
    var myXhr = new XHR(options).send(liveChatUri, uriVars);
	
    return false;
}

function endChatSession()
{
    var options = {
        method: 'get',
        onSuccess: function(response) {
            window.close();
        },
        headers: {
            'X-Request': 'JSON'
        }
    };
	
    var uriVars = 'task=end_session&s='+URLEncode(chatSessionId)+'&t='+$time();
	
    var myXhr = new XHR(options).send(liveChatUri, uriVars);
	
    return false;
}

function initChatSession()
{
    if(processingSomething == false)
    {
        processingSomething = true;
		
        var options = {
            method: 'get',
            onSuccess: function(response) {
                var data = Json.evaluate(response);
							
                processingSomething = false;
							
                if(data.success == 0)
                {
                    $each(data.errors, function (item, index) {
                        $(errorWrapperSelector).setText(item+"\n");
                    });
                }
                else
                {
                    //	Waiting for Operator Response
                    chatClientName = $(nameSelector).getProperty('value');
                    continueBtn.removeEvents('click');
                    nameInput.removeEvents('keydown');
								
                    $(errorWrapperSelector).setText('Connecting, please wait...');
								
                    chatSessionId = data.chat_session_id;
								
                    startOfflineTimer();
								
                    checkIfChatAccepted();
                }
            },
            headers: {
                'X-Request': 'JSON'
            }
        };
		
        var uriVars = 'task=start_session&name='+URLEncode($(nameSelector).getProperty('value'))+'&t='+$time();
		
        var myXhr = new XHR(options).send(liveChatUri, uriVars);
    }
	
    return false;
}

function tryNextOperator()
{
    if(processingSomething == false)
    {
        processingSomething = true;
		
        var options = {
            method: 'get',
            onSuccess: function(response) {
                var data = Json.evaluate(response);
							
                processingSomething = false;
							
                //	Waiting for Operator Response
                chatClientName = $(nameSelector).getProperty('value');
                continueBtn.removeEvents('click');
                nameInput.removeEvents('keydown');
							
                $(errorWrapperSelector).setText('Connecting, please wait...');
							
                chatSessionId = data.chat_session_id;
							
                startOfflineTimer();
							
                checkIfChatAccepted();
            },
            headers: {
                'X-Request': 'JSON'
            }
        };
		
        var uriVars = 'task=try_next_operator&name='+URLEncode($(nameSelector).getProperty('value'))+'&t='+$time();
		
        var myXhr = new XHR(options).send(liveChatUri, uriVars);
    }
	
    return false;
}

function startOfflineTimer()
{
    var options = {
        method: 'get',
        onSuccess: function(response) {
            var data = Json.evaluate(response);
				
            if(data)
            {
                delayInMicroSeconds = data.operator_timeout * 1000;
					
                setTimeout('getNewClient()', delayInMicroSeconds);
            }
            else
            {
                //	Key is not setup yet
                getNewClient();
            }
        },
        headers: {
            'X-Request': 'JSON'
        }
    };

    var uriVars = 'task=get_key_details&t='+$time();
	
    var myXhr = new XHR(options).send(liveChatUri, uriVars);
}

function getNewClient()
{
    if(chatSessionActive == 0 && chatIsOffline == false)
    {
        var options = {
            method: 'get',
            onSuccess: function(response) {
                var data = Json.evaluate(response);
					
                if(data != false)
                {
                    //	We got a new client successfully
                    processingSomething = false;
						
                    //	Retry request with new client
                    tryNextOperator();
						
                    delayInMicroSeconds = data.operator_timeout * 1000;
						
                    setTimeout('getNewClient()', delayInMicroSeconds);
                }
                else
                {
                    setTimeout('chatOffline()', 2000);
                }
            },
            headers: {
                'X-Request': 'JSON'
            }
        };
	
        var uriVars = 'task=get_new_client&t='+$time();
		
        var myXhr = new XHR(options).send(liveChatUri, uriVars);
    }
}

function checkIfChatAccepted()
{
    var options = {
        method: 'get',
        onSuccess: function(response) {
            var data = Json.evaluate(response);
						
            chatSessionActive = data.is_active;
						
            if(chatSessionActive == 0 && data.mdate == 0)
            {
                //	Chat Still Pending
                setTimeout('checkIfChatAccepted()', 3000);
            }
            else if(chatSessionActive == 0 && data.mdate > 0)
            {
                //	Chat Declined
                getNewClient();
            }
            else if(chatSessionActive == 1 && data.mdate > 0)
            {
                //	Chat Accepted
                chatAccepted();
            }
        },
        headers: {
            'X-Request': 'JSON'
        }
    };
	
    var uriVars = 'task=check_session_active&i='+URLEncode(chatSessionId)+'&t='+$time();
	
    var myXhr = new XHR(options).send(liveChatUri, uriVars);
}

function loadConfig()
{
    var options = {
        method: 'get',
        onSuccess: function(response) {
            var data = Json.evaluate(response);
						
            $each(data.vars, function (item, index) {
                config[index] = item;
            });
        },
        headers: {
            'X-Request': 'JSON'
        }
    };
	
    var uriVars = 'task=get_config&t='+$time();
	
    var myXhr = new XHR(options).send(liveChatUri, uriVars);
}

function chatAccepted()
{
    $(preChatSelector).setStyle('display', 'none');
    $(inChatSelector).setStyle('display', 'block');
	
    refreshSession(false);
	
    var refreshTime = 1000; // 1 second delay
	
    setTimeout('startRefreshTimer()', refreshTime);
}

function chatOffline()
{
    if(chatSessionActive == 0)
    {
        chatIsOffline = true;
		
        $$(introWrapperSelector).setStyle('display', 'none');
        $(errorWrapperSelector).setStyle('display', 'none');
        $(nameContainerSelector).setStyle('display', 'none');
        $$(continueLayerSelector).setStyle('display', 'none');
		
        $(msgWrapper).setStyle('display', 'block');
        $$(closeWrapperSelector).setStyle('display', 'block');
		
        $(msgWrapper).setHTML(config['offline_msg']);
    }
}

function refreshSession(keepRefreshing)
{
    var options = {
        method: 'get',
        onSuccess: function(response) {
            var data = Json.evaluate(response);
						
            if(chatSessionMdate != data.mdate)
            {
                var sessionTxt = '';
                var lineColor = null;
                var a = 0;
                
                $each(data.session_lines, function (item, index) {
                    if(a < 2)
                    {
                        lineColor = 'system-line';
                    }
                    else
                    {
                        if(item.indexOf(chatClientName+' (') > -1)
                        {
                            //  Client Line
                            lineColor = 'client-line';
                        }
                        else
                        {
                            //  Operator Line
                            lineColor = 'operator-line';
                        }
                    }
                    
                    sessionTxt += '<span class="'+lineColor+'">'+item+"</span><br />";

                    a += 1;
                });
							
                $(sessionDisplaySelector).setHTML(sessionTxt);
							
                chatSessionMdate = data.mdate;
							
                //	Keep scroll position at the bottom
                $(sessionDisplaySelector).scrollTop = $(sessionDisplaySelector).scrollHeight - $(sessionDisplaySelector).clientHeight;
            }
						
            if(keepRefreshing)
            {
                startRefreshTimer();
            }
        },
        headers: {
            'X-Request': 'JSON'
        }
    };
    
    var uriVars = 'task=refresh_session&s='+chatSessionId+'&t='+$time();
	
    var myXhr = new XHR(options).send(liveChatUri, uriVars);
}

function startRefreshTimer()
{
    var refreshFunc = function () {
        refreshSession(true);
    }
	
    var refreshTime = refreshTimerDelay * 1000; // convert to miliseconds
	
    refreshTimer = refreshFunc.delay(refreshTime);
}

function URLEncode( str ) {       
    var histogram = {}, histogram_r = {}, code = 0, tmp_arr = [];
    var ret = str.toString();
    
    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };
    
    // The histogram is identical to the one in urldecode.
    histogram['!']   = '%21';
    histogram['%20'] = '+';
    
    // Begin with encodeURIComponent, which most resembles PHP's encoding functions
    ret = encodeURIComponent(ret);
    
    for (search in histogram) {
        replace = histogram[search];
        ret = replacer(search, replace, ret) // Custom replace. No regexing
    }
    
    // Uppercase for full PHP compatibility
    return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
        return "%"+m2.toUpperCase();
    });
    
    return ret;
}
