LSD = {
	dom : {
		ready : function(f) {
			if (LSD.dom.ready.done) return f();
			if (LSD.dom.ready.timer) {
				LSD.dom.ready.ready.push(f);
			} else {
				LSD.events.add(window, 'load', LSD.dom.is_ready);
				LSD.dom.ready.ready = [f];
				LSD.dom.ready.timer = setInterval(LSD.dom.is_ready, 20);
			}
		},
		is_ready : function() {
			if (LSD.dom.ready.done) return false;  // Choke should this be return true?
			if (document && document.getElementsByTagName && document.getElementById && document.body) {
				clearInterval(LSD.dom.ready.timer);
				LSD.dom.ready.timer = null;
				for (var i = 0 ; i < LSD.dom.ready.ready.length ; i++) {
					LSD.dom.ready.ready[i]();
				}
				LSD.dom.ready.ready = null;
				LSD.dom.ready.done = true;
			}
		},
		previous_sibling : function(elem) {
			do {
				var elem = elem.previousSibling;
			} while (elem && elem.nodeType != 1);
			return elem;
		},
		next_sibling : function(elem) {
			do {
				var elem = elem.nextSibling;
			} while (elem && elem.nodeType != 1);
			return elem;
		},
		first_child : function(elem) {
			var elem = elem.firstChild;
			return elem && elem.nodType != 1 ? LSD.dom.next_sibling(elem) : elem;
		},
		last_child : function(elem) {
			var elem = elem.lastChild;
			return elem && elem.nodType != 1 ? LSD.dom.previous_sibling(elem) : elem;
		},
		parent : function(elem, generation) {
			generation = generation || 1;
			for (var i = 0 ; i < generation ; i++)
				if (elem != null) elem = elem.parentNode;
			return elem;
		},
		children : function(elem) {
			var currentChild = LSD.dom.first_child(elem);
			var children = new Array();
			var counter = 0;
				children[counter++] = currentChild;
			while (currentChild != LSD.dom.last_child(elem)) {
					children[counter++] = currentChild = LSD.dom.next_sibling(currentChild);
			}
			return children;
		},
		insert_before : function(insert, before, parent, animate) {
			var parent = parent || before.parentNode;
			var insert = LSD.dom.prepare_insert(insert);
			var node = [];
			for (var i = 0 ; i < insert.length ; i++) {
				if (animate) LSD.animate.hide(insert[i]);
				parent.insertBefore(insert[i], before);
				node.push(insert[i]);
				if (animate) LSD.animate.fade_in(insert[i]);
			}
			return node;
		},
		insert_after : function(insert, after, parent, animate) {
			var parent = parent || after.parentNode;
			var insert = LSD.dom.prepare_insert(insert);
			var node = [];
			for (var i = insert.length-1 ; i >= 0 ; i--) {
				if (animate) LSD.animate.hide(insert[i]);
				parent.insertBefore(insert[i], LSD.dom.next_sibling(after));
				node.push(insert[i]);
				if (animate) LSD.animate.fade_in(insert[i]);
			}
			return node;
		},
		insert_first : function(insert, parent) {
			var insert = LSD.dom.prepare_insert(insert);
			var node = [];
			for (var i = insert.length-1 ; i >= 0 ; i--) {
				parent.insertBefore(insert[i], LSD.dom.first_child(parent));
				node.push(insert[i]);
			}
			return node;
		},
		insert_last : function(insert, parent) {
			var insert = LSD.dom.prepare_insert(insert);
			var node = [];
			for (var i = 0 ; i < insert.length ; i++) {
				parent.appendChild(insert[i]);
				node.push(insert[i]);
			}
			return node;
		},
		replace_node : function (replacee, replaceor) {
			try {
				replacee.parentNode.replaceChild(replaceor, replacee);
				return true;
			} catch(e) {
				return false;
			}
		},
		prepare_insert : function(a) {
			var r = [];
			if (a.constructor != Array) a = [a];
			for (var i = 0 ; i < a.length ; i++) {
				if (a[i].constructor == String) {
					var div = document.createElement('div');
					div.innerHTML = a[i];
					for (var j = 0 ; j < div.childNodes.length ; j++) {
						r.push(div.childNodes[j])
					}
				} else if (a[i].length) {
					for (var j = 0 ; j < a[i].length ; j++) {
						r.push(a[i][j]);
					}
				} else {
					r.push(a[i]);
				}
			}
			return r;
		},
		create : function(elem) {
			return document.createElementNS ?
				document.createElementNS('http://www.w3.org/1999/xhtml', elem) :
				document.createElement(elem);
		},
		remove : function(elem) {
			if (elem) elem.parentNode.removeChild(elem);
		},
		remove_children : function(elem) {
			while (elem.firstChild) {
				LSD.dom.remove(elem.firstChild);
			}
		},
		text : function(elem) {
			r = '';
			elem = elem.childNodes || elem;
			for (var i = 0 ; i < elem.length ; i++) {
				r += elem[i].nodeType != 1?elem[i].nodeValue:LSD.dom.text(elem[i].childNodes);
			}
			return r
		},
		get : function(attribute, value, tag, parent) {
			if (attribute == 'tag') return (tag || document).getElementsByTagName(value);
			if (attribute == 'id') return (tag || document).getElementById(value);
			var attribute = {'for' : 'htmlFor', 'class' : 'className'}[attribute] || attribute;
			if (attribute == 'className') {
				var regex = new RegExp("(^|\\s)"+value+"(\\s|$)");
			} else {
				var value = value.replace(/(\[\])/, '\\$1');
				var regex = new RegExp("^"+value+"$");
			}
			var elements = [];
			var allTags = (parent || document).getElementsByTagName(tag||"*");
			for (var i = 0 ; i < allTags.length ; i++) {
				if (regex.test(allTags[i][attribute])) {
					elements.push(allTags[i]);
				}
			}
			return elements.length>0?elements:false;
		}
	},
	events : {
		add : function(elem, type, handler) {
			if (!LSD.events.add.guid) LSD.events.add.guid = 1;
			if (!handler.$$guid) handler.$$guid = LSD.events.add.guid++;
			if (!elem.events) elem.events = {};
			var handlers = elem.events[type];
			if (!handlers) {
				handlers = elem.events[type] = {};
				if (elem['on' + type]) {
					handlers[0] = elem['on' + type];
				}
			}
			handlers[handler.$$guid] = handler;
			elem['on' + type] = LSD.events.handle_event;
		},
		remove : function(elem, type, handler, all_events) {
			if (elem.events && elem.events[type]) {
				if (all_events === true) {
					delete elem.events[type];
				} else {
					delete elem.events[type][handler.$$guid];
				}
			}
		},
		handle_event : function(event) {
			var return_value = true;
			event = event || LSD.events.fix_event(window.event);
			var handlers = this.events[event.type];
			for (var i in handlers) {
				this.$$handle_event = handlers[i];
				if (this.$$handle_event(event) === false) {
					return_value = false
				}
			}
			return return_value;
		},
		fix_event : function(event) {
			event.preventDefault = function() {
				this.returnValue = false;
			}
			event.stopPropagation = function() {
				this.cancelBubble = true;
			}
			return event;
		}
	},
	form : {
		validate : function(elem) {
			LSD.dom.ready(function() {
				if (document.getElementById(elem)) {
					elem = [document.getElementById(elem)];
				} else if (LSD.dom.get('class', elem).length > 0) {
					elem = LSD.dom.get('class', elem);
				} else if (LSD.dom.get('tag', 'form').length > 0) {
					elem = LSD.dom.get('tag', 'form');
				} else { return; }
				for (var i = 0 ; i < elem.length ; i++) {
					LSD.form.set_up(elem[i]);
				}
			});
		},
		set_up : function(form) {
			LSD.form.validate_form(form, true);
			LSD.events.add(form, 'submit', function() { return LSD.form.validate_form(form); });
			for (var i = 0 ; i < form.elements.length ; i++) {
				LSD.events.add(form.elements[i], 'change', function() { LSD.form.validate_field(this); });
//				LSD.events.add(form.elements[i], 'blur', function() { LSD.form.hide_errors(this); LSD.form.validate_field(this); });
			}
		},
		validate_form : function(form, load) {
			var valid = true;
			for (var i = 0 ; i < form.elements.length ; i++) {
				if (!load) LSD.form.hide_errors(form.elements[i]);
				if (form.elements[i].nodeName != 'FIELDSET') {
					if (LSD.form.validate_field(form.elements[i], load)) valid = false;
				}
			}
			if (valid && !load && form.ajax) {
				return LSD.ajax.send(form);
			} else {
				return valid;
			}
		},
		validate_field : function(elem, load) {
			var errors = [];
			for (var name in LSD.form.form_error) {
				var regex = new RegExp('(^|\\s)' + name + '(\\s|$)');
				if (regex.test(elem.className) && !LSD.form.form_error[name].test(elem, load)) {
					errors.push(LSD.form.form_error[name].message);
				}
			}
			if (errors.length) {
				if (elem.type == "checkbox" || elem.type == "radio") elem = elem.parentNode.parentNode;
				LSD.form.show_errors(elem, errors);
			}
			return errors.length > 0;
		},
		get_inputs_by_name : function(name) {
			var results = LSD.dom.get('name', name, 'input');
			r = 0;
			for (var i = 0 ; i < results.length ; i++) {
				if (results[i].checked) r++;
			}
			return r;
		},
		hide_errors : function(elem) {
			var next = elem.nextSibling;
			if (next && next.nodeName == "UL" && next.className == 'errors') {
				elem.parentNode.removeChild(next);
			}
		},
		show_errors : function(elem, errors) {
			if (LSD.dom.next_sibling(elem).nodeName == 'SPAN') {
				var elem = LSD.dom.next_sibling(next);
			}
			var next = LSD.dom.next_sibling(elem);
			if (next && (next.nodeName != 'UL' || next.className != 'errors')) {
				next = document.createElement('ul');
				next.className = 'errors';
				next.style.display = 'none';
				elem.parentNode.insertBefore(next, elem.nextSibling);
			}
			for (var i = 0 ; i < errors.length ; i++) {
				LSD.dom.remove_children(next);
				var li = document.createElement('li');
				li.innerHTML = errors[i];
				next.appendChild(li);
			}
//			Add a class to the fields with errors
//			elem.className = elem.className + ' errors';
			LSD.animate.fade_in(next);
		},
		form_error : {
			email : {
				message : "Please double check the email address.",
				test : function (elem) {
					return !elem.value || /^[a-z0-9_+.-]+\@([a-z0-9-]+\.)+[a-z0-9]{2,4}$/i.test(elem.value);
				}
			},
			phone : {
				message : "Please double check the phone number, should be 7 digits.",
				test : function (elem) {
					var m = /(\d{3}).*(\d{3}).*(\d{4})/.exec(elem.value);
					if (m) elem.value = m[1] + '-' + m[2] + '-' + m[3];
					return !elem.value || m;
				}
			},
			date : {
				message : "Not a valid date, should be MM/DD/YYYY.",
				test : function(elem) {
					var months = new Array('january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september', 'october', 'november', 'december');
					for (var i in months) {
						var regex = new RegExp(months[i].substring(0,3)+((months[i].substring(3).length > 0)?'('+months[i].substring(3)+')?':''), 'i');
						elem.value = elem.value.replace(regex, parseFloat(i)+1);
					}
					var valid = true;
					var m = /(\d{1,2})[^\d]*(\d{1,2})[^\d]*(\d{2,4})/.exec(elem.value);
					if (m) {
						var month = (m[1].length == 1)?'0'+m[1]:m[1];
							var valid = (parseFloat(month) > 0 && parseFloat(month) <=12)?valid:false;
						var day = (m[2].length == 1)?'0'+m[2]:m[2];
							var valid = (parseFloat(day) > 0 && parseFloat(day) <=31)?valid:false;
						var date = new Date();
						var cur_year = date.getYear();
						var year = (m[3].length == 2)?
							((m[3] > cur_year-90)?
								'19'+m[3]:
								'20'+m[3]
							):
							m[3];
							var valid = (year.length == 4)?valid:false;
						elem.value = month + '/' + day + '/' + year;
					}
					return !elem.value || (m && valid);
				}
			},
			url : {
				message : "Please double check the web address (url).",
				test : function (elem) {
					if ((elem.value != '') && !/^https?:\/\//.test(elem.value)) {
						elem.value = "http://"+elem.value;
					}
					return !elem.value || /^https?:\/\/([a-z0-9-]+\.)+[a-z0-9]{2,4}.*$/.test(elem.value);
				}
			},
			zip : {
				message : "Please double check your zip code.",
				test : function (elem) {
					return !elem.value || /^\d{5}(-\d{4})?$/.test(elem.value);
				}
			},
			password : {
				message : "Password must be 8 characters and contain both numbers and letter.",
				test : function (elem) {
					return !elem.value || (elem.value.length > 7 && (/[0-9]/.test(elem.value) && /[a-z]/i.test(elem.value)));
				}
			},
			pass_confirm : {
				message : "Confirmation does not match the password entered.",
				test : function (elem) {
					var input = elem.parentNode.getElementsByTagName('input');
					for (var i = 0 ; i < input.length ; i++) {
						if (/(^|\s)password(\s|$)/.test(input[i].className)) var password = input[i].value;
						if (/(^|\s)pass_confirm(\s|$)/.test(input[i].className)) var pass_confirm = input[i].value;
					}
					return (!password && !elem.value) || (password && pass_confirm && password == pass_confirm);
				}
			},
			integer : {
				message : "Only Numbers are allowed.",
				test : function (elem) {
					elem.value = elem.value.replace(/[^\d]/g, '');
					return !elem.value || /^\d*$/.test(elem.value);
				}
			},
			float : {
				message : "Only numbers and a decimal are allowed.",
				test : function (elem) {
					m = /\d+(\.\d*)?/.exec(elem.value);
					if (m) {
						elem.value = m[0];
					}
					return !elem.value || /^\d+(\.\d*)?$/.test(elem.value);
				}
			},
			required : {
				message : "The field above is required.",
				test : function (elem, load) {
					if (elem.type == "checkbox" || elem.type == "radio") {
						return LSD.form.get_inputs_by_name(elem.name) > 0 || load;
					}
					return elem.value.length > 0 || load || (elem.value == elem.defaultValue && elem.value != '');
				}
			}
		}
	},
	style : {
		get : function(elem, name) {
			if (elem.style[name]) {
				return elem.style[name];
			} else if (elem.currentStyle) {  // for IE
				return elem.currentStyle[name];
			} else if (document.defaultView && document.defaultView.getComputedStyle) {  // for FF, safari
				
				if (name == 'padding') {
					return LSD.style.get(elem, "padding-top")+' '+LSD.style.get(elem, "padding-right")+' '+LSD.style.get(elem, "padding-bottom")+' '+LSD.style.get(elem, "padding-left");
				}
				name = name.replace(/(A-Z)/g, "-$1");
				name = name.toLowerCase(); 
				try {
					return document.defaultView.getComputedStyle(elem, null).getPropertyValue(name);
				} catch(e) { // For safari 2 display:hidden bug
					var old = LSD.style.reset_css(elem, { display : 'block', visibility : 'hidden', position: 'absolute' });
					var r = document.defaultView.getComputedStyle(elem, null).getPropertyValue(name);
					LSD.style.restore_css(elem, old);
					return r;
				}
			} else {
				return null;
			}
		},
		reset_css : function(elem, prop) {
			var old = {};
			for (var i in prop) {
				old[i] = elem.style[i];
				elem.style[i] = prop[i];
			}
			return old;
		},
		restore_css : function(elem, prop) {
			for (var i in prop) {
				elem.style[i] = prop[i];
			}
		}
	},
	element : {
		attribute : function(elem, attribute, value) {
			if (!attribute || attribute.constructor != String) return '';
			attribute = {'for' : 'htmlFor', 'class' : 'className'}[attribute] || attribute;
			if (typeof value != 'undefined') {
				elem[attribute] = value;
				if (elem.setAttribute) {
					elem.setAttribute(attribute, value);
				}
			}
			return elem[attribute] || elem.getAttribute(attribute) || elem.style[attribute] || '';
		},
		x : function(elem) {
			return elem.offsetParent ?
				elem.offsetLeft + LSD.element.x(elem.offsetParent) :
				elem.offsetLeft;
		},
		y : function(elem) {
			return elem.offsetParent ?
				elem.offsetTop + LSD.element.y(elem.offsetParent) :
				elem.offsetTop;
		},
		to_parent_x : function(elem) {
			return elem.parentNode == elem.offsetParent ?
				elem.offsetLeft :
				LSD.element.x(elem) - LSD.element.x(elem.parentNode);
		},
		to_parent_y : function(elem) {
			return elem.parentNode == elem.offsetParent ?
				elem.offsetTop :
				LSD.element.y(elem) - LSD.element.y(elem.parentNode);
		},
		css_x : function(elem) {
			return parseInt(LSD.style.get(elem, 'left'));
		},
		css_y : function(elem) {
			return parseInt(LSD.style.get(elem, 'top'));
		},
		set_x : function(elem, pos) {
			elem.style.left = pos+'px';
		},
		set_y : function(elem, pos) {
			elem.style.top = pos+'px';
		},
		add_x : function(elem, pos) {
			LSD.position.set_x(LSD.element.css_x(elem)+pos);
		},
		add_y : function(elem, pos) {
			LSD.position.set_y(LSD.element.css_y(elem)+pos);
		},
		get_height : function(elem) {
			return parseInt(LSD.style.get(elem, 'height'))
		},
		height : function(elem) {
			var padding = LSD.style.get(elem, 'padding');
			var matches = padding.match(/(\d+)/g);
			var padding = parseInt(matches[0] || 0)+parseInt(matches[2] || 0);
			if (LSD.style.get(elem, 'display') != 'none') {
				var r = elem.offsetHeight || LSD.element.get_height(elem);
				return r-(elem.style['padding']?0:padding);
			}
			var old = LSD.style.reset_css(elem, { display : 'block', visibility : 'hidden', position: 'absolute' });
			var r = elem.clientHeight || LSD.element.get_height(elem);
			LSD.style.restore_css(elem, old);
			return r-(elem.style['padding']?0:padding);
		},
		get_width : function(elem) {
			return parseInt(LSD.style.get(elem, 'height'))
		},
		width : function(elem) {
			if (LSD.style.get(elem, 'display') != 'none') {
				return elem.offsetWidth || LSD.element.get_width(elem);
			}
			var old = LSD.style.reset_css(elem, { display : '', visibility : 'hidden', position: 'absolute' });
			var r = elem.clientWidth || LSD.element.get_width(elem);
			LSD.style.restore_css(elem, old);
			return r;
		},
		adjust_size : function(elem) {
			if (!elem) return;
			var h = Math.max(LSD.page.height(), LSD.page.window_height());
			var w = Math.max(LSD.page.width(), LSD.page.window_width());
			elem.style.width = w+'px';
			elem.style.height = h+'px';
//			LSD.events.add(window, 'resize', function(){ LSD.element.adjust_size(elem); });
		},
		adjust_position : function(elem) {
			if (!elem) return;
			var h = LSD.element.height(elem);
			var w = LSD.element.width(elem);
			var t = LSD.page.scroll_y() + (LSD.page.window_height()/2) - (h/2);
			if (t < 0) t = 0;
			var l = LSD.page.scroll_x() + (LSD.page.window_width()/2) - (w/2);
			if (l < 0) l = 0;
			LSD.element.set_y(elem, t);
			LSD.element.set_x(elem, l);
//			Causes the browser to bog down
//			LSD.events.add(window, 'resize', function(){ LSD.element.adjust_position(elem); });
//			LSD.events.add(document, 'scroll', function(){ LSD.element.adjust_position(elem); });
		}
	},
	animate : {
		hide : function(elem) {
			var cur_display = LSD.style.get(elem, 'display');
			if (cur_display != 'none') {
				elem.old_display = cur_display;
				elem.style.display = 'none';
			}
		},
		show : function(elem) {
			elem.style.display = elem.old_display || 'block';
		},
		opacity : function(elem, level) {
			if (window.opera) return;
			elem.style.MozOpacity = level/100;
			elem.style.opacity = level/100;
			if ((LSD.element.attribute(elem, 'width') == '') && (LSD.element.attribute(elem, 'height') == '')) {
				elem.style.height = '1%'; // Add has-layout for IE
			}
//			Choke, causing problems with overlay fade in. don't think I need this
//			elem.style.height = '100%';
			elem.style.filter = 'alpha(opacity='+level+')';
		},
		grow_y : function(elem) {
			if (!elem.height) elem.height = LSD.element.height(elem);
			var h = elem.height || LSD.element.height(elem);
			elem.style.height = '0px';
			elem.style.overflow = 'hidden';
			LSD.animate.show(elem);
			for (var i = 0 ; i <= 100 ; i += 5) {
				(function(){
					var pos = i;
					setTimeout(function(){
						elem.style.height = ((pos/100)*h)+'px';
					}, (pos+1)*10);
				})();
			}
			setTimeout(function() { elem.style.overflow = "visible"; }, 1100)
		},
		shrink_y : function(elem) {
			var h = elem.height || LSD.element.height(elem);
			elem.style.overflow = 'hidden';
			for (var i = 0 ; i <= 100 ; i += 5) {
				(function(){
					var pos = i;
					setTimeout(function(){
						elem.style.height = (h-(pos/100)*h)+'px';
					}, (pos+1)*10);
				})();
			}
			setTimeout(function() { LSD.animate.hide(elem); }, 1100);
		},
		grow_x : function(elem) {
			var w = LSD.element.width(elem);
			elem.style.width = '0px';
			elem.style.overflow = 'hidden';
			LSD.animate.show(elem);
			for (var i = 0 ; i <= 100 ; i += 5) {
				(function(){
					var pos = i;
					setTimeout(function(){
						elem.style.width = ((pos/100)*w)+'px';
					}, (pos+1)*10);
				})();
			}
		},
		fade_in : function(elem, end) { 
			var end = (end < 100)?end:99;
			LSD.animate.opacity(elem, 0);
			LSD.animate.show(elem);
			for (var i = 4 ; i <= end ; i +=5) {
				(function(){
					var pos = i;
					setTimeout(function(){
						LSD.animate.opacity(elem, pos);
					}, (pos+1)*10);
				})();
			}
		},
		fade_out : function(elem) {
			var start = LSD.element.attribute(elem, 'opacity');
			var start = start * 100;
			for (var i = 0 ; i < start ; i += 5) {
				(function(){
					var pos = i;
					if (pos < (start-5)) {
						setTimeout(function() { LSD.animate.opacity(elem, (start-pos)); }, (pos+1)*10);
					} else {
						setTimeout(function() { LSD.animate.hide(elem); }, (pos+1)*10);
					}
				})();
			}
		}
	},
	mouse : {
// Needs testing get mouse relative to page
		x : function(e) {
			e = e || window.event;
			return e.pageX || e.clentX + document.body.scrollLeft;
		},
		y : function(e) {
			e = e || window.event;
			return e.pageY || e.clentY + document.body.scrollLeft;
		},
// Needs testing get mouse relative to element
		element_x : function (e) {
			return (e && e.layerX) || window.event.offsetX;
		},
		element_y : function (e) {
			return (e && e.layerY) || window.event.offsetY;
		}
	},
	page : {
// Needs testing finds page height
		height : function() {
			return (document.documentElement && document.documentElement.scrollHeight) ?
				document.documentElement.scrollHeight :
					(document.body.scrollHeight > document.body.offsetHeight) ?
						document.body.scrollHeight : document.body.offsetHeight;
		},
		width : function() {
			return (document.documentElement && document.documentElement.scrollWidth) ?
				document.documentElement.scrollWidth :
					(document.body.scrollWidth > document.body.offsetWidth) ?
						document.body.scrollWidth : document.body.offsetWidth;
		},
// Needs testing, finds how far the browser is scrolled
		scroll_x : function() {
			var de = document.documentElement;
			return self.pageXOffset || (de && de.scrollLeft) || document.body.scrollLeft;
		},
		scroll_y : function() {
			var de = document.documentElement;
			return self.pageYOffset || (de && de.scrollTop) || document.body.scrollTop;
		},
// Needs testing viewport height/width
		window_height : function() {
			var de = document.documentElement;
			return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight;
		},
		window_width : function() {
			var de = document.documentElement;
			return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
		}
	},
	shadow : {
		show : function(trigger) {
			if (!document.getElementById('LSD_shadow_overlay')) LSD.shadow.create_overlay();
			var overlay = document.getElementById('LSD_shadow_overlay');
			if ((LSD.style.get(overlay, 'opacity') > 0) && (LSD.style.get(overlay, 'display') == "block")) return;
			overlay.style.height = Math.max(LSD.page.height(), LSD.page.window_height())+'px';
			overlay.style.width = Math.max(LSD.page.width(), LSD.page.window_width())+'px';
			LSD.animate.fade_in(overlay, 60);
//			LSD.element.adjust_size(overlay);
		},
		hide : function() {
			LSD.animate.fade_out(document.getElementById('LSD_shadow_overlay'));
		},
		create_overlay : function() {
			var overlay = LSD.dom.create('div');
			overlay.id = 'LSD_shadow_overlay';
			overlay.style.cssText = 'background: #000; opacity: 0; display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: 1000;';
//			overlay.title = 'Click to return to site.';
//			LSD.events.add(overlay, 'click', LSD.shadow.hide);
			document.body.parentNode.appendChild(overlay);
		}
	},
	ajax : {
		trigger : 'LSD_ajax',
		send : function (elem) {
			if (!elem || !elem.nodeName) {
				var elem = this;
			}
			var url = elem.url || elem.action || elem.href || "";
			var method = elem.method?elem.method.toUpperCase():"POST";
			if (method != 'POST' && method != 'GET') var method = 'POST';
			var parameters = elem.elements?LSD.ajax.serialize_input(elem):LSD.ajax.serialize_input(elem.parameters);
			var start = elem.start || function() { LSD.shadow.show(); };
			var finished = elem.finished || function(){ LSD.shadow.hide(); };
			var success = elem.success || function(){};
			var failure = elem.failure || function(){};
			if (LSD.ajax.isFileUpload(elem)) {
				start();
				var iframe = LSD.ajax.createIframe();
					var input = LSD.dom.create('input');
					input.type = 'hidden';
					input.name = LSD.ajax.trigger;
					input.value = 1;
					LSD.dom.insert_last(input, elem);
				elem.target = iframe.name;
				LSD.events.remove(iframe, 'load', null, true);
				if (!iframe.onload) {
					LSD.events.add(iframe, 'load', function(){
						var results = LSD.ajax.iframeContents(iframe);
						try {
							success(eval("(" + results + ")"));
						} catch(e) {
							failure(results);
						}
						finished();
						setTimeout(function() { LSD.ajax.removeIframe(iframe); }, 5000);
					});
				} else {
alert('iframe.onload was set');
					iframe.onreadystatechange = function() {
						if (iframe.readyState == 'complete') {
							var results = LSD.ajax.iframeContents(iframe);
							try {
								success(eval("(" + results + ")"));
							} catch(e) {
								failure(results);
							}
							finished();
							setTimeout(function() { LSD.ajax.removeIframe(iframe); }, 5000);
						}
					}
				}
				return true;
			}  // End Submit file
			try {
				var xml = new XMLHttpRequest();
			} catch (e) {
				try {
					var xml = new ActiveXObject("Msxml2.XMLHTTP");
				} catch (e) {
					try {
						var xml = new ActiveXObject("Microsoft.XMLHTTP");
					} catch (e) {
						return true;	
					}
				}
			}
			xml.onreadystatechange = function() {
				if (xml.readyState == 4) {
					try {
						var data = eval("(" + xml.responseText + ")");
						success(data);
					} catch(e) {
						failure(xml);
					}
					finished();
					xml = null;
				}
			}
			xml.open(method, url+(method=='GET'?'?'+parameters:''), true);
			if (method == 'POST') {
				xml.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				xml.setRequestHeader("Content-length", parameters.length);
				xml.setRequestHeader("Connection", "close");
			}
			xml.send(method=='POST'?parameters:null);
			start();
			return false;
		},
		serialize_input : function(input) {
			if (!input || input == '') return LSD.ajax.trigger+'=1';
			if (input.constructor == String) return input+'&'+LSD.ajax.trigger+'=1';
			var f = [];
			if (input.elements) {
				for (var i = 0 ; i < input.elements.length ; i++) {
					if (input.elements[i].value) {
						f.push(input.elements[i])
					}
				}
				var input = f;
			}
			var r = [];
			if (input.constructor == Array) {
				for (var i = 0 ; i < input.length ; i++) {
					r.push(input[i].name+'='+encodeURIComponent(input[i].value));
				}
			} else {
				for (var j in input)
					r.push(j+'='+encodeURIComponent(input[j]));
			}
			r.push(LSD.ajax.trigger+'=1');
			return r.join('&');
		},
		isFileUpload : function(elem) {
			if (elem.nodeName == 'FORM' && elem.elements) {
				var file = LSD.dom.get('type', 'file', 'input', elem);
				if (file.length > 0) {
					for (var i = 0 ; i < file.length ; i++) {
						if (file[i] && file[i].value != '') {
							return true;
						}
					}
				}
			}
			return false;
		},
		createIframe : function() {
			var iframe = LSD.dom.create('iframe');
			iframe.style.position = "absolute";
			iframe.style.left = "-9000px";
			var counter = 0;
			while(LSD.dom.get('name', 'LSD_iframe'+counter, 'iframe')) {
				counter++;
				if (counter > 10) {
					throw("createIframe counter error");
				}
			}
			iframe.name = 'LSD_iframe'+counter;
			iframe.id = 'LSD_iframe'+counter;
			LSD.dom.insert_last(iframe, document.body);
			if(self.frames['LSD_iframe'+counter].name != 'LSD_iframe'+counter) {
				self.frames['LSD_iframe'+counter].name = 'LSD_iframe'+counter;
			}
			return iframe;
		},
		removeIframe : function(elem) {
			LSD.dom.remove(elem);
		},
		iframeContents : function(elem){
			if (!document.getElementById(elem)) var elem = elem.id;
			if (document.getElementById(elem).contentDocument) {
				return document.getElementById(elem).contentDocument.body.innerHTML;
			} else {
				return window.frames[elem].document.body.innerHTML;
			}
			return '';
		}
	},
	notify : {
		message : function(input) {
//			if (/MSIE/.test(navigator.userAgent)) {
				alert(input);
				return;
//			}
// Choke, none of this works in IE
/*			var table = LSD.dom.create('table');
			table.style.cssText = 'position: absolute; z-index: 1001; max-width: 500px; top: 20%; left: 20%; padding: 15px 30px; background-color: #FFF; color: #555; border: 2px solid #333; font-family: arial;';
			var tbody = LSD.dom.create('tbody');
			table.appendChild(tbody);
			var tr = LSD.dom.create('tr');
			tbody.appendChild(tr);
			var td = LSD.dom.create('td');
			td.innerHTML = input;
			tr.appendChild(td);
			var button = LSD.dom.create('button');
			button.type = 'button';
			button.className = 'button';
			button.innerHTML = 'OK';
			LSD.events.add(button, 'click', function() {
				var notify = table;
				LSD.shadow.hide();
				LSD.dom.remove(table);
			});
			var center = LSD.dom.create('center');
			button.style.cssText = 'display: block; clear: both; margin: 20px 0 0 0;';
			center.appendChild(button);
			td.appendChild(center);
			// Add to document
			document.body.parentNode.appendChild(table);
			LSD.element.adjust_position(table);*/
		}
	},
	slideshow : {
		set_up : function(elem, autoPlay) {
			var images = elem.getElementsByTagName('img');
			if (images && (images.length > 1)) {
				elem.style.textAlign = 'center';
				var nav = LSD.dom.create('center');
				nav.className = 'nav';
				elem.appendChild(nav);
				elem.caption = LSD.dom.create('center');
				elem.caption.className = 'caption';
				elem.appendChild(elem.caption);
				elem.images = new Array();
				elem.nav = new Array();
				elem.max_height = 0;
				var count = images.length;
				for (var i = 0 ; i < count ; i++) {
					elem.max_height = Math.max(elem.max_height, LSD.element.height(images[i]));
					(function() {
						var current = i;
						LSD.animate.hide(images[current]);
						elem.images[current] = images[current];
						elem.nav[current] = LSD.dom.create('a');
						elem.nav[current].innerHTML = current+1;
						LSD.events.add(elem.nav[current], 'click', function() {
							LSD.animate.hide(elem.images[elem.current]);
							elem.nav[elem.current].className = '';
							elem.images[current].style.marginTop = (elem.max_height - elem.images[current].height)+'px';
							LSD.animate.fade_in(elem.images[current]);
							elem.nav[current].className = 'active';
							elem.caption.innerHTML = elem.images[current].alt;
							elem.current = current;
						});
						nav.appendChild(elem.nav[current]);
						nav.appendChild(document.createTextNode(' '));
					})();
				}
				elem.nav[0].className = 'active';
				elem.images[0].style.marginTop = (elem.max_height - elem.images[0].height)+'px';
				elem.current = 0;
				LSD.animate.fade_in(elem.images[0]);
				elem.caption.innerHTML = elem.images[0].alt;
			}
		}
	},
	loader : {
		trigger : function() {
			LSD.dom.ready(function() {
				LSD.loader.form_validate();
				LSD.loader.form_ajax();
//				LSD.loader.ie_6_buttons();
				LSD.loader.link_to_button();
				LSD.loader.table_stripes();
//				LSD.loader.email();
			});
			LSD.events.add(window, 'load', function() {
				LSD.loader.slideshow();
			})
		},
		form_validate : function() {
			var validate_form = LSD.dom.get('class', 'validate', 'form');
			if (validate_form) {
				for (var i = 0 ; i < validate_form.length ; i++) {
					LSD.form.set_up(validate_form[i]);
				}
			}
		},
		form_ajax : function() {
			var ajax_form = LSD.dom.get('class', 'ajax', 'form');
			if (ajax_form) {
				for (var i = 0 ; i < ajax_form.length ; i++) {
					(function() {
						var form = ajax_form[i];
						ajax_form[i].ajax = true;
						ajax_form[i].success = ajax_form[i].success || function(result) {
							form.reset();
							LSD.notify.message(result.message);
							if (result.url) {
								window.location.href = result.url;
							}
						};
						ajax_form[i].failure = ajax_form[i].failure || function() { LSD.notify.message('Form could not be sent.'); };
						if (!/(^|\s)validate(\s|$)/.test(ajax_form[i].className)) {
							LSD.events.add(ajax_form[i], 'submit', LSD.ajax.send);
						}
					})();
				}
			}
		},
		ie_6_buttons : function() {
			var buttons = LSD.dom.get('class', 'button', 'button');
			if (buttons) {
				if (/MSIE (5\.5|6)/.test(navigator.userAgent)) {
					for (var i = 0 ; i < buttons.length ; i++) {
						LSD.events.add(buttons[i], 'mouseover', function() {
							this.className = this.className+' hover';
						});
						LSD.events.add(buttons[i], 'mouseout', function() {
							this.className = this.className.replace(' hover', '');
						});
					}
				}
			}
		},
		table_stripes : function() {
			var tables = LSD.dom.get('class', 'stripes', 'table');
			if (tables) {
				for (var i = 0 ; i < tables.length ; i++) {
					var rows = tables[i].getElementsByTagName('tr');
					if (rows && (rows.length > 1)) {
						for (var j = 1 ; j < rows.length ; j++) {
							rows[j].className = rows[j].className+j%2 == 0?'even':'odd';
							if (/MSIE (5\.5|6)/.test(navigator.userAgent)) {
								LSD.events.add(rows[j], 'mouseover', function() {
									this.className = this.className+' hover';
								});
								LSD.events.add(rows[j], 'mouseout', function() {
									this.className = this.className.replace(' hover', '');
								});
							}
						}
					}
				}
			}
		},
		link_to_button : function () {
			var links = LSD.dom.get('class', 'button', 'a');
			if (links) {
				for (var i = 0 ; i < links.length ; i++) {
					var button = LSD.dom.create('button');
//					button.type = 'button';  // Setting button type stops script in ie 7
					button.innerHTML = links[i].innerHTML;
					button.className = links[i].className;
					(function() {
						var link_href = links[i].href; 
						LSD.events.add(button, 'click', function() { window.location.href = link_href; return false; });
					})();
					LSD.dom.replace_node(links[i], button);
				}
			}
		},
		slideshow : function() {
			var slideshow = LSD.dom.get('class', 'slideshow', 'div');
			if (slideshow) {
				for (var i = 0 ; i < slideshow.length ; i++) {
					LSD.slideshow.set_up(slideshow[i], /(^|\\s)autoPlay(\\s|$)/.test(slideshow[i].className));
				}
			}
		}/*,
// Needs to be finished
		email : function() {
			var email = LSD.dom.get('class', 'email', 'img');
			if (email) {
				for (var i = 0 ; i < email.length ; i++) {
					var mailto = email[i].alt;
					var mailto = mailto.replace(/\sdot\s/, '.');
					var mailto = mailto.replace(/\sat\s/, '@');
					var mailto = mailto.replace(/\s/g, '');
var full_mailto = 'mailto:'+mailto;
encoded = '';
for (var j = 0 ; j < mailto.length ; j++) {
	var encoded = encoded+'&#'+mailto.charCodeAt(j)+';';
}
					var a = LSD.dom.create('a');
					a.innerHTML = encoded;
// mailto does not work properly
					a.href = '&#109;&#97;&#105;&#108;&#116;&#111;&#58;'+encoded;
//					a.className = email[i].className;
					LSD.dom.replace_node(email[i], a);
				}
			}
		}*/
	}
};
document.documentElement.className = 'javascript';
LSD.loader.trigger();
/* To-dos
	dom.create accept attributes for elem
	LSD.animate.grow_x and LSD.element.width need updates from sister y axis functions
	add array iteration to LSD.events.add
*/
