String.prototype.htmlEntities = function () {
	return this.replace(/</g,'&lt;').replace(/>/g,'&gt;');
};

var insertAfter = function (p, n, r) {
	p.insertBefore(n, r.nextSibling);
};

var prependChild = function (p, n) {
	p.insertBefore(n, p.firstChild);
};

var current_scroll = function () {
	var scroll = {};
	
	if (document.all) {
		if (!document.documentElement.scrollLeft) scroll.x = document.body.scrollLeft;
		else scroll.x = document.documentElement.scrollLeft;

		if (!document.documentElement.scrollTop) scroll.y = document.body.scrollTop;
		else scroll.y = document.documentElement.scrollTop;
	} else {
		scroll.x = window.pageXOffset;
		scroll.y = window.pageYOffset;
	}
	
	return scroll;
};

var hide = function (n) {
	if (typeof n === 'string') n = document.getElementById(n);
	n.style.display = 'none';
};

var in_array = function (a, v) {
	for (var i = 0; i < a.length; i++) {
		if (a[i] == v) return true;
	}
	
	return false;
};

var radio_value = function (g) {
	for (var i = 0; i < g.length; i++) {
		if (g[i].checked) {
			return g[i].value;
		}
	}
	
	return '';
};

var show = function (n) {
	if (typeof n === 'string') n = document.getElementById(n);
	n.style.display = '';
};

var addClass = function (n, c) {
	if (typeof n === 'string') n = document.getElementById(n);
	if (n && !hasClass(n, c)) n.className += ' ' + c;
};

var Event = {
	add : function (o, e, f) {
		if (typeof o === 'string') o = document.getElementById(o);
		
		if (typeof e === 'string') {
			if (o.addEventListener) o.addEventListener(e, f, false);
			else if (o.attachEvent) o.attachEvent('on' + e, function() {
				return f.call(o, window.event);
			});
		} else {
			for (var i = 0; i < e.length; i++) Event.add(o, e[i], f);
		}
	},
	
	stop : function (e) {
		if (e) {
			e.returnValue = false;
			if (e.preventDefault) e.preventDefault();
		}
	},
	
	cancel : function (e) {
		if (e) {
			e.cancelBubble = true;
			if (e.stopPropagation) e.stopPropagation();
		}
	},
	
	target : function (e) {
		if (e) {
			var t = e.target || e.srcElement;
			return t.nodeType == 3 ? t.parentNode : t;
		}
	}
};

var Animation = {
	util : {
		get : function (n) {
			return typeof n == 'string' ? document.getElementById(n) : n;
		}
	},
	
	fadeOut : function (target, increment) {
		target = Animation.util.get(target);
		if (!increment) var increment = 0.05;
		var current = 1.0;
		
		var interval = window.setInterval(function () {
			current -= increment;
			target.style.opacity = current;
			
			if (current < -1) {
				target.style.display = 'none';
				window.clearInterval(interval);
			}
		}, 1);
		
		return interval;
	}
};

var Cookie = {
	add : function (n, v, d, a) {
		if (d) {
			var date = new Date();
			date.setTime(date.getTime() + (d * 24 * 60 * 60 * 1000));
			var expires = '; expires=' + date.toGMTString();
		} else {
			var expires = '';
		}
		
		if (a && Cookie.get(n)) v = Cookie.get(n) + ',' + v;
		
		document.cookie = n + '=' + v + expires + '; path=/';
	},
	
	remove : function (n) {
		Cookie.add(n, '', -1);
	},
	
	get : function (n, f) {
		var p = n + "=";
		var t = document.cookie.split(';');
		
		for (var i = 0; i < t.length; i++) {
			var c = t[i];
			while (c.charAt(0) == ' ') c = c.substring(1, c.length);
			if (c.indexOf(p) == 0) {
				c = c.substring(p.length, c.length);
				
				if (f) {
					var t = c.split(',');
					
					for (var i = 0; i < t.length; i++) {
						if (t[i] == f) return true;
					}
					
					return false;
				} else {
					return c;
				}
			}
		}
		
		return null;
	}
};

var getElementsByClass = function (n, c, t, o) {
	if (typeof n === 'string') n = document.getElementById(n);
	if (!n) n = document;
	var m = [], a = n.getElementsByTagName(t || '*'), t = new RegExp('(\\s|^)' + c + '(\\s|$)');
	for (var i = 0, e; e = a[i]; i++) if (t.test(e.className)) m.push(e);
	return o ? m[0] : m;
};

var hasClass = function (n, c) {
	if (typeof n === 'string') n = document.getElementById(n);
	return n && n.className.match(new RegExp('(\\s|^)' + c + '(\\s|$)'));
};

var HTTPRequest = function (u, f, d, t) {
	var r = window.ActiveXObject ? new ActiveXObject('Microsoft.XMLHTTP') : new XMLHttpRequest();
	r.open(d ? 'POST' : 'GET', u);
	
	r.onreadystatechange = function () {
		if (r.readyState == 4) f(r.status, r.responseText, r.getResponseHeader('Content-Type'));
	};
	
	if (d) r.setRequestHeader('Content-Type', t || 'application/x-www-form-urlencoded');
	r.send(d);
};

var buildQueryString = function (o) {
	var q = [];
	
	for (var f in o) {
		if (o.hasOwnProperty(f)) {
			if (o[f] === null || o[f] === undefined) q.push(f + '=');
			else q.push(f + '=' + encodeURIComponent(o[f]));
		}
	}
	
	return q.join('&');
};

var removeElement = function (n) {
	if (typeof n === 'string') n = document.getElementById(n);
	return n.parentNode.removeChild(n);
};

var removeChildren = function (n) {
	if (typeof n === 'string') n = document.getElementById(n);
	while (n.hasChildNodes()) n.removeChild(n.firstChild);
};

var removeClass = function (n, c) {
	if (typeof n === 'string') n = document.getElementById(n);
	if (n && hasClass(n, c)) n.className = n.className.replace(new RegExp('(\\s|^)' + c + '(\\s|$)'), ' ');
};

var Form = {
	populate : function (form, row, p) {
		if (typeof form === 'string') form = document.getElementById(form) || document[form];
		
		for (var f in row) {
			var n = p !== undefined && typeof row[f] !== 'number' ? p + '[' + f + ']' : p || f;
			
			if (row[f] && typeof row[f] === 'object' && row[f].constructor !== Array) {
				Form.populate(form, row[f], n);
			} else {
				if (form[n + '[]'] && !form[n]) n += '[]';
				
				if (row.hasOwnProperty(f) && form[n]) {
					if (row[f] === null) row[f] = '';
					
					if (row[f] && row[f].constructor === Array) {
						for (var r = 0; r < row[f].length; r++) {
							var t = {};
							t[f] = row[f][r];
							Form.populate(form, t, p);
						}
					} else {
						if (form[n].nodeName == 'SELECT') {
							for (var i = 0; i < form[n].options.length; i++) {
								if ((form[n].options[i].value || form[n].options[i].text) == row[f]) form[n].options[i].selected = true;
							}
						} else if (form[n].nodeName == 'TEXTAREA') {
							form[n].innerHTML = row[f].htmlEntities();
						} else {
							if (form[n].getAttribute === undefined) {
								for (var i = 0; i < form[n].length; i++) {
									if (form[n][i] && form[n][i].value == row[f]) form[n][i].checked = true;
								}
							} else {
								if (form[n].getAttribute('type') == 'checkbox') {
									if (form[n].value == row[f]) form[n].checked = true;
								} else {
									form[n].value = row[f];
								}
							} 
						}
					}
				} else {
					n = document.getElementById(n);
					if (n) n.innerHTML = row[f];
				}
			}
		}
		
		form.onreset = function (e) {
			Form.populate(form, row);
			return false;
		};
	}
};

var validate = function (form) {
	var errors = [];
	var valid_groups = {};
	
	for (var i = 0, f; f = form.elements[i]; i++) {
		var valid = true;
		var value = '';
		
		if (f.getAttribute('required') !== null) {
			if (f.nodeName == 'SELECT') {
				if (f.selectedIndex <= 0) valid = false;
			} else if (f.nodeName == 'TEXTAREA') {
				value = f.value.replace(/^\s+|\s+$/g, '');
				if (!value) valid = false;
			} else {
				var type = f.getAttribute('type');
				var must_equal = f.getAttribute('must_equal');
				
				if (type == 'radio') {
					if (form[f.name].length > 1) {
						if (valid_groups[f.name] === undefined) {
							valid_groups[f.name] = false;
							
							for (var j = 0; j < form[f.name].length; j++) {
								if (form[f.name][j].checked) {			
									valid_groups[f.name] = true;
								}
							}
						}
						
						valid = valid_groups[f.name];
					} else {
						if (!f.checked) valid = false;
					}
				} else if (type == 'checkbox') {
					if (!f.checked) valid = false;
				} else {
					value = f.value;
					
					if (f.getAttribute('required') == 'email') {
						if (!value.match(/^[\w\d.%+-]+@[\d\w.-]{2,}\.[\w]{2,4}$/)) valid = false;
					} else if (f.getAttribute('required') == 'email-optional') {
						if (!value.match(/^(?:[\w\d.%+-]+@[\d\w.-]{2,}\.[\w]{2,4})?$/)) valid = false;
					} else if (f.getAttribute('required') == 'numeric') {
						if (!value || !value.match(/^\d{1,3}(?:\.?\d{2})?$/)) valid = false;
					} else if (f.getAttribute('required') == 'phone-optional') {
						if (!value.match(/^(?:\d{3}[\.-]?\d{3}[\.-]?\d{4})?$/)) valid = false;
					} else if (f.getAttribute('required') == 'phone') {
						if (!value.match(/^\d{3}[\.-]?\d{3}[\.-]?\d{4}$/)) valid = false;
					} else {
						if (!value) valid = false;
					}
					
					/*
					if (f.getAttribute('required') == 'phone') {
						if (!f.value.match(/^\(\d\d\d\)\s*?\d\d\d\-\d\d\d\d$/)) valid = false;
					} else if (f.getAttribute('required') == 'email') {
						if (!f.value.match(/^[\w\d.%+-]+@[\d\w.-]{2,}\.[\w]{2,4}$/)) valid = false;
					} else if (f.getAttribute('required') == 'zip') {
						if (!f.value.match(/^[\d]{5}$/)) valid = false;
					} else {
						if (!f.value) valid = false;
					}
					*/
					
					if (must_equal) {
						var must_equal_element = document.getElementById(must_equal);
						if (must_equal_element && value != must_equal_element.value) valid = false;
					}
				}
			}
		}
		
		if (!valid) {
			if (!in_array(errors, f.getAttribute('prompt'))) {
				errors.push(f.getAttribute('prompt'));
			}
			
			if (errors.length < 2) {
				f.focus();
			}
		}
	}
	
	if (errors.length) {
		alert('Please correct the following errors before submitting this form:\n\n' + errors.join('\n'));
		
		return false;
	} else {
		return true;
	}
};

var preload_images = function (paths, prefix) {
	for (var i = 0, p; p = paths[i]; i++) {
		var m = new Image();
		m.src = prefix + p;
	}	
}

var default_values = function () {
	var elements = document.getElementsByTagName('*');
	
	for (var i = 0, element; element = elements[i]; i++) {
		if (element.getAttribute('default')) {
			if (!element.value) element.value = element.getAttribute('default');
			
			Event.add(element, 'focus', function (e) {
				if (this.value == this.getAttribute('default')) this.value = '';
			});
			
			Event.add(element, 'blur', function (e) {
				if (this.value == '') this.value = this.getAttribute('default');
			});
		}
	}
};

var submit_once = function () {
	var forms = document.getElementsByTagName('form');
	
	for (var f = 0, form; form = forms[f]; f++) {
		Event.add(form, 'submit', function (e) {
			var inputs = this.getElementsByTagName('input');

			for (var i = 0, input; input = inputs[i]; i++) {
				if (input.type == 'submit' && !input.name) {
					input.disabled = true;
				}
			}
		});
	}
};

var set_details_popups = function () {
	var details_popups = [];
	
	var hide_details_popups = function (except) {
		for (var i = 0; i < details_popups.length; i++) {
			if (details_popups[i] !== except) {
				details_popups[i].hide();
			}
		}
	};
	
	var DetailsPopup = function (parent, item, id) {
		var self = this;
		
		this.parent = parent;
		this.item = item;
		this.item_id = id;
		
		this.position = {};
		
		this.load_timer = null;
		this.hide_timer = null;
	
		this.load = function () {
			if (!self.popup) {
				self.generate();
			}
			
			self.stop_hide_timer();
			self.stop_load_timer();
			
			hide_details_popups(self);
			
			if (!self.retrieved_details) {
				HTTPRequest('details.php?item=' + self.item + '&id=' + self.item_id, function (status, response) {
					self.retrieved_details = true;
					self.details.innerHTML = response;
				});
			}
			
			self.show();
		};
		
		this.hide = function () {
			self.stop_load_timer();
			self.stop_hide_timer();
			
			if (self.popup && self.visible) {
				self.visible = false;
				self.popup.style.display = 'none';
			}
		};
		
		this.generate = function () {
			this.popup = document.createElement('div');
			document.getElementById('popups').appendChild(this.popup);
			
			Event.add(this.popup, 'mouseover', function (e) {
				self.stop_hide_timer();
			});
			
			Event.add(this.popup, 'mouseout', function (e) {
				self.start_hide_timer();
			});
			
			addClass(this.popup, 'details-popup');
			
			this.closer = document.createElement('a');
			this.popup.appendChild(this.closer);
			addClass(this.closer, 'closer');
			this.closer.href = '#';
			this.closer.innerHTML = 'close';
			
			Event.add(this.closer, 'click', function (e) {
				Event.stop(e);
				self.hide();
			});
			
			this.details = document.createElement('div');
			this.popup.appendChild(this.details);
			
			this.details.innerHTML = '<h2>Item Details</h2><p>Loading. Please wait...</p>';
		};
		
		this.start_hide_timer = function () {
			this.stop_load_timer();
			this.stop_hide_timer();
			this.hide_timer = window.setTimeout(this.hide, 800);
		};
		
		this.stop_hide_timer = function () {
			window.clearTimeout(this.hide_timer);
			this.hide_timer = null;
		};
		
		this.start_load_timer = function () {
			if (this.load_timer === null) {
				this.stop_hide_timer();
				this.load_timer = window.setTimeout(this.load, 400);
			}
		};
		
		this.loaded = function () {
			return this.load_timer !== null || (this.popup && this.visible);
		};
		
		this.stop_load_timer = function () {
			window.clearTimeout(this.load_timer);
			this.load_timer = null;
		};
		
		this.move = function () {
			this.popup.style.left = this.position.x + Math.min(0, document.body.offsetWidth - (344 + this.position.x)) + 'px';
			this.popup.style.top = this.position.y + 'px';
		};
		
		this.show = function () {
			this.move();
			this.visible = true;
			this.popup.style.display = '';
		};
		
		this.set_position = function (e) {
			var scroll = current_scroll();
			this.position.x = e.clientX + scroll.x;
			this.position.y = e.clientY + scroll.y;
		};
		
		/*Event.add(this.parent, 'click', function (e) {
			Event.stop(e);
		});*/
		
		Event.add(this.parent, 'mousemove', function (e) {
			self.stop_hide_timer();
			
			self.set_position(e);
			
			if (!self.loaded()) {
				self.start_load_timer();
			}
		});
		
		Event.add(this.parent, 'mouseout', function (e) {
			self.start_hide_timer();
		});
	};
	
	var elements = document.getElementsByTagName('*');
	
	for (var i = 0, element; element = elements[i]; i++) {
		if (element.getAttribute('details')) {
			var params = element.getAttribute('details').split('-');
			
			if (element.getAttribute('href')) {
				element.href = params[0] + '.php?id=' + params[1];
			}
			
			details_popups.push(new DetailsPopup(element, params[0], params[1]));
		}
	}
};

var show_poll_results = function (id, vote) {
	var poll = document.getElementById('poll-' + id);
	var poll_form = document.getElementById('poll-' + id + '-form');
	var poll_controls = document.getElementById('poll-' + id + '-controls');
	
	HTTPRequest('vote.php?item=poll&id=' + id + '&choice=' + radio_value(poll_form['choice']), function (status, response) {
		poll.innerHTML = response;
	});
	
	hide(poll_controls);
};

var get_next_poll = function (id) {
	var poll_container = document.getElementById('poll-' + id).parentNode;
	
	HTTPRequest('next-poll.php', function (status, response) {
		poll_container.innerHTML = response;
	});
	
	return false;
};

var highlight_nav = function () {
	var body_classes = document.body.className.split(' ');
	var navs = ['primary-nav', 'secondary-nav', 'tertiary-nav'];

	for (var i = 0, n; n = navs[i]; i++) {
		var tab = getElementsByClass(n, body_classes[i], 'a', true);
		if (tab) addClass(tab, 'current');
	}
};

var add_to_favorites = function () {
	track_outbound_links('share-tools-add-to-favorites');
	
	if (navigator.appName != 'Microsoft Internet Explorer') { 
		window.sidebar.addPanel(document.title, window.location.href, '');
	} else {
		window.external.AddFavorite(document.title, window.location.href);
	}
	
	return false;
};

var image_enlargers = function () {
	var images = document.getElementsByTagName('img');
	
	for (var i = 0, image; image = images[i]; i++) {
		if (hasClass(image, 'enlarge')) {
			image.title = 'Click to enlarge...';
			
			Event.add(image, 'click', function (e) {
				old_scroll = current_scroll();
				window.scrollTo(0, 0); 
				
				document.getElementById('enlarged-image').src = this.src;
				addClass('enlarge-image-overlay', 'active');
				
				var details = document.getElementById('enlarge-details');
				
				if (this.src.indexOf('240.gif') > -1) {
					details.innerHTML = '<a href="upload/289.pdf" target="_blank">Download PDF</a>';
				} else if (this.src.indexOf('239.gif') > -1) {
					details.innerHTML = '<a href="upload/288.pdf" target="_blank">Download PDF</a>';
				} else if (this.src.indexOf('238.gif') > -1) {
					details.innerHTML = '<a href="upload/287.pdf" target="_blank">Download PDF</a>';
				} else if (this.src.indexOf('237.gif') > -1) {
					details.innerHTML = '<a href="upload/286.pdf" target="_blank">Download PDF</a>';
				} else if (this.src.indexOf('241.gif') > -1) {
					details.innerHTML = '<a href="upload/290.pdf" target="_blank">Download PDF</a>';
				} else {
					details.innerHTML = '';
				}
			});
		}
	}
};

var set_avatar = function (avatar, clicked) {
	document.getElementById('avatar-field').value = avatar;
	
	var choosers = getElementsByClass(document, 'avatar-chooser', 'a');
	
	for (var i = 0; i < choosers.length; i++) {
		choosers[i].innerHTML = 'Choose This';
		choosers[i].style.fontWeight = 'normal';
		choosers[i].style.textDecoration = 'underline';
	}
	
	var anchor = document.getElementById('choose-avatar-' + avatar)
	
	anchor.innerHTML = 'My Avatar';
	anchor.style.fontWeight = 'bold';
	anchor.style.textDecoration = 'none';
	
	if (clicked) {
		clicked.blur();
	}
	
	return false;
};

var send_form = function (id) {
	var form = document.getElementById(id);
	
	if (validate(form)) {
		form.submit();
	}
	
	return false;
};

var format_phone = function (input) {
	input.value = input.value.replace(/[^\d]/g, '').replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3').substr(0, 12);
	return false;
};

var format_digits_only = function (input) {
	input.value = input.value.replace(/[^\d]/g, '');
	return false;
};

var format_word_characters_only = function (input) {
	input.value = input.value.replace(/[^a-zA-Z0-9_-]/g, '');
	return false;
};

var old_scroll = {'x' : 0, 'y' : 0};

var redirect_to = function (code, url) {
	track_outbound_links('share-tools-' + code);
	window.open('http://www.kingofprussiamall.com/redirect.php?track=' + encodeURIComponent(code) + '&url=' + encodeURIComponent(url));
};

var open_window = function (url, width, height) {
	if (typeof url !== 'string') url = url.href;
	window.open(url, 'window', 'status=0,toolbar=0,location=0,menubar=0,directories=0,resizable=1,scrollbars=1,height=' + height + ',width=' + width);
	return false;
};


var track_outbound_links = function (a) {
	var h = typeof a !== 'string' ? a.href : a;
	
	pageTracker._trackPageview('/outbound/' + h);
	//alert(h);
};
