function htmlspecialchars(text) {
	var chars = Array("&", "<", ">", '"', "'");
	var replacements = Array("&amp;", "&lt;", "&gt;", "&quot;", "'");
	for(var i=0; i<chars.length; i++) {
		var re = new RegExp(chars[i], "gi");
		if(re.test(text)) {
			text = text.replace(re, replacements[i]);
		}
	}
	return text;
}

function trim(string) {
	return string.replace(/(^\s+)|(\s+$)/g, "");
}

$.fn.paneler = function(opt) {
	var options = $.extend({
		content: 'body #menu_main',
		button: '',
		func: '',
		last: '',
		next: ''
	}, opt);

	var content_max_w = Math.round($(options.content).offset().left + $(options.content).width());
	var temp_options;

	function pnlr_create(elem, options) {
		options.last = false;
		options.elem = elem;
		$(elem).data('paneler_opts', options)
		var panel = $(elem).
			css("position", "absolute").
			css("background-color", "#fff").
			css("z-index", "1").
			css("border", "1pt solid #009").
			css("border-top", "5pt solid #009").
			css("padding", "5pt").
			css("display", "none");

		$(options.button).data('paneler_elem', elem);
		$(options.button).click(function() {
			var $this = $(this);
			var $panel = $this.data('paneler_elem');
			var $options = $panel.data('paneler_opts');

			if($options.last == $this.attr('id')) {
				$panel.toggle();
			} else {
				$options.last = $this.attr('id');
				$panel.show();
			}
			$panel.css("top", Math.round($this.offset().top + $this.height()));
			if($this.offset().left + $panel.width() > content_max_w) {
				$panel.css("left", Math.round(content_max_w - $panel.width()));
			} else {
				$panel.css("left", $this.offset().left);
			}
			if($options.func!='') {
				eval($options.func + '(this)');
			}
			$panel.data('paneler_options', $options);
		});

		$(document).keypress(function(event) {
			if (event.keyCode == '27') {
				$(panel).hide();
			}
		});

		if(options.next != '') {
			temp_options = options;
			$(document).keypress(function(event) {
				if (event.keyCode == '9') {
					if($('#'+temp_options.last).length>0) {
						if($(temp_options.elem).css('display') != 'none') {
							eval(temp_options.next + '(\'#' + temp_options.last + '\')');
							return false;
						}
					}
				}
				return true;
			});
		}
	}

	return pnlr_create(this, options);
};

var MAX_DUMP_DEPTH = 10;

function dumpObj(obj, name, indent, depth) {
	if (depth > MAX_DUMP_DEPTH) {
		return indent + name + ": <Maximum Depth Reached>\n";
	}
	if (typeof obj == "object") {
		var child = null;
		var output = indent + name + "\n";
		indent += "\t";
		for (var item in obj)
		{
				try {
					child = obj[item];
				} catch (e) {
					child = "<Unable to Evaluate>";
				}
				if (typeof child == "object") {
					output += dumpObj(child, item, indent, depth + 1);
				} else {
					output += indent + item + ": " + child + "\n";
				}
			}
		return output;
	} else {
		return obj;
	}
}
