////////////////////////////////////////////////////////////////////////////////
//  HANG WIRE HTML HELPERS



window.HW_HTML_Helpers = function ()
{
	this.unique_number_value = 0;
	this.onload_tasks = new Object();
	this.load_complete = false;
	this.max_zIndex = 0;
	this.min_zIndex = 0;
	this.draggers = new Array();

	this.nbsp = "\u00a0";				// nonbreaking space character

	function unique_number()
	{

		this.unique_number_value++;
		return this.unique_number_value;
	}
	this.unique_number = unique_number;

	this.unique_string = function () {
		return('FCfc' + this.unique_number());
	}

	function add_onload_task(func, cut_in_line, win)
	{
		win = win || window;
		cut_in_line = cut_in_line || false;		// if true, puts this function first in the queue
		var name = win.name || 'main';
		if(!this.onload_tasks[name])
		{
			this.onload_tasks[name] = new Array();
		}

		if(cut_in_line)
		{
			this.onload_tasks[name].unshift(func);
		}
		else
		{
			this.onload_tasks[name].push(func);
		}

		var t = this;
		win.onload = function () {
			for(var i = 0; i < t.onload_tasks[name].length; i++)		// Perform onload tasks in order
			{
				t.onload_tasks[name][i]();										// Do the task
			}
			t.load_complete = true;										// Mark indicator that window has finished loading
		}
	}
	this.add_onload_task = add_onload_task;
	
	function remove_all_children(obj)
	{
		// Removes all children, recursively
		for(var i=obj.children.length - 1; i>=0; i--)
		{
			this.remove_all_children(obj.children[i]);
			obj.removeChild(obj.children[i]);
		}
	}
	this.remove_all_children = remove_all_children;

	function bring_to_front(obj)
	{
		obj.style.zIndex = ++this.max_zIndex;
	}
	this.bring_to_front = bring_to_front;

	function send_to_back(obj)
	{
		obj.style.zIndex = --this.min_zIndex;
	}
	this.send_to_back = send_to_back;

	function create_dragger(dragbar, dragelem)
	{
		var lgth = this.draggers.length;
		this.draggers[lgth] = new HW_Dragger(dragbar, dragelem);
		return lgth;
	}
	this.create_dragger = create_dragger;

	function get_absolute_screen_position(elem)
	{
		var el = elem;
		var ret = new Object();
		ret.left = 0;
		ret.top = 0;
		while(el != document)
		{
			if(el.offsetTop && el.offsetLeft)
			{
				ret.left += el.offsetLeft;
				ret.top += el.offsetTop;
			}
			el = el.parentNode;
		}
		return ret;
	}
	this.get_absolute_screen_position = get_absolute_screen_position;

	function get_screen_scrolling_position()
	{
		var ret = new Object();
		if(window.pageYOffset)
		{
			ret.left = self.pageXOffset;
			ret.top = self.pageYOffset;
		}
		else if(document.documentElement && document.documentElement.scrollTop)
		{
			ret.left = document.documentElement.scrollLeft;
			ret.top = document.documentElement.scrollTop;
		}
		else if(document.body)
		{
			ret.left = document.body.scrollLeft;
			ret.top = document.body.scrollTop;
		}
		return ret;
	}
	this.get_screen_scrolling_position = get_screen_scrolling_position;

	function urlencode(str)
	{
		var s = str.toString();
		var ret = '';
		var hx = null;
		var c = null;
		for(var i=0; i<s.length; i++)
		{
			c = s.charAt(i);
			if((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') || c == '.' || c == '-' || c == '_') 
			{
				// Character OK
				ret = ret + c;
			}
			else if(s.charCodeAt(i)==32)		// for some reason, this doesn't work, so just use %20 for space
			{
				// Space becomes +
				ret = ret + '+';
			}
			else
			{
				// Other character requires a hex code
				hx = s.charCodeAt(i).toString(16);
				ret = ret + '%' + (hx.length==1 ? '0' : '') + hx.toUpperCase();
			}
		}
		return ret;
	}
	this.urlencode = urlencode;

	function alert(html, title, cssclass, onclick, w)
	{
		var popup = new HW_PopUp(title || 'System Message', null, w || window);
		popup.set_dimensions(200, 100);
		var m = w.document.createElement('p');
		m.innerHTML = html;
		popup.contentdiv.appendChild(m);
		var p = w.document.createElement('p');
		p.style.textAlign = 'center';
		popup.contentdiv.appendChild(p);
		var b = new Button();
		b.onclick = function () { popup.hide(); }
		b.value = 'OK';
		p.appendChild(b);
		popup.contentdiv.className = cssclass || 'HW_alert_div_class';
		if(onclick)
		{
			popup.onhide = onclick;
		}
		popup.show();
	}
	this.alert = function (h, t, c, o, w) { this.alert(h, t || 'Alert', c, o, w); }
	this.message = function (h, t, c, o, w) { this.alert(h, t || 'Message', c, o, w); }
}



////////////////////////////////////////////////////////////////////////////////
//  HTTP REQUEST OBJECT


window.HW_http_state_change = function (hwhttp)
{
	if(hwhttp.xmlhttp.readyState == 4)
	{
		if(hwhttp.xmlhttp.status != 200)
		{
			hwhttp.error = 'Error: ' + hwhttp.xmlhttp.status + ' ' + hwhttp.xmlhttp.statusText + '; status ' + hwhttp.xmlhttp.status;
			alert(hwhttp.error);
		}
		else
		{
			hwhttp.error = false;
		}
		hwhttp.on_response(hwhttp.use_xml_response ? hwhttp.xmlhttp.responseXML : hwhttp.xmlhttp.responseText);
	}
}

window.HW_http_request = function (url, uname, pwd)
{
	var cont = '';
	var nullcont = new Object();
	for(nm in (this.get_variable_override ? nullcont : this.content))
	{
		cont = cont + '&' + nm + '=' + this.content[nm];
	}
//	this.xmlhttp.open(this.method, url + '?' + cont.substring(1), this.async, uname || null, pwd || null);
	this.xmlhttp.open(this.method, 'includes/shared/ajax.php?url=' + HangWire.urlencode(url + '?' + cont.substring(1)), this.async, uname || null, pwd || null);
	var t = this;
	this.xmlhttp.onreadystatechange = function () { HW_http_state_change(t); t.onreadycalled = true; }
	for(nm in this.headers)
	{
		this.xmlhttp.setRequestHeader(nm, this.headers[nm]);
	}
	this.xmlhttp.send(null); //cont.length > 0 ? cont.substring(1) : null);
	if(!this.async && !this.onreadycalled)
	{
		this.on_response(this.use_xml_response ? this.xmlhttp.responseXML : this.xmlhttp.responseText);		// firefox bug workaround
	}
	this.onreadycalled = false;		// firefox bug workaround: reset for next use
}

window.HW_http_add_header_value = function (name, val)
{
	this.headers[name] = val;
}

window.HW_http_clear_content = function ()
{
	this.content = new Object();
}

window.HW_http_add_value = function (name, val)
{
	this.content[name] = val;
}

window.HW_HTTP = function ()
{
	this.error = false;
	if(window.XMLHttpRequest)		// Mozilla, etc.
	{
		this.xmlhttp = new XMLHttpRequest();
	}
	else if(window.ActiveXObject)	// IE
	{
		this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	if(!this.xmlhttp)
	{
		throw("Browser doesn't support XML HTTP requests.");
	}

	this.request = HW_http_request;
	this.add_value = HW_http_add_value;
	this.add_header_value = HW_http_add_header_value;
	this.clear_values = HW_http_clear_content;
	this.on_response = function (x) {}
	this.onreadycalled = false;								// firefox bug workaround
	this.get_variable_override = false;

	this.method = 'GET';
	this.async = true;
	this.use_xml_response = false;

	this.headers = new Object();
	this.content = new Object();

	// Prevent caching
	this.add_header_value('Cache-Control', 'no-cache');
	this.add_header_value('Pragma', 'no-cache');
	this.add_value('_', HangWire.unique_string());
}



////////////////////////////////////////////////////////////////////////////////
//  ENHANCED INPUT OBJECT
//  Enhances an input box with some cool features


function HW_ei_prohibit_characters(prohibited_string)
{
	// Prohibits all characters in prohibited_string from this input
	function returnfalse (input_obj) { return false; }

	for(i=0; i<prohibited_string.length; i++)
	{
		this.onkeypress_array[prohibited_string.charCodeAt(i)] = returnfalse;
	}
}

function HW_Enhanced_Input(input_object)
{
	// Syntax:
	// var hwei = HW_Enhanced_Input(document.getElementById('my_input_object_id'));

	// Optional:
	// hwei.onmouseover = function (input_obj) { do what you want with the input obj; default is below }
	// hwei.onenterpress = function () { alert('enter has been pressed'); }
	// hwei.onkeypress[13] = function () { alert('enter has been pressed'); }

	var t = this;
	this.input_object = input_object;

	// Methods
	this.prohibit_characters = HW_ei_prohibit_characters;
	
	// onmouseover function
	this.onmouseover = function (input_obj) { input_obj.focus(); input_obj.select(); }
	this.input_object.onmouseover = function () { t.onmouseover(t.input_object); }

	// onanykeypress function
	this.onanykeypress = function (input_obj, keycode) {}

	// onkeypress associative array of functions
	this.onkeypress_array = new Object();
	this.onkeypress = function (keycode) {
		if(this.onkeypress_array[keycode]) {
			this.onkeypress_array[keycode](this.input_object);			// call the function
		}
		this.onanykeypress(this.input_object, keycode);
	}

	// syntactic sugar: default key 13 (enter) to 'onenterpress' function so the programmer can just reassign that
	this.onenterpress = function (inputobj) {}
	this.onkeypress_array[13] = function (inputobj) { t.onenterpress(inputobj); }

	// finally, assign onkeypress to the input box
	this.input_object.onkeypress = function (e) {
		var key = window.event.keyCode || e.which;			// IE || Netscape
		if(key)
		{
			t.onkeypress(key);								// call the appropriate function if defined
		}
	}

}



////////////////////////////////////////////////////////////////////////////////
//  HANGWIRE OBJECT AND INCLUDE FUNCTION

window.HangWire = new HW_HTML_Helpers();

HangWire.include = function (filename)
{
	var h = new HW_HTTP();
	h.async = false;
	h.request(filename);
	eval(h.responseText);
}
