/*		Copyright Nayan Ghosh. All rights reserved
*		Coded By Nayan Ghosh
*		package HiFiBB JS
*		Common JS scripts to be included in skin files */

var fixed_links = false;
var links_timeout;
var my_cookies = new Array; //stores the cookies
var username_context_menus = new Array;
var AJAX_init = false;
var body_width = 0; //stores the actual body width
var body_offset = 0; //stores the screen size

function trim(str)
{
	return str.replace(/^\s+|\s+$/, ''); //replace whitespace at the start and end with ''
}
//get the cookies
function parseCookies()
{
	var cookie_parts = document.cookie.split(';'); //splits the cookie string into array
	for (i=0; i<cookie_parts.length; i++)
	{
		temp = cookie_parts[i].split('='); //separate the name and value parts
		my_cookies[trim(temp[0]) + ''] = unescape(temp[1]); //store in the array
	}
}
//set a cookie
function setCookie(name, value)
{
	document.cookie = name + "=" + escape(value); //add the cookie to the document
	my_cookies[name + ''] = value; //add the cookie to our my_cookies array
}

/* function to fix the XHTML strict specifications */
function stopExternalLinks() //this is executed onLoad
{
	externalLinks();
	fixed_links = true;
	clearTimeout(links_timeout);
}
function externalLinks() { //fixes links with rel="external" to blank target
 if (fixed_links || !document.getElementsByTagName) return;
 var anchors = document.getElementsByTagName("a");
 for (var i=0; i<anchors.length; i++) {
   var anchor = anchors[i];
   if (anchor.getAttribute("href") && anchor.getAttribute("rel") == "external")
     anchor.target = "_blank";
 }
 links_timeout = setTimeout('externalLinks()', 500); //repeat after 500ms, if document has finished loading, it will be stopped
}
externalLinks(); //trigger the loop, right now before it has finished loading

function create_new_collapse_button(mode,prompt,obj)
{
	var elem = document.createElement('img');
	elem.setAttribute('src', images_dir + mode + '.png');
	elem.setAttribute('title', prompt);
	elem.setAttribute('alt', prompt);
	elem.className = 'fright collapse_button';
	elem.onclick = function(){
		collapse(obj, elem);
	}
	return elem;
}

//collapse/show section
function setCollapse()
{
	/* The collapse header element should have the classname as 'sectionheadercont'
	 * The collapsible element should have the classname as 'collapsed' for collapsed view and nothing for expanded view
	 * Once a sectionheadercont is found the immediate next sibling is searched for collapsible element
	 * The button for collapse/expand has the classname 'collapse_button'
	 * Once a collapsible element is found, a collapse button is inserted in the collapse_h
	 */
	check_collapse_headers = new Array('div','thead');
	for (h in check_collapse_headers){
		divs = document.getElementById('wrap').getElementsByTagName(check_collapse_headers[h]);
		for (i=0;i<divs.length;i++){
			var currentNode = divs[i];
			if (currentNode.className && (currentNode.className == 'sectionheadercont' || currentNode.className.indexOf('sectionheadercont ') >= 0)){
				//found the sectionheadercont... now find the sectioncontent in the next sibling
				sectioncontent = currentNode.nextSibling;
				while (sectioncontent.nodeType != 1){ //1 = ELEMENT_NODE
					sectioncontent = sectioncontent.nextSibling;
				}
				is_collapsed = false;
				if (sectioncontent.className && (sectioncontent.className=='sectioncontent' || sectioncontent.className.indexOf('sectioncontent ') >= 0)){
					//find out the state
					if (sectioncontent.className.indexOf('collapsed') >= 0){
						is_collapsed = true;
					}
				}
				nextNode = currentNode.firstChild;
				while (nextNode)
				{
					if (nextNode.className && (nextNode.className=='sectionheader' || nextNode.className.indexOf('sectionheader ' >= 0))){
						//get the img element
						img_elem = create_new_collapse_button(is_collapsed ? 'expand' : 'collapse', is_collapsed ? 'Expand': 'Collapse', sectioncontent);
						//insert it
						nextNode.insertBefore(img_elem,nextNode.firstChild);
						break;
					}
					nextNode = nextNode.nextSibling;
				}
			}
		}
	}
}

/*function setCollapse(){
	if (divs = document.getElementsByTagName('div')){
		var get_dblclick_handler = new Function('target', "var new_func = function(){collapse(target);return false;}; return new_func;");
		var sectionheadercont, sectioncontent;
		for (i=0;i<divs.length;i++){
			currentdiv = divs[i];
			if (currentdiv.className && (currentdiv.className == 'section' || currentdiv.className.indexOf('section ') >= 0)){
				sectionheadercont = sectioncontent = '';
				//find the sectionheadercont element
				subdivs = currentdiv.getElementsByTagName('div');
				for (j=0;j<subdivs.length;j++){
					if (subdivs[j].className && (subdivs[j].className == 'sectionheadercont' || subdivs[j].className.indexOf('sectionheadercont ') >= 0)){
						sectionheadercont = subdivs[j];
						continue;
					}
					if (subdivs[j].className && (subdivs[j].className == 'sectioncontent' || subdivs[j].className.indexOf('sectioncontent ') >= 0)){
						sectioncontent = subdivs[j];
						break;
					}
				}
				//if we found the header, but not the content, search in table elements and tbody elements
				if (sectionheadercont && !sectioncontent){
					subtables = currentdiv.getElementsByTagName('table');
					for (j=0;j<subtables.length;j++){
						if (subtables[j].className && (subtables[j].className == 'sectioncontent' || subtables[j].className.indexOf('sectioncontent ') >= 0)){
							sectioncontent = subtables[j];
							break;
						}
					}
					if (!sectioncontent){
						subtbodys = currentdiv.getElementsByTagName('tbody');
						for (j=0;j<subtbodys.length;j++){
							if (subtbodys[j].className && (subtbodys[j].className == 'sectioncontent' || subtbodys[j].className.indexOf('sectioncontent ') >= 0)){
								sectioncontent = subtbodys[j];
								break;
							}
						}
					}
				}
				if (sectionheadercont && sectioncontent){
					sectionheadercont.ondblclick = get_dblclick_handler(sectioncontent);
				}
				//i += subdivs.length; //dont allow nested
			}
		}
	}
}*/
function collapse(elem, collapse_button){
	//var elem = collapse_divs[id];
	if (elem.style && elem.style.display == 'none'){
		elem.style.display = '';
		elem.style.opacity = 0;
		fade_in_obj = elem;
		fadein();
		collapse_button.setAttribute('src', images_dir + 'collapse.png');
		collapse_button.setAttribute('alt', 'Collapse');
		collapse_button.setAttribute('title', 'Collapse');
	} else {
		//elem.style.display = 'none';
		elem.style.opacity = 1;
		fade_out_obj = elem;
		fadeout();
		collapse_button.setAttribute('src', images_dir + 'expand.png');
		collapse_button.setAttribute('alt', 'Expand');
		collapse_button.setAttribute('title', 'Expand');
	}
	return false;
}

//functions to be executed when page loads
function doOnLoad()
{
	//calculate body width
	body_offset = document.getElementById('body').offsetWidth;
	body_width = document.getElementById('wrap').offsetWidth;
	
	window.onscroll = doOnScroll; //set the onscroll handler
	doOnScroll();
	stopExternalLinks(); //stop the external links loop
	parseCookies(); //parse and store cookies
	//
	document.body.onmousedown = doOnMouseDown;
	document.body.oncontextmenu = doOnContextMenu;
	//
	//set the doubleclick event handler for sectionheaders...
	setCollapse();
	
	AJAX_init = true;
	
	//trigger a trial ajax request - THIS IS JUST AN EXAMPLE, actually can be done to get the members online and visitors in future
	/*if (createAjaxRequest('trial'))
	{
		var data = new Array;
		data['hello'] = 'My name is Nayan';
		data['bye'] = 'See you tomorrow.';
		triggerAJAXRequest('trial', data, 'ajax/php/trial.php', 'get', trialUpdate);
	}*/
}
function doOnResize()
{
	
}
function doOnMouseDown(eventObj)
{
	/*document.write('<ol>');
	for (var i in eventObj)
		document.write('<li>' + i + " => " + eventObj[i] + "</li>");
	document.write('</ol>');*/
	
	//username_context_menu.style.visibility = "collapse";
	if (cx_menu = document.getElementById('cx_menu')) { cx_menu.style.display = "none"; }
	if (username_context_menu = document.getElementById('username_context')) { username_context_menu.style.display = "none"; }
}
function doOnContextMenu(eventObj)
{
	target = eventObj.target;
	//clear any context menu thats visible
	var username_context_menu = document.getElementById('username_context');
	if (eventObj.button == 2) //right button
	{
		//if we have a username, then we should display options
		if (target.getAttribute('class') == 'username')
		{
			//get the href and the user_id
			var url = target.getAttribute('href');
			var offset = url.indexOf('u=') + 2;
			var rem_url = url.substr(offset);
			var length = rem_url.indexOf('&');
			if (length < 0){ length = rem_url.length; }
			var user_id = url.substr(offset, length);
			//check if the context menu already exists for this user
			if (username_context_menus[user_id])
			{
				showContextMenu(eventObj, username_context_menu, username_context_menus[user_id]);
			}
			else if (createAjaxRequest('username_context_menu'))
			{
				var data = new Array;
				data['go'] = 'context_menu';
				data['type'] = 'username';
				data['u'] = user_id;
				//add the user_id property to the AJAX request object
				AjaxRequests['username_context_menu'].user_id = user_id;
				AjaxRequests['username_context_menu'].eventObj = eventObj;
				triggerAJAXRequest('username_context_menu', data, 'ajax.php', 'get', receiveUsernameContextMenu);
			}
			return false;
		}
	}
}
function doOnScroll()
{
	var ajax_block = document.getElementById('ajax_notify');
	ajax_block.style.top = (document.documentElement.scrollTop + document.documentElement.clientHeight - 25) + "px";
}
window.onload = doOnLoad; //set the onLoad handler
window.onresize = doOnResize; //set the onResize handler

//shows a context menu
function showContextMenu(eventObj, context_menu, content)
{
	context_menu.innerHTML = content;
	if (content) {
		var cx_menu = document.getElementById('cx_menu');
		var body_width = document.getElementById('body').offsetWidth;
		cx_menu.style.display = "inline";
		context_menu.style.display = 'inline';
		context_menu.style.top = (eventObj.clientY > 5 ? eventObj.clientY - 5 : eventObj.clientY) + document.documentElement.scrollTop + 'px';
		context_menu.style.left = (eventObj.clientX + cx_menu.offsetWidth > document.documentElement.clientWidth ? document.documentElement.clientWidth - cx_menu.offsetWidth : eventObj.clientX) + document.documentElement.scrollLeft + 'px';
	}
}

/***** login and password functions ******/
function validate_login(form_obj){
	var u=document.login.username;
	var p=document.login.password;
	if (u.value==""){
		alert("Username is invalid!");
		u.focus();
		return false;
	}
	else if (p.value==""){
		alert("Password is blank!");
		p.focus();
		return false;
	}
	return encrypt(form_obj); //turn this to true
}
function encrypt(formObj){
	var pass = formObj.password.value;
	var timestamp = formObj.timestamp.value; //convert to string
	var key1 = Math.random()+'';
	while (key1==0 || key1==1){key1 = Math.random()+'';}
	key1 = key1.substr(2, 11); //get an 11 character long key
	for (i=key1.length; i<11; i++){key1 += Math.floor(Math.random()*10)+'';}
	var key1_enc = encrypt_key(key1);//encode this encryption key
	pass_hex_enc = hex(pass);
	//make the pass_hex_enc at least 10 chars long by appending 10 chars....
	addition = Math.random() + '';
	addition = addition.substr(2,10);
	for (i=addition.length;i<10;i++){addition += Math.floor(Math.random()*10)+'';}
	pass_hex_enc += addition;
	//now do the pass encryption
	for (i=key1.length-1; i>=0; i--){ //start from end
		pass_hex_enc = pass_hex_enc.substr(0,key1[i]) + timestamp[i%10] + pass_hex_enc.substr(key1[i]);
	}
	//now modify the form elements
	input_pass_enc = document.createElement('input');
	input_pass_enc.setAttribute('type', 'hidden');
	input_pass_enc.setAttribute('name', 'pass_enc');
	input_pass_enc.setAttribute('value', pass_hex_enc);
	input_key_enc = document.createElement('input');
	input_key_enc.setAttribute('type', 'hidden');
	input_key_enc.setAttribute('name', 'key_enc');
	input_key_enc.setAttribute('value', key1_enc);
	formObj.appendChild(input_pass_enc);
	formObj.appendChild(input_key_enc);
	formObj.password.value = '';
	return true;
}
function encrypt_key(key){
	var enc = hex(key);
	//insert arbitrary chars before and after the encrypted key
	a = Math.floor(Math.random() * 1000000);
	b = Math.floor(Math.random() * 1000000);
	a+='';b+= '';
	for (i=a.length;i<6;i++){a+='0';}
	for (i=b.length;i<6;i++){b+='0';}
	enc = hex(a) + enc + hex(b);
	return enc;
}
function hex(input){
	hex_array = new Array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f');
	var output = '';
	for (i=0;i<input.length;i++){
		output += hex_array[Math.floor(input.charCodeAt(i) / 16)] + hex_array[input.charCodeAt(i) % 16];
	}
	return output;
}

/*********** fading menus ************/
var fade_in_obj=null,fade_out_obj=null,fadeintimer,fadeouttimer;

function showMenu(id,show){
	var b = document.getElementById("menu_"+id);
	/*var c = b.previousSibling;
	while (c && c.className != 'menuheader')
	{
		c = c.previousSibling;
	}
	var body_width = c.offsetLeft + c.offsetWidth;*/
	
	b.style.display = 'block';
	b.style.left = 'auto';
	if (b.offsetLeft + b.offsetWidth > body_width - 20)
	{
		b.style.left = (body_offset - b.offsetWidth - 25) + 'px';
	}
	//b.style.left = a + "px";
	if(show){
		if(fade_out_obj==b){
			b.style.opacity=1;			
			fade_out_obj=null;
		}
		else if(fade_in_obj == null)
		{
			b.style.display="block";
			if (!b.style.opacity){
				b.style.opacity=0;
			}
			fade_in_obj=b;
			fadein();
		}
	}
	else{
		if (fade_in_obj == b)
		{
			fade_in_obj = null;
		}
		if(fade_out_obj != null){
			fade_out_obj.style.opacity=0;
			fade_out_obj.style.display="none";
		}
		fade_out_obj=b;
		fadeout();
	}
}
function fadein()
{
	if (fade_in_obj==null) return false;
	var x = fade_in_obj.style.opacity;	
	x -= 0;
	x += 0.1;	
	fade_in_obj.style.opacity = x;
	if (x < 1)
	{
		fadeintimer=setTimeout("fadein();", 50);
	}
	else
	{
		fade_in_obj=null;
	}
}
function fadeout()
{
	if (fade_out_obj==null) return false;
	var x = fade_out_obj.style.opacity;	
	x -= 0;
	x -= 0.1;
	fade_out_obj.style.opacity = x;
	if (x > 0)
	{
		fadeouttimer=setTimeout("fadeout();", 50);
	}
	else
	{
		fade_out_obj.style.display="none";
		fade_out_obj=null;
	}
}

//*********************AJAX COMPONENTS****************
var AjaxRequests = new Array; //array of AJAX Request objects

//creates a XMLHttpRequest Object and returns the same, also adds the same to the AjaxRequests array
//ident - the textual identifier for this request object
function createAjaxRequest(ident)
{
	if (!AJAX_init){return false;}
	ident += ''; //force a string
	if (AjaxRequests[ident]){return false;}  //request object already exists, in working mode
	try {
		xmlHttp = new XMLHttpRequest(); //for most modern browsers
	} catch (e) {
		try {
		xmlHttp = new ActiveXObject("Msxml2.XMLHTTP"); //for newer IE
	} catch (e1) {
		try {
		xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); //for old IE
	} catch (e2) {
		return false; //browser does not support AJAX requests
	} } }
	xmlHttp.ident = ident; //set the property to the object
	AjaxRequests[ident] = xmlHttp; //add the object to the array
	return AjaxRequests[ident];
}

//each function using AJAX will create its own AjaxRequests element and check if it already exists if required.
//function to open and send the request...
//request - the XMLHttpRequest object, data - as an array with name/value pairs, method - get/post in caps, updateFunction - the function to call when we receive data
function triggerAJAXRequest(requestIdent, data, url, method, updateFunction)
{
	//first form the request...
	var sendData = '';
	for (var i in data)
	{
		sendData += (sendData != '' ? '&' : '') + i + "=" + escape(data[i]);
	}
	method = method.toLowerCase();
	if (method == 'get') //append to the url
	{
		url += "?" + sendData;
		sendData = null;
	}
	//open the request object
	var request = AjaxRequests[requestIdent]; //get the request object
	request.open(method, url, true);
	request.workingFunction = updateFunction; //set the working function... we will be calling this function when the AJAX request completes
	request.onreadystatechange = onXMLHttpUpdate; //this function handles all the AJAX request readystate changes
	if (method == 'post'){
		request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); //required
	}
	request.send(sendData); //send out the data
	var ajax_notify = document.getElementById('ajax_notify');
	ajax_notify.innerHTML = "Working on your request. Please wait...";
	ajax_notify.style.display = "inline";
}

/* This function handles all AJAX request readystate changes */
function onXMLHttpUpdate(eventObj)
{
	//get the request object
	var request = AjaxRequests[eventObj.target.ident];
	if (request.readyState == 4) //if request is complete
	{
		request.workingFunction(request); //call the working function for this request object
		AjaxRequests[eventObj.target.ident] = false;
		var ajax_notify = document.getElementById('ajax_notify');
		ajax_notify.innerHTML = "Request complete.";
		ajax_notify.style.display = "none";
	}
}

//this is just an example of a working function for a request object
function trialUpdate(request)
{
	if (request.status == 200) //no errors in interface
	{
		var response = request.responseXML; //if we expect XML, get it, else we may also use request.responseText to get plain text
		//get individual values
		var hello = response.getElementsByTagName('hello')[0].childNodes[0].nodeValue;
		var bye = response.getElementsByTagName('bye')[0].childNodes[0].nodeValue;
		var zero = response.getElementsByTagName('i0')[0].childNodes[0].nodeValue;
		var one = response.getElementsByTagName('i1')[0].childNodes[0].nodeValue;
		var new_text = document.createTextNode("hello = " + hello + " and bye = " + bye + " and myVar = " + request.ident);
		var new_element = document.createElement('p');
		new_element.appendChild(new_text);
		var my_body = document.getElementById('body');
		my_body.appendChild(new_element);
	}
}
/* receives the username context menu and adds it to the cache Array */
function receiveUsernameContextMenu(request)
{
	if (request.status == 200) //no errors in interface
	{	
		var response = request.responseText;
		username_context_menus[request.user_id] = response;
		showContextMenu(request.eventObj, document.getElementById('username_context'), response);
	}
}

/* function to gather all the form data and return an array
* formObj is the reference to the form Object, filters - array of names of elements that should be included exclusively */
function formToArray(formObj, filters)
{
	var result = new Array();
	//get all the input and parse each one and pass on the values to the array
	var inputElements = formObj.getElementsByTagName('input');
	for (i=0;i<inputElements.length;i++){
		//first check the type...
		type = inputElements[i].getAttribute('type');
		name = inputElements[i].getAttribute('name');
		value = inputElements[i].value;
		switch (type) {
			case 'checkbox':
			case 'radio':
				if (inputElements[i].checked){
					result[name] = value;
				}
			break;
			default:
				result[name] = value;
		}
	}
	//now the select elements
	var selectElements = formObj.getElementsByTagName('select');
	for (i=0;i<selectElements.length;i++){
		name = selectElements[i].getAttribute('name');
		if (!(selectElements[i].selectedIndex >= 0))
			selectElements[i].selectedIndex = 0;
		
		result[name] = selectElements[i].options[selectElements[i].selectedIndex].value;
	}
	//now the textarea elements
	var textareaElements = formObj.getElementsByTagName('textarea');
	for (i=0;i<textareaElements.length;i++){
		name = textareaElements[i].getAttribute('name');
		result[name] = textareaElements[i].value;
	}
	//now check if we have filters
	if (filters && filters.length > 0)
	{
		var temp = new Array;
		for (var i in filters){
			temp[filters[i]] = result[filters[i]];
		}
		return temp;
	}
	return result;
}