// Conversive Communication Handlers for Verbots Online
// Copyright 2005-2006 Conversive, Inc.
// Version 0.5

// some vars must be set in the config already

//startup vars
var startupTickCount = 0;
//internal vars
var req = null;
var reqTo = null;
var sendQueue = new Array();
//interval references
var intStartup = null;
var intSendMessage = null;

//optional settings:
//logOnTop = true;
//logLastOnly = true;

//////////////////////////
///////  "Public"  ///////
//////////////////////////

//init
modernizeJS();
var searchData = getSearchData();
intSendMessage = setInterval("intSendMessageTick(this)", 100);
intStartup = setInterval("intStartupTick(this)", 100);

function intStartupTick(sender)
{
	sender.startupTickCount++;
	if(document.flashReady == 1 || sender.startupTickCount > 50)
	{
		var startupText = searchData["input"];
		if(startupText == null)
			startupText = "_startup";
		getReplySilent(startupText);
		clearInterval(sender.intStartup);
	}
}

function getReply(inputText)
{
	if(logLastOnly)
		setOutput("");
			
	if(inputText != "")
	{
		if(userDisplayName == null)
			userDisplayName = "You";
		addOutput("<span class=\"userName\">" + userDisplayName + ": </span><span class=\"userText\">" + inputText + "</span><br />\n");
	}
	else
	{
		inputText = "_blank";
	}
	
	engineSendMessage(inputText);
}

function getReplySilent(inputText)
{
	if(logLastOnly)
		setOutput("");
	if(inputText != "")
		engineSendMessage(inputText);
}

/////////////////
//// TOOLBOX ////
/////////////////
function modernizeJS()
{
	if(typeof(Array.prototype.push) == null)
	{
		Array.prototype.push = function()
		{
			var A_p = 0;
			for(A_p = 0; A_p < arguments.length; A_p++)
				this[this.length] = arguments[A_p];

			return this.length;
		}
	}

	if(typeof(Array.prototype.shift) == null)
	{
		Array.prototype.shift = function()
		{
			var A_s = 0;
			var response = this[0];
			for(A_s = 0; A_s < this.length-1; A_s++)
				this[A_s] = this[A_s + 1];

			this.length--;
			return response;
		}
	}
	
	if(typeof(String.prototype.split) == null)
	{
		String.prototype.split = function(delimiter)
		{
			var remainder = this.toString();
			var i = remainder.indexOf(delimiter);
			var result = new Array();
			while(i != -1)
			{
				result.push(remainder.substring(i));
				if(i < remainder.length - 1)
					remainder = remainder.substring(i+1);
				else
					remainder = "";
				i = remainder.indexOf(delimiter);
			}
			return result;
		}
	}//end if split undefined
}//modernizeJS()

function getSearchData()
{
	//returns an 'associative array' with lowercase keys from window.location.search
    var data = new Object();
    var s = window.location.search;
    if(s.length > 1)
    {
        s = s.substring(1, s.length);//remove leading '?'
        var pairs = s.split("&");
        for(var i = 0; i < pairs.length; i++)
        {
            var nv = pairs[i].toString().split("=");
            if(nv.length == 2)
                data[unescape(nv[0]).toLowerCase()] = unescape(nv[1]);
        }
    }
    return data;
}//getSearchData()

function URLencode(s)
{
	if(s != null)
		return encodeURIComponent(s).replace(/\+/g, '%2B').replace(/\"/g,'%22').replace(/\'/g, '%27');
	else
		return "";
}

function URLdecode(s) {
	if(s != null)
		return unescape(s.replace(/\+/g, " ").replace(/%2B/g, "+").replace(/%22/g, "\"").replace(/%27/g, "'"));
	else
		return "";
}

function responseTextToArray(text)
{
	var retArray = new Array();
	var fields = text.split("&");
	for(var x in fields)
	{
		var field = String(fields[x]);
		var nameval = field.split("=");
		retArray[URLdecode(nameval[0])] =  URLdecode(nameval[1]);
	}
	return retArray;
}//responseTextToArray(text)

function setOutput(s)
{
	var outdiv = document.getElementById(elOutput);
	//fix formatting
	s = s.replace(/\r\n/g, '<br />');
	outdiv.innerHTML = s + "<hr style='display:none;' />";
}

function addOutput(s)
{
	var outdiv = document.getElementById(elOutput);
	//fix formatting
	s = s.replace(/\r\n/g, '<br />');
	if(logOnTop)
	{
		outdiv.innerHTML = s + outdiv.innerHTML;
		outdiv.scrollTop = 0;
	}
	else
	{
		outdiv.innerHTML = outdiv.innerHTML + s;
		outdiv.scrollTop = outdiv.scrollHeight;
	}
}

function trace(s)
{
	var tracediv = document.getElementById(elTrace);
	var d = new Date();
	var stDate = d.getHours() + ":" + d.getMinutes() + ":" + d.getSeconds();
	tracediv.innerHTML = tracediv.innerHTML + "(" + stDate + ") " + s + "<br />\n";
	tracediv.scrollTop = 50000;
}

function setInnerHTML(elementId, htmlText)
{
	if(document.getElementById != null)
	{
		var el = document.getElementById(elementId);
		if(document.createRange != null)
		{
			var rng = document.createRange();
			if(rng.createContextualFragment != null)
			{
				//primarily for Mozilla
				rng.setStartBefore(el);
				var htmlFrag = rng.createContextualFragment(htmlText);
				while(el.hasChildNodes())
					el.removeChild(el.lastChild);
				el.appendChild(htmlFrag);
			}
			else
			{
				//primarily for Opera
				//alert("el: " + el + " el.innerHTML: " + el.innerHTML);
				el.innerHTML = htmlText;
				//alert("el.innerHTML: " + el.innerHTML);
			}
		}
		else
		{
			//primarily for IE
			el.innerHTML = htmlText;
		}
	}
}

////////////////////////////
//// Interrupt Handlers ////
////////////////////////////
//sends outbound messages as the connection comes available
function intSendMessageTick(sender)
{
	if(sender.sendQueue.length != 0 && sender.req == null)
	{
		var m = sender.sendQueue.shift();//shift=dequeue
		sender.query(m);
	}
}

/////////////////////////
///// COMMUNICATION /////
/////////////////////////
function query(data)
{
	if (window.XMLHttpRequest)
        req = new XMLHttpRequest();
	else if (window.ActiveXObject)
        req = new ActiveXObject("Microsoft.XMLHTTP");
	
	if(req != null)
	{
		req.onreadystatechange = reqStateChange;
		req.open("POST", urlEngine, true);
		req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		var datastr = "";
		for(var x in data)
			datastr += URLencode(x)+"="+URLencode(data[x])+"&";
		req.send(datastr);
	}
}//query(data, callback)

function reqStateChange()
{
	if(req != null && req.readyState == 4)
	{
		//0 = OK running locally
		//200 = OK
		//304 = Not Modified		
		if(req.status == 0 || req.status == 200 || req.status == 304)
		{
			if(req.responseText != null)
			{
				processResponse(responseTextToArray(req.responseText));
			}
		}
		else//change to only listen for 4xx?
		{
			processError(reqTo, req.status, req.statusText);
		}

		reqTo = null;
		req = null;//ready to handle another request
	}
}//processResponse()

function processResponse(resp)
{
	if(resp.answer != null)
	{
		addOutput("<span class=\"engineName\">" + engineName + ": </span><span class=\"engineText\">" + resp.answer + "</span><br />");
	}
	if(resp.cmd != 'undefined' && resp.cmd != undefined && resp.cmd != null && resp.cmd != "" && elCmdDiv != null)
	{
		setInnerHTML(elCmdDiv, "<hr style='display:none;' />"+resp.cmd);
	}
	if(resp.voiceurl != null)
		setVoiceUrl(resp.voiceurl);
	if(resp.answerext != null)
		handleExts(resp.answerext);
}//processResponseArray(resp)

function processError(reqTo, status, statusText)
{
	//alert("error: " + reqTo + ", " + status + ", " + statusText);
}

//////////////////////
///////  Engine //////
//////////////////////
function engineSendMessage(inputText)
{	
	var m = new Array();
	m["input"] = inputText;
	m["botcode"] = botCode;
	if(voice != null)
		m["voice"] = voice;
	sendQueue.push(m);
}

function playAnimation(animationName) {
    var flashVoicePlayer = getFlashObject();
    if (flashVoicePlayer) {
        flashVoicePlayer.SetVariable('animation', animationName);
    }
}

function getFlashObject() 
{
    var flashVoicePlayer = null;
    if(elFlashVoicePlayer != null)
	{
		flashVoicePlayer = document[elFlashVoicePlayer];
		if(flashVoicePlayer == null)//if that didn't work, try it the old IE way
			flashVoicePlayer = window[elFlashVoicePlayer];
        if (flashVoicePlayer == null)               flashVoicePlayer = document.getElementById(elFlashVoicePlayer);
	}
	return flashVoicePlayer;
}

function setVoiceUrl(voiceurl)
{
	if(elFlashVoicePlayer != null)
	{
		var flashVoicePlayer = document[elFlashVoicePlayer];
		if(flashVoicePlayer == null)//if that didn't work, try it the old IE way
			flashVoicePlayer = window[elFlashVoicePlayer];
		if(flashVoicePlayer != null)
			flashVoicePlayer.SetVariable('voiceurl', voiceurl);
	}
}

///////////////////
/////// EXT ///////
///////////////////
function handleExts(exts)
{
	var extArr = exts.split("\n");
	for(var i = 0; i < extArr.length; i++)
		handleExt(extArr[i]);
}

function handleExt(ext)
{
	var command = ext.replace(/^\s*|\s*$/g,"");
	var args = "";
	var pos = ext.indexOf(":");
	if(pos != -1)
	{
		command = ext.substring(0, pos).replace(/^\s*|\s*$/g,"");
		if(pos < ext.length)
			args = ext.substring(pos+1).replace(/^\s*|\s*$/g,"");
	}

	command = command.toUpperCase();
	switch(command)
	{
		case "JAVASCRIPT":
			eval(args);
			break;
		case "OPENMAIN":
			window.open(args, "main");
			addOutput("[<a href=\""+args+"\" target=\"main\">link</a>]<br />");
			break;
		case "OPENBLANK":
			window.open(args, "_blank");
			addOutput("[<a href=\""+args+"\" target=\"_blank\">link</a>]<br />");
			break;
		case "POPUPWIN":
			var winArray = args.split(",");
			var urlWin = winArray[0];
			var winNameWin = winArray[1];
			var wWin = winArray[2];
			var hWin = winArray[3];
			var toolbarWin = 0;
			var locationWin = 0;
			var directoriesWin = 0;
			var statusWin = 0;
			var menubarWin = 0;
			var scrollbarsWin = winArray[4];
			var resizableWin = 0;
			var top = (screen.height/2)-(hWin/2);
			var left = (screen.width/2)-(wWin/2);
			
			var myWin;
			if(!myWin || myWin.closed)
			{
				myWin = window.open(urlWin, winNameWin, "width="+wWin+",height="+hWin+",toolbar="+toolbarWin+",location="+locationWin+",directories="+directoriesWin+",status="+statusWin+",menubar="+menubarWin+",scrollbars="+scrollbarsWin+",resizable="+resizableWin+",top="+top+",left="+left);
			}
			else
			{
				myWin.focus();
			};			
			break;
		case "HTMLMENU":
			setInnerHTML(elMenu, args);
			break;
		case "LOADHTMLMENU":
			var m = new Array();
			m["__to__"] = "loadhtmlmenu";
			m["url"] = args;
			sendQueue.push(m);
			break;
		case "HTMLCONTENT":
			if(!contentIsModal)
				setInnerHTML(elContent, args);
			break;
		case "LOADHTMLCONTENT":
			var m = new Array();
			m["__to__"] = "loadhtmlcontent";
			m["url"] = args;	
			sendQueue.push(m);
			break;
		default:
			break;
	}//switch
}
