/**
* @package JLive! Chat
* @version 3.1
* @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 processingSomething = false;

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

	if(screen.availWidth && screen.availHeight) {
	   w = screen.availWidth;
	   h = screen.availHeight;
	}
	
	var popW = 250; 
	var popH = 202;
	
	if(window.webkit)
	{
		popW = 260;
		popH = 210;
	}
	
	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 = $('pre-chat');
	inChat = $('in-chat');
	
	msgInput = $('msg-input');
	sessionDisplay = $('session-content-display');
	name = $('name');
	errorLayer = $('error-wrapper');
	introLayer = $$('.intro-wrapper');
	msgLayer = $('msg-wrapper');
	nameLayer = $('name-container');
	continueLayer = $$('.continue-wrapper');
	closeLayer = $$('p.close-wrapper');
	
	sendBtn = $$('#in-chat .send-button');
	
	continueBtn = continueLayer.getElement('input[type=image]');
	nameInput = nameLayer.getElement('input[type=text]');
	closeBtn = closeLayer.getElement('input[type=image]');
	
	if(nameInput)
	{
		nameInput.addEvent('keydown', function (event) {
			if(event.keyCode == 13)
			{
				//	user pressed enter on the keyboard
				initChatSession();
			}
		});
	}
	
	if(msgInput)
	{
		msgInput.addEvent('keydown', function (event) {
			if(event.keyCode == 13)
			{
				//	user pressed enter on the keyboard
				sendMsg();
			}
		});
	}
	
	if(window.ie)
	{
		sessionDisplay.setStyle('width', '88%');
		msgInput.setStyle('width', '88%');
		
		sessionDisplay.setProperty('rows', '10');
	}
	else
	{
		sessionDisplay.setStyle('width', '91%');
		msgInput.setStyle('width', '91%');
	}
}

function sendMsg()
{
	var sendTxt = msgInput.getValue();
	
	var options = { 
					method: 'get', 
					onSuccess: function(response) {	
						//	Clear Box
						msgInput.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);
}

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

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) {
									errorLayer.setText(item+"\n");
								});
							}
							else
							{
								//	Waiting for Operator Response
								chatClientName = name.getProperty('value');
								continueBtn.removeEvents('click');
								nameInput.removeEvents('keydown');
								
								errorLayer.setText('Connecting, please wait...');
								
								chatSessionId = data.chat_session_id;
								
								startOfflineTimer();
								checkIfChatAccepted();
							}
						}, 
						headers: {'X-Request': 'JSON'}
						};
		
		var uriVars = 'task=start_session&name='+URLEncode(name.getProperty('value'))+'&t='+$time();
		
		var myXhr = new XHR(options).send(liveChatUri, uriVars);
	}
}

function startOfflineTimer()
{
	var options = {
			method: 'get', 
			onSuccess: function(response) {
				var data = Json.evaluate(response);
				
				client = data;
				
				delayInMicroSeconds = client.app_key_data.client_timeout * 1000;
				
				setTimeout('getNewClient()', delayInMicroSeconds);
			}, 
			headers: {'X-Request': 'JSON'}
			};

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

function getNewClient()
{
	if(chatSessionActive == 0)
	{
		var options = {
				method: 'get', 
				onSuccess: function(response) {
					var data = Json.evaluate(response);
					
					if(data != false)
					{
						//	We got a new client successfully
						client = data;
						
						processingSomething = false;
						
						//	Retry request with new client
						initChatSession();
						
						delayInMicroSeconds = client.app_key_data.client_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()
{
	preChat.setStyle('display', 'none');
	inChat.setStyle('display', 'block');
	
	refreshSession(false);
	
	var refreshTime = 1000; // 1 second delay
	
	setTimeout('startRefreshTimer()', refreshTime);
}

function chatOffline()
{
	if(chatSessionActive == 0)
	{
		var options = {
				method: 'get', 
				headers: {'X-Request': 'JSON'}
				};

		var uriVars = 'task=clear_used_clients&t='+$time();
		
		var myXhr = new XHR(options).send(liveChatUri, uriVars);
		
		introLayer.setStyle('display', 'none');
		errorLayer.setStyle('display', 'none');
		nameLayer.setStyle('display', 'none');
		continueLayer.setStyle('display', 'none');
		
		msgLayer.setStyle('display', 'block');
		closeLayer.setStyle('display', 'block');
		
		msgLayer.setHTML(config['offline_msg']);
	}
}

function refreshSession(keepRefreshing)
{
	var sessionDisplay = $('session-content-display');
	
	var options = {
					method: 'get', 
					onSuccess: function(response) {	
						var data = Json.evaluate(response);
						
						if(chatSessionMdate != data.mdate)
						{
							var sessionTxt = '';
							$each(data.session_lines, function (item, index) {
								sessionTxt += item+"\n";
							});
							
							sessionDisplay.setText(sessionTxt);
							chatSessionMdate = data.mdate;
							
							//	Keep scroll position at the bottom
							sessionDisplay.scrollTop = sessionDisplay.scrollHeight - sessionDisplay.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;
}

