////////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// Javascript Generic API
//=================================================================================================
function Generic() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	Generic.SetOpacity = function(obj, opacity)
	{
		obj.style.filter = "alpha(opacity:" + opacity + ")";	// IE/Win 
		obj.style.KHTMLOpacity = opacity / 100;					// Safari<1.2, Konqueror 
		obj.style.MozOpacity = opacity / 100;					// Older Mozilla and Firefox
		obj.style.opacity = opacity / 100;						// Safari 1.2, newer Firefox and Mozilla, CSS3
	}

	Generic.ChangeClass = function(obj, class_name)
	{
		obj.className = class_name;
	}

	Generic.Enable = function(obj)
	{
		obj.disabled = false;
	}

	Generic.Disable = function(obj)
	{
		obj.disabled = true;
	}

	Generic.ScreenWidth = function()
	{
		return screen.width;
	}

	Generic.ScreenHeight = function()
	{
		return screen.height;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// Data Library (Access) API
//=================================================================================================
function DataLib() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	DataLib.States = function(input)
	{
		var states = new Array("AL","AK","AZ","AR","CA","CO","CT","DC","DE","FL","GA","HI","ID","IL","IN","IA","KS","KN","LA","ME","MD","MA","MI","MN","MS","MO","MT","NE","NV","NH","NJ","NM","NY","NC","ND","OH","OK","OR","PA","RI","SC","SD","TN","TX","UT","VT","VA","WA","WV","WI","WY");
		for (i = 0; i < states.length; i++)
		{
			if (input.toUpperCase() == states[i]) {return true;}
		}
		return false;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// Browser related API
//=================================================================================================
function Browser() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	Browser.Window = function(url, attributes, name)
	{
		url = (url == null ? "about:blank" : url);
		attributes = (attributes == null ? "" : attributes);
		name = (name == null ? "" : name);
		return window.open(url, name, attributes);
	}

	Browser.SetCookie = function(name, value, days)
	{
		if (days)
		{
			var date = new Date();
			if (days == "now")
			{
				date.setTime(date.getTime());
			}
			else
			{
				date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
			}
			var expires = "; expires=" + date.toGMTString();
		}
		else var expires = "";
		document.cookie = name + "=" + value + expires + "; path=/";
	}

	Browser.GetCookie = function(document_obj, cookie_name)
	{
		var nameEQ = cookie_name + "=";
		var ca = document_obj.cookie.split(';');
		for(var i = 0; i < ca.length; i++)
		{
			var c = ca[i];
			while (c.charAt(0) == ' ') c = c.substring(1, c.length);
			if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
		}
		return null;
	}

	Browser.DeleteCookie = function(name)
	{
		SetCookie(name, "", -1);
	}

	Browser.Dimensions = function()
	{
		return new Array(HTML.Width(element), HTML.Height(element));
	}

	Browser.Width = function()
	{
		if (document.all)
		{
			// IE4+ or IE6+ in standards compliant 
			return (document.documentElement.clientWidth ? document.documentElement.clientWidth : document.body.clientWidth);
		}
		else
		{
			// Non-IE
			return window.innerWidth;
		}
	}

	Browser.Height = function()
	{
		if (document.all)
		{
			// IE4+ or IE6+ in standards compliant 
			return (document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight);
		}
		else
		{
			// Non-IE
			return window.innerHeight;
		}
	}

	Browser.MouseXY = function(event)
	{
		return new Array(event.clientX, event.clientY);
	}

	Browser.AddEvent = function(e, type, handler, capture)
	{
		if (e.addEventListener)
		{
			e.addEventListener(type, handler, capture);
			return true;
		}
		else if (e.attachEvent)
		{
			var r = e.attachEvent("on" + type, handler);
			return r;
		}
		else
		{
			alert("Handler could not be removed");
		}
	}

	Browser.SelectZIndexFix = function(div, hide)
	{
		if (!hide)
		{
			if (!document.getElementById(div.id + "_mask"))
			{
				iframe = document.createElement("iframe");
				iframe.id = div.id + "_mask";
				iframe.style.position = "absolute";
				document.body.appendChild(iframe);
			}

			div.style.display = "block";
			div.style.zIndex = 100;

			
			iframe.style.width = div.offsetWidth;
			iframe.style.height = div.offsetHeight;
			iframe.style.top = div.style.top;
			iframe.style.left = div.style.left;
			iframe.style.zIndex = div.style.zIndex - 1;
			iframe.style.display = "block";
		}
		else
		{
				iframe.style.display = "none";
		}
	}

	Browser.ScrollTo = function(id)
	{
		document.getElementById(id).scrollIntoView();
		return false;
	}

	// Returns the version of Internet Explorer or a -1
	// (indicating the use of another browser).
	Browser.IEVersion = function()
	{
		var rv = -1; // Return value assumes failure.
		if (navigator.appName == 'Microsoft Internet Explorer')
		{
			var ua = navigator.userAgent;
			var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
			if (re.exec(ua) != null)
			rv = parseFloat( RegExp.$1 );
		}
		return rv;
	}
	
///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// XML related API
//=================================================================================================
function XML() {}	
///////////////////////////////////////////////////////////////////////////////////////////////////
	XML.HttpRequest = function()
	{
		if (window.XMLHttpRequest)
		{ // Mozilla, Firefox, and related browsers 
			request = new XMLHttpRequest();
			if (request.overrideMimeType)
			{
				request.overrideMimeType('text/xml');
			}
		}
		else if (window.ActiveXObject)
		{ // IE
			try {request = new ActiveXObject("Msxml2.XMLHTTP");}
			catch (e)
			{
				try {request = new ActiveXObject("Microsoft.XMLHTTP");}
				catch (e) {}
			}
		}
		if (!request)
		{
			alert('Cannot create XMLHTTP instance');
			return false;
		}
		return request;
	}

	XML.Parse = function(xml, node, key)
	{
		var xmldoc;
		if (typeof DOMParser != "undefined")
		{ // Mozilla, Firefox, and related browsers 
			xmldoc = (new DOMParser()).parseFromString(xml, "application/xml"); 
		} 
		else if (typeof ActiveXObject != "undefined")
		{ // IE
			xmldoc = new ActiveXObject("Msxml2.DOMDocument.3.0");
			xmldoc.loadXML(xml);
		}
		nodes = new Array();
		var results = xmldoc.getElementsByTagName(node);
		for (var i = 0; i < results.length; i++)
		{
			nodes.push(XML.ParseNode(results[i]));
		}
		return nodes;
	}

	XML.ParseNode = function(node)
	{
		var n = new Array();
		for (var j = 0; j < node.childNodes.length; j++)
		{
			if (node.childNodes[j].firstChild != null && node.childNodes[j].childNodes.length == 1 && node.childNodes[j].firstChild.firstChild == null)
			{
				// Only parse node if it is not empty
				if(node.childNodes[j].firstChild.nodeValue != "\n")
				{
					eval("n['" + node.childNodes[j].tagName + "'] = unescape('" + node.childNodes[j].firstChild.nodeValue + "');");
				}
			}
			else
			{
				var temp = XML.ParseNode(node.childNodes[j]);
				// Modified for shrinksafe compatibility
				//eval("n['" + node.childNodes[j].tagName + "'] = " + temp + ";");
				n[node.childNodes[j].tagName] = temp;
			}
		}
		return n;
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// XML related API
//=================================================================================================
function RPC(){}
///////////////////////////////////////////////////////////////////////////////////////////////////
		RPC.LastRequest = null;

		RPC.Restrain = function(func)
		{
			if (typeof(timeout) != "undefined"){clearTimeout(timeout);}
			timeout = setTimeout("eval("+func+")", 300);

			if(RPC.LastRequest != null && RPC.LastRequest.readyState < 4)
			{
				RPC.LastRequest.onreadystatechange = function() {};
				RPC.LastRequest.abort();
			}
 		}

///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// Formatting related API
//=================================================================================================
function Format() {}	
///////////////////////////////////////////////////////////////////////////////////////////////////
	Format.Phone = function(input)
	{
		format = "";
		var phone = input;
		phone = phone.replace(/\D/g, '');
		var c1 = phone.match(/^(\d{3})\d+$/);
		var c2 = phone.match(/^\d{3}(\d{3})\d{4}$/);
		var c3 = phone.match(/^\d+(\d{4})$/);
		return c1[1]+"-"+c2[1]+"-"+c3[1];
	}

	Format.Date = function(date, format)
	{
		/******************
		dd = day
		MM = month
		yy = year (or yyyy)
		hh = hours
		mm = minutes
		ss = seconds
		*******************/
		function _addZero(number) {return (number < 10 ? "0" : "") + number;}
		var day = _addZero(date.getDate());
		var month = _addZero(date.getMonth() + 1);
		var yearlong = _addZero(date.getFullYear());
		var yearshort = _addZero(date.getFullYear().toString().substring(3, 4));
		var year = (format.indexOf("yyyy") > -1 ? yearlong : yearshort);
		var hour = _addZero(date.getHours());
		var minute = _addZero(date.getMinutes());
		var second = _addZero(date.getSeconds());
		var formatted = format.replace(/dd/g, day).replace(/MM/g, month).replace(/y{1,4}/g, year);
		return formatted.replace(/hh/g, hour).replace(/mm/g, minute).replace(/ss/g, second);
	} 

	Format.Number = function(value, precision, seperator)
	{
		precision = (precision == null ? 2 : precision);
		seperator = (seperator == null ? "" : seperator);
		var result = (precision > 0 ? parseFloat(value).toFixed(precision) : Math.round(value));
		if (isNaN(result)) {return "";}
		if (seperator)
		{
			result += "";
			x = result.split(".");
			x1 = x[0];
			x2 = (x.length > 1 ? "." + x[1] : "");
			var rgx = /(\d+)(\d{3})/;
			while (rgx.test(x1))
			{
				x1 = x1.replace(rgx, '$1' + seperator + '$2');
			}
			result = x1 + x2;
		}
		return result;
	}

	Format.Currency = function(value, prefix, precision)
	{
		prefix = (prefix == null ? "$" : prefix);
		precision = (precision == null ? 2 : precision);
		value = (value + "").replace(/[$\,]/g, "");
		var result = Format.Number(value, precision, ",");
		return (result.length > 0 ? prefix + result : result);
	}
///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// Validation related API
//=================================================================================================
function Validate() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	Validate.Phone = function(phone)
	{
		phone = myString.Trim(phone);
		phone = phone.replace(/\s+/g, ' ');
		return /^\({0,1}\d{3}[ \)\.-]{0,1}\d{3}[ \)\.-]{0,1}\d{4}$/.test(phone);
	}

	Validate.Email = function(e, notify)
	{
		notify = (notify == null || notify ? true : false);
		var v = e.value;
		var isValid = v.match(/\b[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b/i);
		if (!notify) {return isValid;}
		if (!isValid)
		{
			alert("Invalid email address!");
			e.focus();
			e.select();
			return false;
		}
		else
		{
			return true;
		}
	}

	Validate.State = function(e)
	{
		var v = e.value;
		if (v == "") {return true;}
		if (!DataLib.States(v))
		{
			alert("Invalid state entry!!");
			e.select();
			e.focus();
			return false;
		}
		else
		{
			e.value.toUpperCase();
			return true;
		}
	}
	
	Validate.Zip = function(e)
	{
		v = e.value;
		if (v == "") {return true;}
		else if (/^\d{5}$/.test(v)) {return true;}
		else if (/^\d{5}-\d{4}$/.test(v)) {return true;}
		else
		{
			alert("Invalid zip code entry!");
			e.focus();
			return false;
		}
	}

	Validate.IsDate = function(input)
	{
		input = input.replace(/\s/g, '');
		if (/^\d{2}\/\d{2}\/\d{4}$/.test(input)) {return true;}
		else {return false;}
	}

	/* Shrinksafe cannot parse.  Is not in use currently
	Validate.URL = function(url)
	{
		var regx = /(ftp|http|file):\/\/[^/]+\.(com|edu|biz|org|gov|info|mil|net|[a-z][a-z])$/;
		return regx.test(url);
	}
	*/

	Validate.Currency = function(currency)
	{
		currency = (currency + "").replace(/[$\,]/g, "");
		var regx = /^((\$\d*)|(\$\d*\.\d{2})|(\d*)|(\d*\.\d*))$/;
		return regx.test(currency);
	}

	Validate.Numeric = function(value)
	{
		return !isNaN(value);
	}

	Validate.Integer = function(value)
	{
		var regx = /^\d+\.*0*$/;
		return regx.test(value);
		//return !isNaN(parseInt(value));
	}

	Validate.RegisterForm = function(name)
	{
		var form = document.getElementById(name);
		var textboxes = document.getElementsByTagName("input");
		var selectlists = document.getElementsByTagName("select");
		var inputs = new Array();
		for (var i = 0; i < textboxes.length; i++)
		{
			if (textboxes[i].type == "text") {inputs[inputs.length] = textboxes[i];}
		}
		for (var i = 0; i < selectlists.length; i++)
		{
			inputs[inputs.length] = selectlists[i];
		}
		for (var i = 0; i < inputs.length; i++)
		{
			var require = inputs[i].getAttribute("require");
			if (require != null)
			{
				inputs[i].onblur = function() {Validate.Required("onblur", this);};
				inputs[i].onchange = function() {Validate.Required("onchange", this);};
				inputs[i].onpaste = function() {Validate.Required("onpaste", this);};
				inputs[i].onkeyup = function() {Validate.Required("onkeyup", this);};
				Validate.Required("onload", inputs[i]);
			}
		}
	}

	Validate.IsComplete = function(form)
	{
		var ready = true;
		for (var i = 0; i < form.elements.length; i++)
		{
			var require = form.elements[i].getAttribute("require");
			var invalid = form.elements[i].getAttribute("invalid");
			ready = (require != null && form.elements[i].className == invalid ? false : ready);
		}
		return ready;
	}

	Validate.Form = function(form)
	{
		var ready = true;
		for (var i = 0; i < form.elements.length; i++)
		{
			var require = form.elements[i].getAttribute("require");
			var valid = form.elements[i].getAttribute("valid");
			var invalid = form.elements[i].getAttribute("invalid");
			var handler = form.elements[i].getAttribute("handler");
			var additional = (handler != null ? eval(handler) : true);
			ready = (require != null && form.elements[i].className == invalid ? false : ready);
			ready &= additional; 
		}
		for (var i = 0; i < form.elements.length; i++)
		{
			if (form.elements[i].type == "submit")
			{
				form.elements[i].disabled = !ready;
			}
		}
		return ready;
	}

	Validate.Required = function(e, element)
	{
		var format = false;
		var require = element.getAttribute("require");
		var valid = element.getAttribute("valid");
		var invalid = element.getAttribute("invalid");
		var handler = element.getAttribute("handler");
		switch (require)
		{
			case "currency":
				format = (e == "onload" || e == "onblur" || e == "onchange");
				element.className = (element.value != "" && Validate.Currency(element.value) ? valid : invalid);
				if (format && element.className == valid) {element.value = Format.Currency(element.value);}
				break;
			case "numeric":
				format = (e == "onload" || e == "onblur" || e == "onchange");
				element.className = (element.value != "" && Validate.Numeric(element.value) ? valid : invalid);
				if (format && element.className == valid) {element.value = Format.Number(element.value);}
				break;
			case "integer":
				format = (e == "onload" || e == "onblur" || e == "onchange");
				element.className = (element.value != "" && Validate.Numeric(element.value) ? valid : invalid);
				if (format && element.className == valid) {element.value = Format.Number(element.value, 0);}
				break;
			case "phone":
				element.className = (element.value != "" && Validate.Phone(element.value) ? valid : invalid);
				if (element.className == valid && !/^\d{3}-\d{3}-\d{4}$/.test(element.value)) {element.value = Format.Phone(element.value);}
				break;
			case "email":
				element.className = (element.value != "" && Validate.Email(element, false) ? valid : invalid);
				break;
			case "string":
				element.className = (element.value != "" && myString.Trim(element.value).length > 0 ? valid : invalid);
				break;
			case "prh-address":
				element.className = (element.value != "" && myString.Trim(element.value).length > 0 ? valid : invalid);
				break;
		}
		if (handler != null && eval(handler)) {Validate.Form(element.form);}
	}
///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// Date/Time related API
//=================================================================================================
function DateTime() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	DateTime.Add = function(date, days)
	{
		return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
	}

	DateTime.Difference = function(date1, date2)
	{
		var day_in_milliseconds = 1000 * 60 * 60 * 24;
		return Math.ceil((date1.getTime() - date2.getTime()) / day_in_milliseconds);
	}

	DateTime.FromString = function(str, format, separator)
	{
		var date;
		var tokens;
		var d, m, y;
		try
		{
			if (str.indexOf(separator) >= 0) {tokens = str.split(separator);}
			else {tokens = false;}
			if (tokens)
			{
				switch (format)
				{
					case "dmy":
						d = parseInt(tokens[0], 10);
						m = parseInt(tokens[1], 10) - 1;
						y = parseInt(tokens[2], 10);
						break;
					case "ymd":
						d = parseInt(tokens[2], 10);
						m = parseInt(tokens[1], 10) - 1;
						y = parseInt(tokens[0], 10);
						break;
					case "mdy":
					default :
						d = parseInt(tokens[1], 10);
						m = parseInt(tokens[0], 10) - 1;
						y = parseInt(tokens[2], 10);
						break;
				}
				date = new Date(y, m, d);
			}
			else if (str)
			{
				date = new Date(str);
			}
			else
			{
				date = new Date();
			}
		}
		catch(e)
		{
			date = new Date();
		}
		return date;
	}

	DateTime.ToString = function(date, format, separator)
	{
		var str;
		var day = "00" + date.getDate();
		var month = "00" + (date.getMonth() + 1);
		day = day.substring(day.length - 2);
		month = month.substring(month.length - 2);
		switch (format)
		{
			case "dmy":
				str = day + separator + month + separator + date.getFullYear();
			case "ymd":
				str = date.getFullYear() + separator + month + separator + day;
			case "mdy":
			default :
				str = month + separator + day + separator + date.getFullYear();
		}
		return str;
	}
///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// HTML related API
//=================================================================================================
function HTML() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	/*
	   Adds an html hidden input field to the given HTML form element.
	   @param formElement the given HTML form element
	   @param fieldName the name of the hidden input field
	   @param fieldValue the (string) value of the hidden input field
	*/
	HTML.AddHiddenInputField = function(formElement, fieldName, fieldValue)
	{
		var inputElement = document.createElement("input")
		inputElement.setAttributeNode(HTML.CreateHtmlAttribute("type", "hidden"));
		inputElement.setAttributeNode(HTML.CreateHtmlAttribute("id", fieldName));
		inputElement.setAttributeNode(HTML.CreateHtmlAttribute("name", fieldName));
		inputElement.setAttributeNode(HTML.CreateHtmlAttribute("value", fieldValue));
		formElement.appendChild(inputElement);
		return;
	}
	/*
	   Creates an html attribute.
	   @param name the name of the attribute.
	   @param value the (string) value of the attribute.
	   @return the newly created html attribute
	*/
	HTML.CreateHtmlAttribute = function(name, value)
	{
		var attribute = document.createAttribute(name);
		attribute.nodeValue = value;
		return attribute;
	}

	HTML._SetHtmlAttribute = function(element, name, value)
	{
		element.setAttributeNode(HTML.CreateHtmlAttribute(name, value));
	}

	HTML.SelectedValues = function(selectList)
	{
		var selected = new Array();
		var count = 0;
		for (var i = 0; i < selectList.options.length; i++)
		{
			if (selectList.options[i].selected)
			{
				selected[count] = selectList.options[i].value;
				count++;
			}
		}
		return selected;
	}

	HTML.SelectAll = function(select)
	{
		if (typeof select == "string") {select = document.getElementById(select);}
		if (select.type == "select-multiple")
		{
			for (var i = 0; i < select.options.length; i++) {select.options[i].selected = true;}
		}
	}

	HTML.SetSelected = function(select, value)
	{
		for (var i=0 ; i<select.options.length ; i++)
		{
			if (select.options[i].innerHTML == value)
			{
				select.selectedIndex = i;
				return;
			}
		}
	}

	HTML.RemoveNode = function(id, doc)
	{
		doc = (doc != null ? doc : document);
		var element = doc.getElementById(id);
		element.parentNode.removeChild(element);
	}

	HTML.GetParent = function(e, tagName)
	{
		if (e == null) {return null;}
		else if (e.nodeType == 1 && e.tagName.toLowerCase() == tagName.toLowerCase()) {return e;}
		else {return HTML.GetParent(e.parentNode, tagName);}
	}

	HTML.GetParentByClass = function(e, className)
	{
		if (e == null) {return null;}
		else if (e.nodeType == 1 && e.className.toLowerCase() == className.toLowerCase()) {return e;}
		else {return HTML.GetParentByClass(e.parentNode, className);}
	}

	// Returns cell from row and cell number
	// Browser indenpendent
	HTML.CellAccessor = function(row, cellNum)
	{
		var xmldoc;
		if (typeof DOMParser != "undefined")
		{ // Mozilla, Firefox, and related browsers 
			return row.cells[cellNum];
		} 
		else if (typeof ActiveXObject != "undefined")
		{ // IE
			return row.childNodes[cellNum];
		}
	}

	HTML.SortSelect = function(select) 
	{
		var optionsArray = new Array();
		var valueKeyArray = new Array();

		for(i=0; i<select.length; i++)  
		{
			optionsArray[i] = select.options[i].text;
			valueKeyArray[select.options[i].text] = select.options[i].value;
		}

		optionsArray.sort();

		for(i=0; i<select.length; i++)  
		{
			select.options[i].text = optionsArray[i];
			select.options[i].value =  valueKeyArray[optionsArray[i]];
		}
		return select;
	}

	HTML.AddSelectOption = function(select, option_text, option_value, selected)
	{
		var o = document.createElement("option");
		o.text = option_text;
		o.value = option_value;
		o.selected = selected;
		try {select.add(o, null);}		// standards compliant; doesn't work in IE
		catch (e) {select.add(o);}	// IE only
	}
	
	HTML.Position = function(element)
	{
		return new Array(HTML.GetX(element), HTML.GetY(element));
	}

	HTML.GetX = function(element)
	{
		var left = 0;
		if (element.offsetParent)
		{
			left = element.offsetLeft
			while (element = element.offsetParent) {left += element.offsetLeft}
		}
		else if (element.x) {left += element.x;}
		return left;
	}

	HTML.GetY = function(element)
	{
		var top = 0;
		if (element.offsetParent)
		{
			top = element.offsetTop
			while (element = element.offsetParent) {top += element.offsetTop}
		}
		else if (element.y) {top += element.y;}
		return top;
	}

	HTML.GetSize = function(element)
	{
		return new Array(HTML.Width(element), HTML.Height(element));
	}

	HTML.Width = function(element)
	{
		return element.offsetWidth;
	}

	HTML.Height = function(element)
	{
		return element.offsetHeight;
	}

	HTML.DisableOnClick = function(obj, disable)
	{
		if(disable)
		{
			if(obj.onclick && obj.onclick != "" && obj.onclick != null)
			{
				obj.onclick_bak = obj.onclick;
			}
			obj.onclick = "";
		}
		else
		{
			try	
			{
				if (obj.onclick_bak && obj.onclick_bak != "" && obj.onclick_bak != null) {obj.onclick = obj.onclick_bak;}
			}
			catch(e){}
		}
	}

	HTML.DisableAnchor = function(obj, disable)
	{
		if(disable)
		{
			var href = obj.href;
			if(href && href != "" && href != null)
			{
				obj.href_bak = href;
			}
			try{obj.removeAttribute('href');}
			catch(e){};
			obj.style.color = "gray";
		}
		else
		{
			try	
			{
				if (obj.href_bak)
				{
					obj.setAttribute('href', obj.href_bak);
					obj.style.color = "";
				}
			}
			catch(e){};
		}
	}

	HTML.GetEventTarget = function(e)
	{
		var target;
		if (!e) {var e = window.event;}
		if (e.target) {target = e.target;}
		else if (e.srcElement) {target = e.srcElement;}
		if (target.nodeType == 3)
		{
			// defeat Safari bug
			target = target.parentNode;
		}
		return target;
	}

	HTML.Display = function(id, visible)
	{
		var element = document.getElementById(id);
		visible = (typeof(visible) == "undefined" ? (element.style.display == "none" || element.style.display == "" ? true : false) : visible);
		element.style.display = (visible ? "block" : "none");
	}

	HTML.SwapImage = function(image, src)
	{
		var i = new Image();
		i.src = src;
		//i.onload = function() {image.src = i.src; return true;};
		i.onload = function() {image.setAttribute("src", i.src); return true;};
		return true;
	} 

	HTML.SimplePreload = function(imagePaths)
	{
		__PRELOADED_IMAGES__ = new Array();
		for(var i=0; i<imagePaths.length; i++) 
		{
			__PRELOADED_IMAGES__[i] = new Image();
			__PRELOADED_IMAGES__[i].src=imagePaths[i];
		}	
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// 
//	Image Preloader related API - loads images incrementally by utilizing the onload method 
//		attached to last loaded image.  A new images will not be loaded untill the current
//		image is cached.  callback will fire on each image completion where as finalCallback
//		will only fire when all images are cached.
//  
//=================================================================================================
function Preloader() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	Preloader.Callback = null;
	Preloader.FinalCallback = null;
	Preloader.Images = new Array;
	Preloader.Processing = 0;
	Preloader.Complete = 0;

	Preloader.Start = function(imgs, callback, finalCallback)
	{
		Preloader.Images = imgs;
		Preloader.Callback = callback;
		Preloader.FinalCallback = finalCallback;
		Preloader.LoadImage(Preloader.Images[0]);
	}

	Preloader.LoadImage = function()
	{
		var newImage = new Image;
		
		//alert(Preloader.Processing + " ," + Preloader.Images.length);
		if(Preloader.Processing == (Preloader.Images.length - 1))
		{
			newImage.onload = function(){ eval(Preloader.FinalCallback); };
		}
		else
		{
			newImage.onload = function(){ Preloader.LoadImage(); eval(Preloader.Callback); Preloader.Complete++; };
		}

		Preloader.Processing++;
		newImage.src = Preloader.Images[Preloader.Processing - 1];
	}

///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// Array related API
//=================================================================================================
function Arrays() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	Array.Contains = function(needle, haystack, assoc)
	{ 
		if (assoc)
		{
			for (var k in haystack)
			{
				if (haystack[k][assoc] == needle) {return true;}
			}
			return false;
		}
		else
		{
			for (var k in haystack)
			{
				if (haystack[k] == needle) {return true;}
			}
			return false;
		}
	}

	Array.KeyExists = function(key, array)
	{ 
		for (var k in array)
		{
			if (k == key) {return true;}
		}
		return false;
	}
///////////////////////////////////////////////////////////////////////////////////////////////////
//=================================================================================================
// String related API
//=================================================================================================
function myString() {}
///////////////////////////////////////////////////////////////////////////////////////////////////
	myString.TrimL = function(str)
	{
		var regx = /^\s+/;
		return str.replace(regx, "");
	}

	myString.TrimR = function(str)
	{
		var regx = /\s+$/;
		return str.replace(regx, "");
	}

	myString.Trim = function(str)
	{
		return myString.TrimR(myString.TrimL(str));
	}
	
	myString.PricePoint = function(price)
	{
		var prefix = "High $";
		var base = parseFloat(price) / 100000;
		if (base < (Math.floor(base) + 0.4)) {prefix = "Low $";}
		else if (base < (Math.floor(base) + 0.74)) {prefix = "Mid $";}
		return prefix + (Math.floor(base) * 100) + "s";
	}
