var Library = {
	ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)'
}
String.prototype.stripScripts = function(){
	return this.replace(new RegExp(Library.ScriptFragment, 'img'), '');
}
String.prototype.evalScripts = function(){
	var matchAll = new RegExp(Library.ScriptFragment, 'img');
	var matchOne = new RegExp(Library.ScriptFragment, 'im');
	var matches = this.match(matchAll);
	var results = [];
	for(var i=0; i<matches.length; i++){
		eval(matches[i].match(matchOne)[1]);
	}
}
var $ = function(elem){
	if(typeof elem == 'string') elem = document.getElementById(elem);
	return elem;
}
var $F = function(input){
	input = $(input);
	if(input.value != undefined) return input.value;;
}
var $M = function(){
	return Elem.get(arguments);
}
var addLoadEvent = function(func){
	Elem.addEListener(window,'load',func);
}

var Class = {
	create: function(){
		return function(){
			this.init.apply(this, arguments);
		}
	},
	extend: function(parent,child){
		if(parent.prototype) parent = parent.prototype;
		for(var i in parent){
			if(!child[i]) child[i] = parent[i];
			else child[i+'_base'] = parent[i];
		}
		return child;
	}
}

var Elem = {
	create: function(tag,init){
		var elem = document.createElement(tag);
		if(init){
			for(var i in init){
				if(i == 'attributes'){
					for(var j in attributes) elem.setAttribute(j,init[i][j]);
				} else {
					elem[i] = init[i];
				}
			}
		}
		return elem;
	},
	get: function(tag,parent,matchObj){
		if(!tag) tag = '*';
		if(!parent) parent = document;
		if(!matchObj) matchObj = {};
		var elems = parent.getElementsByTagName(tag);
		var returnElems = [];
		for(var i=0; i<elems.length; i++){
			var elem = elems[i];
			for(var j in matchObj){
				if(j == 'attributes'){
					for(var k in matchObj[j]){
						alert(k);
						if(elem.getAttribute(k) == matchObj[j][k]) returnElems.push(elem);
					}
				} else {
					if(j == 'className'){
						if(Elem.hasClassName(elem,matchObj[j])) returnElems.push(elem);
					} else if(elem[j] == matchObj[j]){
						 returnElems.push(elem);
					}
				}
			}
		}
		return returnElems;
	},
	update: function(elem,html){
		$(elem).innerHTML = html.stripScripts();
	    setTimeout(function(){html.evalScripts()}, 10);
	},
	empty: function(elem){
		elem = $(elem);
		try {
			elem.innerHTML = '';
		} catch(e) {
			var elems = elem.getElementsByTagName('*');
			for(var i=0; i<elems.length; i++){
				elem.removeChild(elems[i]);
			}
		}
	},
	prepend: function(elem,node){
		elem = $(elem);
		elem.insertBefore(node,elem.firstChild);
	},
	append: function(elem,node){
		elem = $(elem);
		elem.appendChild(node);
	},
	remove: function(elem){
		elem = $(elem);
		elem.parentNode.removeChild(elem);
	},
	addEListener: function(obj,e,func){
		if(obj.attachEvent){
			e = 'on'+e;
			obj.attachEvent(e,func);
		} else if(obj.addEventListener){
			obj.addEventListener(e,func,false);
		}
	},
	addClassName: function(elem,c){
		elem = $(elem);
		if(!Elem.hasClassName(elem,c)) elem.className = elem.className + ' ' + c;
	},
	removeClassName: function(elem,c){
		elem = $(elem);
		var cArr = elem.className.split(' ');
		for(var i=0; i<cArr.length; i++){
			if(cArr[i] == c){
				cArr.splice(i,1);
				break;
			}
		}
		elem.className = cArr.join(' ');
	},
	hasClassName: function(elem,c){
		elem = $(elem);
		var cArr = elem.className.split(' ');
		var has = false;
		for(var i=0; i<cArr.length; i++){
			if(cArr[i] == c){
				has = true;
				break;
			}
		}
		return has;
	},
	setOpacity: function(elem,opacity){
		elem.style.opacity = opacity/100;
		elem.style.filter = 'alpha(opacity='+opacity+')';
	},
	hide: function(elem){
		$(elem).style.display = 'none';
	},
	show: function(elem){
		$(elem).style.display = 'block';
	}
}

var Form = {
	getForm: function(frm){
		if(frm) frm = $(frm);
		else if(document.forms[0]) frm = document.forms[0];
		return frm;
	},
	getParentForm: function(input){
		input = $(input);
		for(var i=0; i<document.forms.length; i++){
			var frm = document.forms[i];
			for(var j=0; j<frm.length; j++){
				if(frm[j] == input) return frm;
			}
		}
		alert("Parent form of "+input+" not found.");
	},
	addSubmitEvent: function(frm,func){
		Elem.addEListener(frm,'submit',func);
	},
	focusFirstElement: function(frm){
		frm = Form.getForm(frm);
		if(frm && frm.length){
			for(var i=0; i<frm.length; i++){
				var input = frm[i];
				if(input.type != 'hidden'){
					try {
						input.focus();
						return;
					}catch(e){
					}
				}
			}
		}
	},
	serialize: function(frm){
		frm = Form.getForm(frm);
		var str = '';
		if(frm && frm.length){
			for(var i=0; i<frm.length; i++){
				var input = frm[i];
				str += input.name+'='+escape($F(input));
				if(i<frm.length) str += '&';
			}
			return str;
		}
	}
}

var Ajax = Class.create();
Ajax.prototype = {
	init: function(url,onSuccess,onError,params){
		var thisRef = this;	// reference to this for methods used as callback functions
		if(!params.method) params.method = "get";
		else params.method = params.method.toLowerCase();
		if(!params.args) params.args = {};
		if(typeof params.args == 'object'){
			var paramstring = "";
			for(var i in params.args)
				if(typeof params.args[i] != 'object' && typeof params.args[i] != 'function')
					paramstring += i+"="+escape(params.args[i])+"&";
		}
		if(params.container) this.container = params.container;
		this.getTransport();
		this.onSuccess = onSuccess || function(){};
		this.onError = onError || function(){};
		this.XHR.onreadystatechange = function(){
			thisRef.checkState();
		}
		this.XHR.open(params.method, url, true);
		if(params.method == 'post') this.XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
		this.XHR.send(paramstring);
	},
	getTransport: function(){
		if(window.ActiveXObject) this.XHR = new ActiveXObject("Microsoft.XMLHTTP");
		else if (window.XMLHttpRequest) this.XHR = new XMLHttpRequest();
	},
	checkState: function(){
		if(this.XHR.readyState == 4) {
			if(this.XHR.status == 200){
				if(this.container) Elem.update(this.container,this.XHR.responseText);
				this.onSuccess(this.XHR);
				return;
			}
			this.onError(this.XHR);
		}
	}
}

var Menu = Class.create();
Menu.prototype = {
	params: {icons:true},
	iconFolder: '/dhtml/icons/',
	init: function(elem,params){
		this.current = [];
		if(params) this.params = params;
		var menus = $(elem).getElementsByTagName('li');
		for(var i=0; i<menus.length; i++){
			var menu = menus[i];
			var level = 0;
			while(menu.parentNode.nodeName.toLowerCase() == 'li' || menu.parentNode.nodeName.toLowerCase() == 'ul'){
				level++;
				menu = menu.parentNode.parentNode;
			}
			this.addChild(menus[i],level);
		}
	},
	addChild: function(elem,level){
		new Menu.Child(this,elem,level);
	}
}

Menu.Child = Class.create();
Menu.Child.prototype = {
	init: function(parent,elem,level){
		var thisRef = this;
		this.parent = parent;
		this.level = level;
		this.timeout = null;
		this.container = elem;
		this.a = elem.getElementsByTagName('a')[0];
		this.ul = elem.getElementsByTagName('ul');
		this.ul = this.ul.length ? this.ul[0] : {};
		this.a.onmouseover = function(){thisRef.show()};
		this.ul.onmouseover = function(){thisRef.reset()};
		this.a.onmouseout = this.ul.onmouseout = function(){thisRef.hide()};
		if(this.parent.params.icons && this.container.getAttribute('rel')){
			this.container.style.backgroundImage = 'url("'+this.parent.iconFolder+this.container.getAttribute('rel')+'")';
		}
		if(this.ul.style && this.parent.params.rootArrow){
			this.a.style.background = 'url("'+this.parent.iconFolder+'arrow2.gif") no-repeat right center';
		}
	},
	show: function(e){
		var parent = this.parent;
		var lvl = this.level;
		if(parent.current[lvl]) parent.current[lvl].kill();
		parent.current[lvl] = this;
		this.reset.apply(this);
		this.container.className = this.ul.className = this.a.className = 'over';
	},
	hide: function(e){
		var thisRef = this;
		if(this.ul.style){
			this.timeout = setTimeout(function(){thisRef.kill()},700);
		} else {
			this.kill();
		}
	},
	kill: function(e){
		this.container.className = this.ul.className = this.a.className = '';
	},
	reset: function(e){
		if(this.timeout) clearTimeout(this.timeout);
	}
}