/*---------------------------------------------------------------------------
	
	AJAX.JS
		
	Used for basic AJAX script interaction
	
----------------------------------------------------------------------------
	This file is copyright © 2008, 2009 by Wes Roberts
----------------------------------------------------------------------------*/


/*---------------------------------------------------------------------------
	
	DOCUMENT.onload EVENT FUNCTIONS (put handle_onload() in body onload attr)
----------------------------------------------------------------------------*/
var readyfunks = new Array();
function addReadyFunk(funk) {
	readyfunks.push(funk);
}
function handle_onload() {
	//Run ready functions
	for (var i=0, l=readyfunks.length; i<l; i++) {
		eval(readyfunks[i]);
	}	
}

function dbug(msg) {
	html('dbug', html('dbug')+"<br />\n"+msg);
}


/*---------------------------------------------------------------------------
	
	VARIABLE TYPING FUNCTIONS
----------------------------------------------------------------------------*/
function isObject(obj) {
/*--------------------------------------------------
  Returns true for DOM Objects and {1:2, 3:4} but
  returns false for [1,2,3]
--------------------------------------------------*/
	return ((obj !== null) && (typeof(obj) == 'object') && (typeof(obj.length) !== 'number'));
}
function isArray(obj) {
/*--------------------------------------------------
  Returns true  for [1,2,3]
  Returns false for {1:2, 3:4}
  Safari has problems with this.. so we include functions & objects
--------------------------------------------------*/
	//return ((typeof(obj) == 'object') && (typeof(obj.length) == 'number'));
	return ((!empty(obj)) && ((typeof(obj) == 'object') || (typeof(obj) == 'function')) && (typeof(obj.length) == 'number'));
	//return ((obj != undefined) && (typeof(obj.length) == 'number'));
}
function isFunction(obj){
	return (typeof(obj) == 'function');
}
function isForm(obj) {
	return isObject(obj) && (typeof(obj.elements) != 'undefined');
}
function empty(obj) {
	return (obj === null) || (obj == undefined) || (obj == '');
}


/*---------------------------------------------------------------------------
	
	OBJECT SELECTION
----------------------------------------------------------------------------*/
function select(tag, params, parent) {
/*----------------------------------------------------------------
  This is a newer method which allows you to send an associative
  array of attribute:value pairs to match via regular expressions
  
  e.g. select("*", {'class':'active'});
-----------------------------------------------------------------*/
	var data = bytag(tag, parent);
	for (var i in params) {
		data = filter(data, i, params[i]);
	}
	return data;
}
function filter(els, id, val) {
	var a = [];
	var re = new RegExp('\\b' + val + '\\b');
	var len = els.length;
	for(var x=0; x<len; x++) {
		if (isObject(els[x])) {
			if (re.test(attr(els[x], id))) {
				a.push(els[x]);
			}
		} else { // Not an object, must be a string?
			if (re.test(els[x])) {
				a.push(els[x]);
			}
		}
	}
	return a;
}
function bytag(tagname, node) {
	var r = null;
	//if(!node) node = document.getElementsByTagName("body")[0];
	if(!isObject(node)) node = document.body;
	if (isObject(node)) {
		r = node.getElementsByTagName(tagname);
	}
	return r;
}
function byattr(name, val, node) {
/*--------------------------------------------------
	getElementsByAttribute -- returns an array
--------------------------------------------------*/
	var a = [];
	var els = bytag("*", node);
	var re = new RegExp('\\b' + val + '\\b');
	for(var i=0,j=els.length; i<j; i++) {
		if (isObject(els[i])) {
			if(re.test(attr(els[i], name)))
				a.push(els[i]);
		}
	}
	return a;
}
function byclass(classname, node) {
/*--------------------------------------------------
	getElementsByClass -- returns an array
--------------------------------------------------*/
	return byattr('class', classname, node);
}
function $e(obj) {
	if (isArray(obj)) {
		var r = new Array();
		foreach(obj, function(e){
			r.push($e(e));
		});
		return r;
	}
	return byid(obj); 
}
function byid(whichLayer) {
/*--------------------------------------------------
	Multi-platform getElementById function
--------------------------------------------------*/
	var obj;
	if (isObject(whichLayer)) {
		return whichLayer;
	} else {
		//Get Item
		if (document.getElementById) {
			obj = document.getElementById(whichLayer);
		}	//Standard
		else if (document.all) { 
			obj = document.all[whichLayer];
		}	//IE
		else if (document.layers) { 
			obj = document.layers[whichLayer];
		}	//NN
	}
	return obj;
}
function form(form_id) {
/*--------------------------------------------------
  Given a form id, attempts to load the form object
--------------------------------------------------*/
	if (isObject(form_id)) return form_id;
	var obj = document.forms[form_id];
	if (isObject(obj)) {
		return obj;
	}
	return byid(form_id);
}



/*---------------------------------------------------------------------------
	
	DOM MANIPULATION
----------------------------------------------------------------------------*/
function show(e) {
	var obj = $e(e);
	obj.style.display = "block";
}
function hide(e) {
	var obj = $e(e);
	obj.style.display = "none";
}
function blur(obj){
	var obj = $e(obj);
	obj.blur();
}
function focus(e){
	var obj = $e(e);
	obj.focus();
}
function toggle(e) {
	var obj = $e(e);
	if (obj.style.display != "none") {
		hide(obj);
	} else {
		show(obj);
	}
}
function val(e, val) {
	var obj = $e(e);
	if ((isObject(obj)) && (obj.value != undefined)) {
		if (val != undefined) {
			obj.value = val;
			return isObject(obj);
		} else {
			return obj.value;
		}
	}
	return attr(e, 'value', val);
}
function attr(obj, id, val) {
	var obj = $e(obj);
	if (typeof(val) !== 'undefined') {
		if (id == 'class') {
			obj.className = val;
		} else {
			obj.setAttribute(id, val);
		}
		return isObject(obj);
	}
	if (id == 'class') {
		return obj.className;
	}
	return obj.getAttribute(id);
}
function addClass(e, classname) {
	var obj = $e(e);
	if (isObject(obj)) {
		obj.setAttribute('class', obj.getAttribute('class')+' '+classname);
	}
}
function html(obj, val) {
	obj = $e(obj);
	if (val == null) {
		return obj.innerHTML;
	}
	obj.innerHTML = val;
	return (isObject(obj));
}
function css(obj, pairs) {
	var s = "";
	for(var i in pairs) {
		s += i+":"+pairs[i]+";";
	}
	attr(obj, 'style', s);
}
function foreach(ra, action) {
	if (!isFunction(action)) return;
	//Normal Array
	if (typeof(ra.length) == 'number') {
		for(var i=0, j=ra.length; i<j; i++) {
			action(ra[i]);
		}
	}
	//Associative Array
	else if (isObject(ra)) {
		for (var i in ra) {
			action(ra[i], i);
		}
	}
}


/*---------------------------------------------------------------------------
	
	EVENTS
----------------------------------------------------------------------------*/
function setEvent(obj, type, fn) {
	obj = $e(obj);
	/*if (type == 'altclick') {
		obj.onaltclick = fn;
	} else if (type == 'click') {
		obj.onclick = fn;
	} else if (type == 'dblclick') {
		obj.ondblclick = fn;
	} else if (type == 'focus') {
		obj.onfocus = fn;
	} else if (type == 'blur') {
		obj.onblur = fn;
	}*/
	if (!empty(obj)) obj['on'+type] = fn;
}
function addEvent(obj, type, fn) {
	if (type == 'altclick') {
		ajax_click_alt_add(obj, fn);
		return;
	}
	var funk = function(e){
		e = e || window.event;
		if (!fn(e)) eventPreventDefault(e);
	};
	obj = $e(obj);
	if (obj.attachEvent) {
		obj['e'+type+funk] = funk;
		obj[type+funk] = function(){obj['e'+type+funk](window.event);}
		obj.attachEvent('on'+type, funk);
	} else {
		obj.addEventListener(type, funk, false);
	}
}
function removeEvent(obj, type, fn) {
	if (type == 'altclick') {
		ajax_click_alt_remove(obj);
		return;
	}
	obj = $e(obj);
	if (obj.detachEvent) {
		obj.detachEvent('on'+type, obj[type+fn]);
		obj[type+fn] = null;
	} else {
		obj.removeEventListener(type, fn, false);
	}
}
function eventPreventDefault(e) {
	e = e || window.event;
	e.preventDefault ? e.preventDefault() : e.returnValue = false;
}

/*---------------------------------------------------------------------------
	
	EVENT: ALTCLICK
	
	Allows you to set right-click or control-click functions for elements
	either in the HTML or dynamically by javascript.
	
	USAGE:
	<a id="test" href="#" onaltclick="alert('altclick');">Test</a>
	addEvent('test', 'altclick', function(){ alert('altclick'); });
----------------------------------------------------------------------------*/
var altclickable_id = 0;
var altclickables = {};
var ihaveoncontextmenu = false; // This stops firefox from submitting two altclicks (one for onmousedown, one for oncontextmenu)
var icanseerightclicks = false;
function ajax_click_init() {
	document.body.onmousedown   = function(e){ if (!ihaveoncontextmenu) { return ajax_click_event(e); }};
	document.body.oncontextmenu = function(e){ if (!icanseerightclicks) { return ajax_click_event(e, true); } else { return false; }};
}
function ajax_click_event(e, oncontext){
	if (empty(e)) e = window.event;
	if (oncontext) {
		ihaveoncontextmenu = true;
		return ajax_click_alt(e);
	} else if ((e.button == 2)) {
		icanseerightclicks = true;
		return ajax_click_alt(e);
	}
	return true;
}
function ajax_click_alt(e){
	var target = e.target != null ? e.target : e.srcElement;
	var id = attr(target, 'id');
	var action = attr(target, 'onaltclick');
	var r = true;
	if (!empty(action)) {
		r = r && eval(action);
	}
	if (isFunction(target.onaltclick)) {
		r = r && target.onaltclick(e);
	}
	if ((!empty(id)) && (isFunction(altclickables[id]))) {
		r = r && altclickables[id](e);
	}
	return r;
}
function ajax_click_alt_add(target, callback) {
	var id = (isObject(target)) ? attr(target, 'id') : target;
	if (empty(id)) {
		id = "altclickable_"+altclickable_id;
		altclickable_id++;
		attr(target, 'id', id);
	}
	altclickables[id] = callback;
}
function ajax_click_alt_remove(target, callback) {
	var id = (isObject(target)) ? attr(target, 'id') : target;
	if (empty(id)) return;
	altclickables[id] = null;
}
function mouse(e) {
	var posx = 0;
	var posy = 0;
	if (!e) var e = window.event;
	if (e.pageX || e.pageY){
		posx = e.pageX;
		posy = e.pageY;
	} else if (e.clientX || e.clientY) 	{
		posx = e.clientX + document.body.scrollLeft
			+ document.documentElement.scrollLeft;
		posy = e.clientY + document.body.scrollTop
			+ document.documentElement.scrollTop;
	}
	return [posx,posy];
}

addReadyFunk('ajax_click_init()');




/*---------------------------------------------------------------------------
	
	AJAX FUNCTIONS
----------------------------------------------------------------------------*/
function getXMLHttpRequest() {
/*----------------------------------------------------
  Cross-browser new XMLHttpRequest object.
----------------------------------------------------*/
	var xmlHttp;
	try {
	  // Firefox, Opera 8.0+, Safari
	  xmlHttp=new XMLHttpRequest();
	} catch (e) {
		try {
			// Internet Explorer 6.0+
			xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
		} catch (e) {
	    	try {
				// Internet Explorer 5.5+
	      		xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
	      	} catch (e) {
				// Old or unsupportive browser
				alert("Your browser does not support AJAX!");
				return false;
			}
		}
	}
	return xmlHttp;
}
function get(url, data, callback) {
	if (callback == null) {
		callback = function(){};
	}
	if (isFunction(data)) {
		callback = data;
		data = {};
	}
	if (isForm(data)) {
		data = loadFormData(data);
	}
	var url = url + "?" + arrayToString(data);
	var http = getXMLHttpRequest();
	http.open("GET", url, true);
	http.onreadystatechange = function(){
		if(http.readyState == 4 && http.status == 200) {
			if (isFunction(callback)) {
				callback(http.responseText);
			}
		}
	}
	http.send(null);
}
function post(url, data, callback) {
	if (callback == null) {
		callback = function(){};
	}
	if (isFunction(data)) {
		callback = data;
		data = {};
	}
	if (isForm(data)) {
		data = loadFormData(data);
	}
	var params = arrayToString(data);
	var http = getXMLHttpRequest();
	http.open("POST", url, true);
	http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	http.setRequestHeader("Content-length", params.length);
	http.setRequestHeader("Connection", "close");
	http.onreadystatechange = function(){
		if(http.readyState == 4 && http.status == 200) {
			if (isFunction(callback)) {
				callback(http.responseText);
			}
		}
	}
	http.send(params);
}




/*---------------------------------------------------------------------------
	
	UTILITY FUNCTIONS
----------------------------------------------------------------------------*/
function arrayToString(ra) {
/*-------------------------------------------------------
  Given an associative array, loads values into a string
--------------------------------------------------------*/
	var r = "";
	var i = 0;
	for (var j in ra) {
		if (i > 0) r += "&";
		r += j + "=" + ra[j];
		i++;
	}
	return r;
}
function loadFormData(frm) {
/*--------------------------------------------------
  Given a form, loads the inputs into an array
--------------------------------------------------*/
	var r = new Array();
	frm = (isForm(frm)) ? frm : form(frm);
	if (isForm(frm)) {
		for (var i=0; i<frm.elements.length; i++) {
			r[frm.elements[i].name] = frm.elements[i].value;
		}
	} else {
		alert("Object not a form: "+frm);
	}
	return r;
}
function findPos(obj) {
/*------------------------------------------------------------
	returns the true [x,y] position of the object
-------------------------------------------------------------*/
	obj = $e(obj);
	if (!isObject(obj)) {
		dbug("findPos: Not an object");
		return [0,0];
	}
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop;
		} while (obj = obj.offsetParent);
	}
	return [curleft,curtop];
}
function popup(menuID, relation, locater) {
/*------------------------------------------------------------
	displays a popup window and sets its location near locater
	relation tells how menuID will be positioned near locater:
		'above'
		'below' (default)
		'left'
		'right'
-------------------------------------------------------------*/
	var obj = $e(menuID);
	if (!empty(locater)) {
		var c = findPos(locater);
		if (relation == 'above') {
			obj.style.left = c[0]+"px";
			obj.style.top = (c[1]-obj.clientHeight)+"px";
		} else if (relation == 'left') {
			obj.style.left = (c[0]-obj.clientWidth)+"px";
			obj.style.top = c[1]+"px";
		} else if (relation == 'right') {
			obj.style.left = (c[0]+obj.clientWidth)+"px";
			obj.style.top = c[1]+"px";
		} else {
			obj.style.left = c[0]+"px";
			obj.style.top =  (c[1]+28)+"px";
		}
	} else if (isArray(relation)) {
		obj.style.left = relation[0]+"px";
		obj.style.top = relation[1]+"px";
	}
	show(obj);
}
function htmlentities (string, quote_style) {
	var histogram = {}, symbol = '', tmp_str = '', entity = '';
	tmp_str = string.toString();
	if (false === (histogram = get_html_translation_table('HTML_ENTITIES', quote_style))) {
		return false;
	}
	for (symbol in histogram) {
		entity = histogram[symbol];
		tmp_str = tmp_str.split(symbol).join(entity);
	}
	return tmp_str;
}


/*---------------------------------------------------------------------------
	
	DEPRICATED FUNCTIONS
----------------------------------------------------------------------------*/
function loadQuery(frm) {
/*--------------------------------------------------
  Given a form, loads the inputs into a GET query
--------------------------------------------------*/
	var r = "";
	if ((isObject(frm)) && (frm.elements.length > 0)) {
		r = "?";
		for (var i=0; i<frm.elements.length; i++) {
			if (i > 0) {
				r = r + "&";
			}
			r = r + frm.elements[i].name + "=" + frm.elements[i].value;
		}
	}
	return r;
}
function ajaxForce(scriptURL) {
	var xmlHttp = getXMLHttpRequest();
	
	// Upon State Change
	xmlHttp.onreadystatechange = function()
	{
		if(xmlHttp.readyState==4) {
				return xmlHttp.responseText;
		}
	}
	
	// Send Data
	xmlHttp.open("GET", scriptURL, false);
	xmlHttp.send(null);
}


function ajaxFunk(argForm, updateObject) {
/*--------------------------------------------------
  Runs an AJAX script via the GET vars
--------------------------------------------------*/
	var xmlHttp = getXMLHttpRequest();
	var obj = $e(updateObject);
	//var frm = getObject(argForm);
	var frm = document.forms[argForm];
	
	// Upon State Change
	xmlHttp.onreadystatechange = function(){
		if(xmlHttp.readyState==4) {
			if (xmlHttp.responseText.length > 5) {
				obj.innerHTML="";
				obj.innerHTML=xmlHttp.responseText;
			}
		}
	}

	var scriptURL = frm.action + loadQuery(frm);
	
	xmlHttp.open("GET", scriptURL, true);
	
	// Send Data
	xmlHttp.send(null);
}




