var displayElement 		= null;
var screenElement 		= null;
var promptElement 		= null;
var spinnerElement 		= null;
var preInputArea 		= null;
var inputArea 			= null;
var postInputArea 		= null;
var bottomlineElement 		= null;
var leftOfCursorElement 	= null;
var cursorElement 		= null;
var rightOfCursorElement 	= null;
var pageAlertElement		= null;
var inputBuffer 		= '';
var cursorPosition 		= 0;
var cursorBlinkThreadId 	= false;
var multilineMode 		= false;
var specialCommandHandler 	= false;
var specialCommandHandlerCode 	= false;
var passwordInputMode=false;
var historyArray 		= [];
var historyIndex 		= 0;
var clientSideCommandsEnabled 	= true;
var promptText 			= "guest@nulog:/$&nbsp;";
var sessionId 			= '_0bfafd248b8269e04a42133503dad042';
var eatIt 			= false; // eat next character input
var spinnerCharacters 		= ['-', '\\', '|', '/'];
var spinnerCharacterIndex 	= 0;
var spinnerThreadId 		= false;
var stickyState 		= []; // for "sticky" modifier keys
	stickyState.CTRL=false;
	stickyState.ALT=false;
var xmlhttp 			= false;
var interpreter 		= "http://www.nulog.com/news/wp-content/themes/wordpress-cli/interpret.php";
var requestId 			= 0;
var firstCommand 		= true;
var waitingForServer 		= false;
var savedDisplayHTML		= false;
var cursorState 		= 1;
var scrLock	 		= false;
var targetHeight 		= false;
var scrollerThreadId 		= false;
var waitingAtPage 		= false;
var paging 			= true; // there's no option for this, but it's possible. Make false for no "--More--"
var initialScreenOffsetHeight 	= false;
var scrollStep 			= 24;


var ENTER 			= String.fromCharCode(13);
var DOUBLE_QUOTE 		= String.fromCharCode(34);

function cursorBlink(){
	cursorState = 1 - cursorState;
	if (cursorState == 1){
		cursorElement.style.color = 'rgb(200,200,200)';
		cursorElement.style.backgroundColor = 'rgb(32,32,32)';
	}else{
		cursorElement.style.color = 'rgb(32,32,32)';
		cursorElement.style.backgroundColor = 'rgb(200,200,200)';
	}
}

function initializeCLI(){
	screenElement 		= document.getElementById('scr');
	displayElement 		= document.getElementById('display');
	spinnerElement 		= document.getElementById('spinnerdiv');
	promptElement 		= document.getElementById('prompt');
	bottomlineElement 	= document.getElementById('bottomline');
	leftOfCursorElement 	= document.getElementById('lcommand');
	cursorElement 		= document.getElementById('undercsr');
	rightOfCursorElement 	= document.getElementById('rcommand');
	pageAlertElement	= document.getElementById('pagealert');
		if (!cursorBlinkThreadId){
		cursorBlinkThreadId = setInterval(cursorBlink,1000);
	}
		var frm 		= document.forms[0];
	inputArea 		= frm.inputArea;
	preInputArea 		= frm.preInputArea;
	postInputArea 		= frm.postInputArea;
	promptElement.innerHTML = promptText;
	screenElement.scrollTop = 1;
	inputArea.focus();
}

/**** start from http://snippets.dzone.com/posts/show/701 ****/
// Removes leading whitespaces
function ltrim( value ) {
	if (value){
		var re = /\s*((\S+\s*)*)/;
		return value.replace(re, "$1");
	}
	return '';
}

// Removes ending whitespaces
function rtrim( value ) {
	if (value){
		var re = /((\s*\S+)*)\s*/;
		return value.replace(re, "$1");
	}
	return '';
}

// Removes leading and ending whitespaces
function trim( value ) {
	if (value){
		return ltrim(rtrim(value));
	}
	return '';
}
/**** end from http://snippets.dzone.com/posts/show/701 ****/

function prepareInputForDisplay(str){
	str = str.replace(/&/g,'&amp;'); // keep first
	str = str.replace(/</g,'&lt;');
	str = str.replace(/>/g,'&gt;');
	str = str.replace(/  /g,' &nbsp;');
	str = str.replace(/\x0D/g,'&nbsp;<br />');
	return str;
}

function updateInputDisplay(){
	var left = '', underCursor = ' ', right = '';
	if (trim(inputBuffer) === ''){
		inputBuffer='';
	}
	if (cursorPosition < 0){
		cursorPosition = 0;
	}
	if (cursorPosition > inputBuffer.length){
		cursorPosition = inputBuffer.length;
	}
	if (cursorPosition > 0){
		left = inputBuffer.substr(0, cursorPosition);
	}
	if (cursorPosition < inputBuffer.length){
		underCursor = inputBuffer.substr(cursorPosition, 1);
	}
	if (inputBuffer.length - cursorPosition > 1){
		right = inputBuffer.substr(cursorPosition + 1, inputBuffer.length-cursorPosition-1);
	}

	leftOfCursorElement.innerHTML = prepareInputForDisplay(left);
	cursorElement.innerHTML = prepareInputForDisplay(underCursor);
	if (underCursor == ' '){
		cursorElement.innerHTML = '&nbsp;';
	}
	rightOfCursorElement.innerHTML = prepareInputForDisplay(right);
	promptElement.innerHTML=promptText;
	return;
}

function clearInputBuffer(){
	inputArea.value = '';
	inputBuffer = '';
	cursorPosition = 0;
	updateInputDisplay();
}

function setPromptActive(active){
	if (active){
		bottomlineElement.style.visibility = 'visible';
		inputArea.focus();
		return true;
	}else{
		bottomlineElement.style.visibility = 'hidden';
		return false;
	}
}

function pageAlert(active){
	waitingAtPage = active;
	if (active){
		pageAlertElement.style.visibility = 'visible';
	}else{
		pageAlertElement.style.visibility = 'hidden';
	}
}

function jumpToBottom(){
	screenElement.scrollTop = screenElement.scrollHeight - screenElement.offsetHeight;
	inputArea.focus();
}

function jumpToTop(){
	screenElement.scrollTop = screenElement.offsetHeight;
	inputArea.focus();
}

function backgroundScroller(){
//	topofscreentotopofviewport	= screenElement.scrollTop;
// +	viewportheight			= screenElement.offsetHeight;
// <=	fullheight			= screenElement.scrollHeight;
	
	if (scrollStep > 0 && (screenElement.scrollHeight - screenElement.offsetHeight > screenElement.scrollTop + scrollStep)	){
		if (!targetHeight	|| initialScreenOffsetHeight != screenElement.offsetHeight){
			initialScreenOffsetHeight = screenElement.offsetHeight;
			if (paging){ 
				targetHeight = Math.min(screenElement.scrollTop+screenElement.offsetHeight-40, screenElement.scrollHeight);
			}else{
				targetHeight = screenElement.scrollHeight;
			}
		}
		if (screenElement.scrollTop < targetHeight){
			screenElement.scrollTop += scrollStep;
			scrollerThreadId = setTimeout(backgroundScroller, 10);
			return;
		}else{
			targetHeight = false;
			scrollerThreadId = false;
			pageAlert(true);
		}
	}else{
		screenElement.scrollTop = screenElement.scrollHeight - screenElement.offsetHeight;
		targetHeight = false;
		scrollerThreadId = false;
		pageAlert(false);
		jumpToBottom();
	}
}

function scroller(){
	initialScreenOffsetHeight = screenElement.offsetHeight;
	if (!waitingAtPage && !scrollerThreadId){ 
		scrollerThreadId = setTimeout(backgroundScroller, 10);
	}
	return;
}

function appendToDisplay(html){
	displayElement.innerHTML += html;
	scroller();
}

function displayFromXML(xdisplayData){
	var html = '';
	for(var i = 0; i < xdisplayData.length; i++){
		if (xdisplayData[i].firstChild){
			html += xdisplayData[i].firstChild.data;
		}
	}
	appendToDisplay(html);
}

function initializeSpecialCommandHandler(xspecialCommandHandler){
	for(var i = 0; i < xspecialCommandHandler.length; i++){
		if (xspecialCommandHandler[i].firstChild){
			specialCommandHandlerCode += xspecialCommandHandler[i].firstChild.data;
		}
	}
	if (specialCommandHandlerCode == '0'){
		specialCommandHandler = false;
		specialCommandHandlerCode = false;
	}else{
		specialCommandHandler = function(input){
			eval(specialCommandHandlerCode);
			return false;
		};
		specialCommandHandler('__INIT__');
	}
}

function handleServerXML(xml){
	if (!xml){
		return false;
	}
	var xmlDocumentElement = xml.documentElement;
	if (!xmlDocumentElement){
		return false;
	}
/* 
	//for some weird-ass reason some people's servers are responding with empty responseId's
	xresponseId = xmlDocumentElement.getElementsByTagName('responseId');
	if (xresponseId.length == 0 || (xresponseId[0].getAttribute('value') != requestId)){ 
		// to avoid confusion with slow-arriving results
		alert('Out-of-order or malformed server response');
		return false;
	}
*/
	var xmultilineMode = xmlDocumentElement.getElementsByTagName('multiline');
	if (xmultilineMode.length > 0 && xmultilineMode[0].getAttribute('value') == "1"){
		multilineMode = true;
	}
	
	var xclientSideCommandsEnabled = xmlDocumentElement.getElementsByTagName('clientsidecommands');
	if (xclientSideCommandsEnabled.length > 0	&& xclientSideCommandsEnabled[0].getAttribute('value') == "off"){
		clientSideCommandsEnabled = false;
	}else{
		clientSideCommandsEnabled = true;
	}
	
	var xcommandlineData = xmlDocumentElement.getElementsByTagName('commandline');
	if (xcommandlineData.length > 0){
		inputBuffer = xcommandlineData[0].firstChild.data;
		cursorPosition = inputBuffer.length;
	}else{
		inputBuffer = '';
		cursorPosition = 0;
	}

	var xprompt = xmlDocumentElement.getElementsByTagName('prompt');
	if (xprompt && xprompt[0]){
		promptText = xprompt[0].firstChild.data;
	}
	
	var xdisplayData = xmlDocumentElement.getElementsByTagName('display');
	if (xdisplayData.length > 0){
		displayFromXML(xdisplayData);
	}
	
	var xspecialCommandHandler = xmlDocumentElement.getElementsByTagName('specialcommandhandler');
	if (xspecialCommandHandler.length > 0){
		initializeSpecialCommandHandler(xspecialCommandHandler);
	}
	
	updateInputDisplay();
	return true;
}

function createXMLHTTP(){
	/* I stole this from somebody a long time ago. Sorry, somebody. */
        /*@cc_on @*/
        /*@if (@_jscript_version >= 5)
        try {
        	xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
        } catch (e) {
        	try {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		} catch (E) {
			xmlhttp = false;
		}
	}
  @end @*/
  if (!xmlhttp && typeof XMLHttpRequest!='undefined') {
		xmlhttp = new XMLHttpRequest();
  }
}

function prepareURI(what){
	what = encodeURI(what);
	what = what.replace(/&amp;/g,'%26');
	what = what.replace(/&lt;/g,'<');
	return what;
}

function busySpinner(active){
	if (active){
		spinnerCharacterIndex = (++spinnerCharacterIndex) % spinnerCharacters.length;
		spinnerElement.innerHTML = spinnerCharacters[spinnerCharacterIndex];
		if (!spinnerThreadId){
			spinnerElement.style.display = 'block';
			spinnerThreadId = setInterval('busySpinner(true);', 100);
		}
	}else{
		spinnerElement.style.display = 'none';
		clearInterval(spinnerThreadId);
		spinnerThreadId = false;
	}
}

function executeCommand(getCommand, postData){
	multilineMode = false;
	if (!xmlhttp){
		createXMLHTTP();
	}
	if (!xmlhttp){
		alert('Darn.');
		return false;
	}
	if (firstCommand){
		firstCommand = false;
	}else{
		requestId = Math.round(Math.random() * 100000);
	}
	var url = interpreter + "?" + prepareURI(getCommand) + "&requestId=" + requestId +"&CSID="+sessionId;
	if (postData){
		xmlhttp.open("POST", url, true);
		xmlhttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	}else{
		xmlhttp.open("GET", url, true);
	}
	xmlhttp.onreadystatechange = function(){
		var xstate = xmlhttp.readyState;
		if (xstate == 4 && xmlhttp.status == 200){
			waitingForServer = false;
			busySpinner(false);
			handleServerXML(xmlhttp.responseXML);
			scroller();
			setPromptActive(true);
			return true;
		}
		return false;
	};
	waitingForServer = true;
	busySpinner(true);
	if (postData){
		xmlhttp.send(prepareURI(postData));
	}else{
		xmlhttp.send("");
	}
	return false;
}

function processInputBuffer(input){
	clearInputBuffer();
	
	/* redisplay command in display div */
	var inputForDisplay = input;
	if (passwordInputMode){
		inputForDisplay = "";
		for(var i = 0; i < input.length; i++){
			inputForDisplay += '*';
		}
	}
	appendToDisplay("<p>" + promptText + prepareInputForDisplay(inputForDisplay) + '</p>');

	input = trim(input);

	/* for weird local-only interaction, maybe editor */
	if (specialCommandHandler){
		specialCommandHandler(input);
		setPromptActive(true);
		return false;
	}
			
	if (clientSideCommandsEnabled){
			/* add to history */
			if (input !== ''){
				historyArray[historyArray.length] = input;
				historyIndex = historyArray.length;
			}
			var possibleCommand = input.toLowerCase();
			/*LOCALLY EVALUATED COMMANDS */
		//CLS
			if (possibleCommand == 'cls' || possibleCommand == 'clear'){
				displayElement.innerHTML='';
				return false;
			}
		//ADMIN
			if (possibleCommand == 'admin' || possibleCommand == 'su'){
				document.location.href = "http://www.nulog.com/news/wp-admin/index.php";
				return false;
			}
				//LOGIN
			if (possibleCommand == 'login'){
				document.location.href = "http://www.nulog.com/news/wp-login.php";
				return false;
			}
				//STARTX
			if (possibleCommand == 'gui'|| possibleCommand == 'startx'){
						alert('No GUI link configured!');
						return false;
			}
	/* END LOCALLY EVALUATED COMMANDS */
	}
	setPromptActive(false);
	executeCommand("c=" + input, false);
	return false;
}

function scrollPage(mul){
	screenElement.scrollTop += mul * screenElement.offsetHeight;
	return false;	
}

function scrollLine(mul){
	screenElement.scrollTop += mul * scrollStep;
	return false;	
}

function showpost(which){
	if (which == 'latest'){
		executeCommand('c=latest', false);
	}else{
		executeCommand('c=cat ' + which, false);
	}
}

function ls(which){
	executeCommand('c=ls ' + which, false);
}

function help(what){
	executeCommand('c=help ' + what, false);
}

function autosearch(which){
	executeCommand('c=grep ' + which, false);
}

function showcomments(){
	executeCommand('c=comments', false);
}

function showcat(which){
	executeCommand('c=category ' + which, false);
}

function telnet(which){
	executeCommand('c=telnet ' + which, false);
}

function setcl(addend){
  inputBuffer += addend;
  cursorPosition = inputBuffer.length;
	//updateInputDisplay();
	processInputBuffer(inputBuffer);
}

function stickyModifierKeys(key, evt){
	if (evt !== null && evt.type == 'keydown'){
		return false;
	}
	stickyState[key] = !stickyState[key];
	document.getElementById(key + 'indicator').style.display=(stickyState[key] ? 'inline' : 'none');
	return true;
}

function handleKeyEvent(e){
	var rval=false;
	var left, right, character = false, keyName=false, keyCode=false;
	if (waitingForServer){ 
		return rval; 
	}// waiting on a response from server
	if (!e && window.event){ //i.e. if it's MSIE
		e = window.event;
		inputArea.value = '';
	}
	if( !e ) return true;
	if( typeof( e.keyCode ) == 'number'  ) {
		keyCode = e.keyCode;
	} else if( typeof( e.which ) == 'number' ) {
		keyCode = e.which;
	} else if( typeof( e.charCode ) == 'number'  ) {
		keyCode = e.charCode;
	} else { /*damn*/
		return true;
	}
	if (inputBuffer == ENTER){ 
		inputBuffer = ''; 
	}//bah, i have no idea
	if(navigator.appVersion.indexOf('AppleWebKit') > 0){
		//alert(keyCode+' : '+keycodes[keyCode]);
		if(e.type=='keyup' && keycodes[keyCode] && keycodes[keyCode].length == 1){
			character = String.fromCharCode(e.charCode);
		}else if(!keycodes[keyCode]){ // for debugging
			alert (keyCode);
		}
	}else{
		if (inputArea.value){
			character = inputArea.value.charAt(0);
		}
	}
	if (inputArea.value){
		inputArea.value = inputArea.value.substr(1);//remove first character, rest for later
	}
	if (waitingAtPage){
		if (e.type == 'keydown'){
			return rval;
		} 
		pageAlert(false);
		scroller();
		return rval;
	}
	if (keyCode == 9){// tab
		if (e.shiftKey){
			postInputArea.focus();
		}else{
			preInputArea.focus();
		}
	}
	if (! (stickyState.CTRL || stickyState.ALT)){	
		if ((character.length == 1) && e &&	(e.keyCode != 13)){ // if it's a regular key
			if (eatIt){
				character = '';
				eatIt = false;
			}
			left = inputBuffer.substr(0,cursorPosition);
			right = inputBuffer.substr(cursorPosition, inputBuffer.length-cursorPosition);
			inputBuffer = left + character + right;
			cursorPosition++;
			updateInputDisplay();
		}
	}
	if (multilineMode){ 
		scroller();
	}
	if (character){
		keyName = character;
	}else if (keycodes[keyCode]){ // in keycodes.js -- is named.
		keyName = keycodes[keyCode];
	}else{
		return rval;
	}
	if (keyName == 'SHIFT'){
		return rval;
	}
	if (keyName == 'ALT' ||	keyName == 'CTRL'){
		stickyModifierKeys(keyName, e);
		return rval;
	}		
	if (e && (e.type == 'keyup')){
		return rval;
	}
	if (e && e.shiftKey){
		keyName = 'SHIFT_' + keyName;
	}
	if (stickyState.CTRL || stickyState.ALT){
		eatIt = true;
		character = '';
	}
	if ((e && e.ctrlKey) || stickyState.CTRL){
		e.returnValue=false;
		keyName = 'CTRL_' + keyName;
		stickyModifierKeys('CTRL', null);
	}
	if ((e && e.altKey) || stickyState.ALT){
		e.returnValue=false;
		keyName='ALT_' + keyName;
		stickyModifierKeys('ALT', null);
	}
	if (keyName == 'BACKSPACE'){
		e.returnValue=false;
		if (cursorPosition > 0){
			inputArea.focus();
			left = inputBuffer.substr(0, cursorPosition - 1);
			right = inputBuffer.substr(cursorPosition, inputBuffer.length - cursorPosition);
			inputBuffer = left + right;
			cursorPosition--;
			updateInputDisplay();
		}
		return false;
	}
	if (keyName == 'DEL' || keyName == 'SHIFT_BACKSPACE'){
		e.returnValue=false;
		if (cursorPosition < inputBuffer.length){
			left = inputBuffer.substr(0, cursorPosition);
			right = inputBuffer.substr(cursorPosition + 1, inputBuffer.length - cursorPosition - 1);
			inputBuffer = left + right;
			updateInputDisplay();
		}
		return rval;
	}
	if (keyName == 'CTRL_c'){
		if (specialCommandHandler){
			specialCommandHandler('__CANCEL__');
		}else{
			executeCommand('cancel=1', false);
		}
		clearInputBuffer();
		return rval;
	}
	if ((keyName == 'LEFT') && (cursorPosition > 0)){
		cursorPosition--;
		updateInputDisplay();
		e.returnValue=false;
		return rval;
	}		
	if ((keyName == 'RIGHT') && (cursorPosition < inputBuffer.length)){
		cursorPosition++;
		updateInputDisplay();
		e.returnValue=false;
		return rval;
	}		
	if (multilineMode){
		if (keyName == 'CTRL_x'){ // end multilineMode input
			if (specialCommandHandler){
				specialCommandHandler('__EXIT__');
			}else{
				executeCommand('c=','p=' + prepareURI(inputBuffer));
			}
			clearInputBuffer();
			return rval;
		}
		if (keyName == 'UP'){
			if (inputBuffer.charCodeAt(cursorPosition) == 13){
				 cursorPosition++;
			}
			var previousNewline = inputBuffer.lastIndexOf(ENTER, cursorPosition - 1);
			var previousPreviousNewline = inputBuffer.lastIndexOf(ENTER, previousNewline - 1);
			if (previousNewline < 0){
				previousNewline = 0; previousPreviousNewline = 0;
			}
			if (previousPreviousNewline < 0){
				previousPreviousNewline = 0;
			}
			cursorPosition = previousPreviousNewline + cursorPosition - previousNewline;
			if (cursorPosition > previousNewline){
				cursorPosition = previousNewline - 1;
			}
			updateInputDisplay();
			return rval;
		}
		if (keyName == 'DOWN'){
			if (inputBuffer.charCodeAt(cursorPosition) == 13){
				cursorPosition--;
			}
			var previousNewline = Math.max(0,inputBuffer.lastIndexOf(ENTER, cursorPosition - 1));
			var nextNewline = inputBuffer.indexOf(ENTER, cursorPosition + 1);
			var nextNextNewline = inputBuffer.indexOf(ENTER, nextNewline + 1);
			if (nextNewline < 0){
				nextNewline = inputBuffer.length; nextNextNewline = nextNewline;
			}
			if (nextNextNewline < 0){
				nextNextNewline = inputBuffer.length;
			}
			cursorPosition = nextNewline + cursorPosition - previousNewline;
			if (cursorPosition > nextNextNewline){
				cursorPosition = nextNextNewline;
			}
			updateInputDisplay();
			return rval;
		}
		if (keyName == 'ENTER' || keyCode == 13){
			left = inputBuffer.substr(0,cursorPosition);
			right = inputBuffer.substr(cursorPosition);
			inputBuffer = left + ENTER + right; 
			cursorPosition++;
			updateInputDisplay();
			return rval;
		}
		if (keyName == 'CTRL_a' || keyName == 'HOME'){
			if (inputBuffer.charCodeAt(cursorPosition) == 13){
				cursorPosition--;
			}
			var ocursorPosition = cursorPosition;
			cursorPosition = inputBuffer.lastIndexOf(ENTER, cursorPosition) + 1;
			if (cursorPosition >= ocursorPosition){
				cursorPosition = 0;
			}
			updateInputDisplay();
			return rval;
		}
		if (keyName == 'CTRL_e' || keyName == 'END'){
			if (inputBuffer.charCodeAt(cursorPosition) == 13){
				cursorPosition++;
			}
			var ocursorPosition = cursorPosition;
			cursorPosition = inputBuffer.indexOf(ENTER, cursorPosition);
			if (cursorPosition <= ocursorPosition){
				cursorPosition=inputBuffer.length;
			}
			updateInputDisplay();
			return rval;
		}
		if (keyName == 'TAB'){
			left = inputBuffer.substr(0,cursorPosition);
			right = inputBuffer.substr(cursorPosition);
			inputBuffer = left + '    ' + right;  // 4 spaces 
			cursorPosition += 4;
			updateInputDisplay();
			return rval;
		}
	}else{ //not multilineMode
		if ((keyName == 'CTRL_a' || keyName == 'HOME') && cursorPosition > 0){
			cursorPosition = 0;
			updateInputDisplay();
			return rval;
		}		
		if ((keyName == 'CTRL_e' || keyName == 'END') && cursorPosition < inputBuffer.length){
			cursorPosition = inputBuffer.length;
			updateInputDisplay();
			return rval;
		}		
		if (keyName == 'CTRL_l'){ // well, maybe some browser catches it
			displayElement.innerHTML='';
			return rval;
		}
		if (keyName == 'SCRLOCK'){
			scrLock = !scrLock;
			document.getElementById('SCRLOCKindicator').style.display=
				(scrLock ? 'inline' : 'none');
		}		
		if (keyName == 'UP' || keyName == 'SHIFT_UP'){
			if(scrLock || keyName == 'SHIFT_UP'){
				scrollLine(-1);
			}else if (historyIndex > 0){
				inputBuffer = historyArray[--historyIndex];
				cursorPosition = inputBuffer.length;
				updateInputDisplay();
				jumpToBottom();
			}
			return rval;
		}
	 	if (keyName == 'DOWN' || keyName == 'SHIFT_DOWN'){
			if(scrLock || keyName == 'SHIFT_DOWN'){
				scrollLine(1);
			}else if (historyIndex < historyArray.length){
				if (historyIndex == historyArray.length - 1){
					historyIndex = historyArray.length;
					clearInputBuffer();
				}else{
					inputBuffer = historyArray[++historyIndex];
				}
				cursorPosition = inputBuffer.length;
				updateInputDisplay();
				jumpToBottom();
			}
			return rval;
		}
		if (keyName == 'PGUP' || keyName == 'CTRL_UP'){
			scrollPage(-1);
			return rval;
		}
		if (keyName == 'PGDN' || keyName == 'CTRL_DOWN'){
			scrollPage(1);
			return rval;
		}
		if (keyName == 'CTRL_HOME'){
			jumpToTop();
			return rval;
		}
		if (keyName == 'CTRL_END'){
			jumpToBottom();
			return rval;
		}
		if (keyName == 'TAB'){
			executeCommand('tc='+inputBuffer, false); // tab completion
			return rval;
		}
		if (keyName == 'SHIFT_TAB'){
			return rval;
		}
		if (keyName == 'ENTER' || keyCode == 13){
			processInputBuffer(inputBuffer);
			return rval;
		}
	}
	if (inputArea.value){
		handleKeyEvent(false);
	}
	return rval;
}

//document.onkeydown=function(event){handleKeyEvent(event)}; 
//document.onkeyup=function(event){handleKeyEvent(event)};
//document.onkeypress=function(event){handleKeyEvent(event)};
if( document.captureEvents && Event.KEYUP ) {
  document.captureEvents( Event.KEYUP );
}
