///////////////////////////////////////////////////////////////////////////////////////
// PHPizabi TRITON 3                                         http://www.phpizabi.net //
///////////////////////////////////////////////////////////////////////////////////////
// Please read the license.txt file before using / modifying this software           //
// Original author:         Claude Desjardins, R - feedback@realitymedias.com        //
//                                                                                   //
// (C) 2005, 2006 Real!ty Medias / PHPizabi / TRITON - All rights reserved           //
///////////////////////////////////////////////////////////////////////////////////////

/* Declarations */
var bufferList = new Array;		// Defines the list of buffers
var selectedItem = null;		// Defines the actually selected item
var buffer = new Array;			// Buffers content array
var initComplete = false;		// Defines if the system has been initialized
var floatInt = 0;				// Floating marker for execution timer
var topicBuffer = new Array;	// Buffer containing topics results
var nicksBuffer = new Array;	// Buffer containing nicks results
var lastId = 0;					// Holds the last ID 
var selectedUser = null;		// Holds the user selection index
var sid = null;

/* Launch Trion */
function launchTriton() {
	ajFetch('system/core.php?mde=netini','appendChatContent',false,0);
}

/* ajFetch function */
function ajFetch(url, destination, cycle, delay, noloading) {
	
	document.getElementById('messageBox').style.visibility = 'hidden';
	
	/* Execution timer */
	var timerOne = new Date();
	floatInt = timerOne.getTime();
	//
	
	var curInstance;
	if (cycle == null) {
		cycle = false;	
	}
	if (noloading == null) {
		noloading = false;	
	}
	
	if (arAjx.length == 1) {
		curInstance = 1;
		arAjx[1] = new Ajax;
	} else {
		var found = false;
		for (i=1;i<arAjx.length;i++) {
			if (arAjx[i].Is_Free()) {
				curInstance = i;
				found = true;
			}
		}
		
		if (!found) {
			arAjx.push(new Ajax);
			curInstance = arAjx.length;
			arAjx[curInstance] = new Ajax;
		}
	}
	
	if (noloading) { arAjx[curInstance].Set_Loading(false); }
	arAjx[curInstance].HTTP_Get(url, destination);
	
	if (arStops[destination] != true) {
		if (cycle) {
			setTimeout("ajFetch('"+url+"','"+destination+"',true,"+delay+");",delay);
		}
	} else {
		arStops[destination] = null;	
	}
}

function ajStop(destination) {
	arStops[destination] = true;
}

/* Ajax function class */
/* Declarations */
var arAjx = new Array(1);
var arStops = new Array;

/* Ajax functions, objects, classes and callback */
function Ajax() {
	/* Declarations */
	/* Public methods */
	this.HTTP_Get = HTTP_Get;
	this.Is_Free = Is_Free;
	this.Set_Loading = Set_Loading;
		
	/* Private variables */
	var ajobj = XMLHTTP_object();
	var http_destobj = null;
	var free = true;
	var show_loading = true;

	/* Methods */
	function HTTP_Get(url, destination) {
		if (free && (url != null) && (destination != null) && ((ajobj.readyState == 0) || (ajobj.readyState == 4))) {
			http_destobj = destination;
			
			ajobj.open("GET", url, true);
			ajobj.onreadystatechange = HTTP_Get_CallBack;
			ajobj.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
			ajobj.send(null);
			free = false;
		} else {
			return false;
		}
	}
	
	/* Get CallBack (Handle received data) */
	function HTTP_Get_CallBack() {
		if (ajobj.readyState == 4) {
			var results = ajobj.responseText;
			
			/* First answer received?, set initComplete to true */
			if (!initComplete) {
				initComplete = true;
			}
			
			if (typeof(results)=='string' && results != null && results != '') {
				/* Function callback evaluator */
				if (eval("typeof(" + http_destobj + ") == 'function'")) { 
					/* Function detected, pass data to function */
					eval(http_destobj + "(results);");
				} else {
					/* Not a function, pass data to the html object */
					if (typeof document.getElementById(http_destobj).innerHTML != "undefined") {
						document.getElementById(http_destobj).innerHTML = results;
					}
				}
			}
			free = true;
		}
	}
	
	/* Helpers functions */
	function Is_Free() {
		return free;	
	}
	
	function Set_Loading(value) {
		show_loading = value;
	}
	
	/* AJAX OBJECT */
	function XMLHTTP_object() {
	  var xmlhttp;
	  /*@cc_on
	  @if (@_jscript_version >= 5)
		try {
		  xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
		  try {
			xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
		  } catch (E) {
			xmlhttp = false;
		  }
		}
	  @else
	  xmlhttp = false;
	  @end @*/
	  if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
		try {
		  xmlhttp = new XMLHttpRequest();
		} catch (e) {
		  xmlhttp = false;
		}
	  }
	  return xmlhttp;
	}
}

/* Append Chat Content */
function appendChatContent(streamData) {

	/* End of execution timer */
	var timerTwo = new Date();
	document.getElementById('networkInfo').innerHTML = "Latency: "+(timerTwo.getTime() - floatInt) + ' ms';

	/* Break stream buffer into lines */
	streamLines = streamData.split('[eol]');
	
	/* Run through each lines */
	for (var n=0; n < streamLines.length; n++) {
		
		/* Don't act if the streamLine is blank */
		if (trim(streamLines[n]) != '') {
		
			/* Split the line into content chunks, divided by ":" */
			contentArray = streamLines[n].split(':');
			
			/* Data innput modes switching */
			/* STRING FORMAT -> TYPE:DESTINATION:ID:SPARE:CONTENT[eol] */
			switch(contentArray[0]) {
				
				/* SID INIT MODE */
				case 'SID':
					sid = contentArray[1];
					ajFetch('system/core.php?mde=getChatData&'+sid,'appendChatContent',true,5000);
					ajFetch('system/core.php?mde=pingpong&'+sid,'wasteland',true,120000);
				break;
				
				/* CHANNELS LIST MODE */
				case 'CHANNEL':
					/* Check if destination is in the bufferList array - If it's not, add it (used for CHANNELS) */
					if (!in_array(bufferList, contentArray[1])) {
						bufferList.push(contentArray[1]);
					
						buffer[contentArray[1]] = "Now talking in "+contentArray[1]+'<br />';

						/* Re-Generate the menu */
						menuElements();
						
						/* Set the selectedItem id if selectedItem was blank */
						if (selectedItem == null) {
							selectedItem = contentArray[1];
							showBuffer(contentArray[1]);
						}
					}
					
					menuElements();
					
				break;
				
				/* MESSAGE MODE */
				
				
				// BE CAREFULL WITH THOSE MESSAGES, THEY SHOULD NOT INTERFER WITH THE CHANNELS BUFFERS LIST! //
				case 'MESSAGE':
					if (contentArray.length >= 4) {

						contentArray[1] = trim(contentArray[1]);
						/* Check if destination is in the bufferList array - If it's not, add it (used for private messages) */
						
						//if ((!in_array(bufferList, contentArray[1]) && (contentArray[1]) != '') && (contentArray[1] != null)) {
						//	bufferList.push(contentArray[1]);

							/* Re-Generate the menu */
							//menuElements();
						//}

						/* Append the new data content to the corresponding buffer array item */
						contentArray[4] = trim(decode64(trim(contentArray[4])));
						if (contentArray[4] != '' && contentArray[4] != null) {
							if (!buffer[contentArray[1]]) {
								buffer[contentArray[1]] = contentArray[4]+'\n';
							} else {
								var bufferLen = buffer[contentArray[1]].length;
								buffer[contentArray[1]] = buffer[contentArray[1]].substring(bufferLen-9000, bufferLen) + contentArray[4]+'\n';
							}
						}
	
						/* If the text we just got is meant to be sent to the actually selected container, send it now. */
						if (selectedItem == contentArray[1]) {
							showBuffer(contentArray[1]);
						} else { 
							if (typeof contentArray[1].className != "undefined") {
								document.getElementById(contentArray[1]).className = 'newMenuItem';
							}
						}
					}
				break;
				
				case 'PRIVMSG':
				
					//if (contentArray.lenght >= 4) {
						contentArray[1] = trim(contentArray[1]);
						contentArray[4] = trim(decode64(trim(contentArray[4])));
						if (contentArray[4] != '' && contentArray[4] != null) {
							
							/* Check if destination is in the bufferList array - If it's not, add it (used for CHANNELS) */
							if (!in_array(bufferList, contentArray[1])) {
								bufferList.push(contentArray[1]);
					
								buffer[contentArray[1]] = "Now talking with "+contentArray[1]+'<br />';
							}					
							menuElements();

							/* Add message */
							
							if (!buffer[contentArray[1]]) {
								buffer[contentArray[1]] = contentArray[4]+'\n';
							} else {
								var bufferLen = buffer[contentArray[1]].length;
								buffer[contentArray[1]] = buffer[contentArray[1]].substring(bufferLen-9000, bufferLen) + contentArray[4]+'\n';
							}
						}
					
						/* If the text we just got is meant to be sent to the actually selected container, send it now. */
						if (selectedItem == contentArray[1]) {
							showBuffer(contentArray[1]);
						} else { 
							if (typeof contentArray[1].className != "undefined") {
								document.getElementById(contentArray[1]).className = 'newMenuItem';
							}
						}
					//}
				
				/* NICKNAMES MODE */
				case 'NICKNAMES':
					
					var nicknames = decode64(contentArray[4]);
					nicksBuffer[contentArray[1]] = nicknames;
					
					/* Show right now selected */
					if (selectedItem == contentArray[1]) {
						document.getElementById('nicksList').innerHTML = nicknames;
					}
				break;
				
				/* CHANNEL MODES & TOPIC */
				case 'MODES':
					
					var channelTopic = decode64(contentArray[4]);
					topicBuffer[contentArray[1]] = channelTopic;
					
					if (selectedItem == contentArray[1]) {
						document.getElementById('topicsContainer').innerHTML = channelTopic;
					}
				break;
				
				/* INFORMATION MESSAGE (System Debug?) */
				case 'INFO':
					//document.getElementById('messageBox').style.visibility = 'visible';
					//document.getElementById('messageBoxText').innerHTML = contentArray[5];
					//document.getElementById('messageBoxIcon').src = 'images/infoicons/' + contentArray[1] + '.gif';
				break;
				
				/* ANYTHING ELSE */
				default :
					document.getElementById('wasteland').innerHTML += streamLines[n];
				break;
			}
		}
	}
}

/* Send data from textInput element */
function sendData() {
	data = document.getElementById('textInput').value;

	/* Don't act if data is null */
	if (data != null && trim(data) != '') {
				
		/* encode and send the channel (ch), encode and send the text content (txt) */
		ajFetch('system/core.php?mde=sendChatData&'+sid+'&ch=' + encode64(selectedItem) + '&txt=' + encode64(data), 'appendChatContent', false, 0);

		/* Clear the textInput value */
		document.getElementById('textInput').value = '';
		
	}
}

/* MenuElements constructor */
function menuElements() {

	var object = document.getElementById('queriesContainer');
	
	/* Start the main container content */
	object.innerHTML = '';

	/* Run through each item in buffer list */
	
	for (var i=0; i < bufferList.length; i++) {
		/* If the item is equal to the selected item index, we will set its class (style) to selected more */
		if (bufferList[i] == selectedItem) {
			var clX = 'selectedMenuItem';
		} else {
			var clX = 'menuItem';
		}
		
		/* Find the container object, and create the child link in it */
		object.innerHTML += '<a id="'+bufferList[i]+'" class="'+clX+'" onClick="showBuffer(\''+bufferList[i]+'\');">'+bufferList[i]+'</a>';
	}
}

/* Show buffer */
function showBuffer(object) {
	/* 
		This function will fake swapping windows by showing the buffer array content for the corresponding
		item into the chat content element.
	*/
	
	/* Show corresponding buffer */
	if (buffer[object] != null) {
		document.getElementById('chatContent').innerHTML = buffer[object];
	}
	
	if (topicBuffer[object] != null) { 
		document.getElementById('topicsContainer').innerHTML = topicBuffer[object];
	} else {
		document.getElementById('topicsContainer').innerHTML = '';
	}
	
	if (nicksBuffer[object] != null) {
		document.getElementById('nicksList').innerHTML = nicksBuffer[object];
	} else {
		document.getElementById('nicksList').innerHTML = ''
	}

	/* Set the selected item correspondance for the object */
	selectedItem = object;
	/* Re-Generate the menu elements */
	menuElements();
	/* Scroll down to the end of the content */
	scrollDown();
	/* Set focus back to the text field */
	document.getElementById('textInput').focus();
	
}

/* Scrolls the content div to its end */
function scrollDown() {
	content = document.getElementById('chatContent');
	content.scrollTop = content.scrollHeight;
}

/* MoveToItem */
function moveToItem(direction) {
	/* This will swap to the previous or next item in bufferitems list */
	for (var i=0; i < bufferList.length; i++) {	
		if (bufferList[i] == selectedItem) {
			if (direction == 'left') {
				selectedItem = (i!=0?bufferList[i-1]:bufferList[bufferList.length-1]);
			} else {
				selectedItem = (i!=bufferList.length?bufferList[i+1]:bufferList[1]);
			}
			showBuffer(selectedItem);
			break;
		}
	}
}

/* KeyCodes handler */
function keyEventHandler(key) {
	/* This is called when a key has been pressed in the text area */
	switch (key) {
		case 9: /* Tab key */
			//
		break;
		
		case 13: /* Return key */
			sendData();
		break;
		
		case 37: /* Left Arrow */
			if (document.getElementById('textInput').value == '') {
				moveToItem('left');
			}
		break;
		
		case 38: /* Up Arrow */
		break;	
		
		case 39: /* Right Arrow */
			if (document.getElementById('textInput').value == '') {
				moveToItem('right');
			}
		break;
		
		case 40: /* Down Arrow */
			//
		break;		
	}
}

/* JavaScript Helpers */
/* ... or "functions that should exist but doesnt for reasons noone knows" */

/* Base64 Helpers */
var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function encode64(input) {
	if (input != null && input != '' && input != ' ') {
		var output = "";
		var chr1, chr2, chr3;
		var enc1, enc2, enc3, enc4;
		var i = 0;

		do {
			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}

			output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + 
			keyStr.charAt(enc3) + keyStr.charAt(enc4);
		} while (i < input.length);
   		
		return output;
	}
}
function decode64(input) {
	var output = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;

	input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");

	do {
		enc1 = keyStr.indexOf(input.charAt(i++));
		enc2 = keyStr.indexOf(input.charAt(i++));
		enc3 = keyStr.indexOf(input.charAt(i++));
		enc4 = keyStr.indexOf(input.charAt(i++));

		chr1 = (enc1 << 2) | (enc2 >> 4);
		chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
		chr3 = ((enc3 & 3) << 6) | enc4;

		output = output + String.fromCharCode(chr1);

		if (enc3 != 64) {
			output = output + String.fromCharCode(chr2);
		}
		if (enc4 != 64) {
			output = output + String.fromCharCode(chr3);
		}
	} while (i < input.length);
	
	return output;
}

/* in_array helper */
function in_array(array, string) {
	for (var i=0; i<array.length; i++) {
		if (array[i] == string) {
			return true;
		}
	}
}

/* trim helper */
function trim(str) {
	/* Removes white spaces on the beginning and on the end of a string */
	if (str != null && str != '') {
		while (str.charAt(0) == ' ')
			str = str.substring(1);
		while (str.charAt(str.length - 1) == ' ')
			str = str.substring(0, str.length - 1);
	}
	return str;
}

/* Menu *///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

/* shows or hide the menu */
function showMenu() {
	if (document.getElementById('menu').style.visibility == 'visible') {
		document.getElementById('menu').style.visibility = 'hidden';
	} else {
		document.getElementById('menu').style.visibility = 'visible';
	}
}

/* hides the menu if it is visible when the text field gets the focus back */
function getFocus() {
	document.getElementById('menu').style.visibility = 'hidden';
	document.getElementById('submenu').style.visibility = 'hidden';
}

/* Performs actions on menu click */
function menuAction(action) { 
	
	switch(action) {
		case ('nick'):
			var nick = prompt("Nickname ","") 
			if (nick != null && nick != "") { 
				document.getElementById('textInput').value = "/nick "+nick;
				sendData();
			}
		break;

		case('join'):
			var channel = prompt("Channel name ","")
			if (channel != null && channel != "") {
				document.getElementById('textInput').value = "/join "+channel;
				sendData();
			}
		break;
		
		case('part'):
			document.getElementById('textInput').value = "/part";
			sendData();
		break;

		case('whois'):
			var whois = prompt("Nickname ","")
			if (whois != null && whois != "") {
				document.getElementById('textInput').value = "/whois "+whois;
				sendData();
			}
		break;
		
		case('help'):
			document.getElementById('textInput').value = "/help";
			sendData();
		break;
	}
}

function subMenu(itemName) {
	
	document.getElementById('submenu').innerHTML = '<center>Loading, Please stand by</center>';
	
	switch(itemName) {
		
		case('smiles'):
			ajFetch('menus/smiles.php', 'submenu', false, 0);
			document.getElementById('submenu').style.visibility = 'visible';
		break;
		
		case('colors'):
			ajFetch('menus/colors.php', 'submenu', false, 0);
			document.getElementById('submenu').style.visibility = 'visible';
			
		break;
	}
}

function userAct() {
	if (selectedUser != null) {
		
		var textBox = document.getElementById('textInput');

		switch(document.getElementById('userAct').value) {
			
			case('Query'):
				if (!in_array(bufferList, selectedUser)) {
					bufferList.push(selectedUser);
					buffer[selectedUser] = "Now talking with "+selectedUser+'<br />';
					menuElements();
					selectedItem = selectedUser;
					showBuffer(selectedUser);
				}
			break;
			
			case('Whois'):
				textBox.value = '/whois ' + selectedUser;
				sendData();
			break;
			
			case('Slap'):
				textBox.value = '/slap ' + selectedUser;
				sendData();
			break;
			
			case('Ban'):
				textBox.value = '/ban ' + selectedUser;
				sendData();
			break;
			
			case('Op'):
				textBox.value = '/op ' + selectedUser;
				sendData();
			break;
			
			case('Deop'):
				textBox.value = '/deop ' + selectedUser;
				sendData();
			break;
			
			case('Voice'):
				textBox.value = '/voice ' + selectedUser;
				sendData();
			break;
			
			case('Devoice'):
				textBox.value = '/devoice ' + selectedUser;
				sendData();
			break;
			
			case('Mute'):
				textBox.value = '/mute ' + selectedUser;
				sendData();
			break;
			
			case('Demute'):
				textBox.value = '/demute ' + selectedUser;
				sendData();
			break;
			
		}
	}
}
