dom = {
	//the basis of prototypal inheritance
    clone : function(o) {
        function F() {}
        F.prototype = o;
        return new F();
    },

	//the result of our last query
	origin : new Array(),

	//the result of our new dom query
	result : null,

	//the css selector being evaluated
	css : null,

	//for the ready method
	loaded : null,

	//better than window.onload
	ready : function(f) {
		//is there a body element yet?
		if(!document.body) {
			//wait a few milliseconds, check again
			setTimeout('dom.ready(' + f + ')', 10);

			//stop here
			return false;
		}

		//alias
		var length = document.body.innerHTML.length

		/*
		 * if our loaded variable is the same length
		 * as the innerHTML twice in a row, the body
		 * is fully loaded
		 */
		if(dom.loaded == length) {
			//and we can execute the function
			f();

			//dunno if this is necessary
			return true;
		}

		//otherwise we need 
		else {
			//otherwise we get the length
			dom.loaded = length;

			//and run the check again
			setTimeout('dom.ready(' + f + ')', 10);
		}
	},

	get : function(css) {
		//reset any result we might have
		this.result = new Array();
		
		//if they've passed a css selector...
		if(typeof(css) == "string") {
			//start from here
			this.result = this.origin;
			
			//seperate the css selector by spaces...
			var css = css.split(' ');
	
			//and loop through each piece
			for(var i=0; i<css.length; i++) {
				//our other methods need access
				this.css = css[i];
	
				//if the selector contains a hash...
				if(this.css.match(/(\#)/)) {
					//we're looking for an element by its id
					this.get_by_id();
				}

				//if the selector has a period in it...
				else if(this.css.match(/(\.)/)) {
					//we're looking for elements of a certain class
					this.get_by_class();
				}

				//otherwise...
				else {
					//we want a certain set of elements
					this.get_by_tag();	
				}
			}
		}

		//otherwise we're expecting a node
		else {
			this.result.push(css);
		}

		//we're going to be returning a new dom object
		var dom_obj = this.clone(this);

		//containing the results we just found
		dom_obj.origin = this.result;

		//all done! ship it off
		return dom_obj;
	},

	get_by_id : function() {
		//we find a specific element
		var found = document.getElementById(this.css.substr(1));

		//and add it to the results
		this.result.push(found);
	},

	get_by_tag : function() {		
		//if no starting point has been supplied...
		if(!this.result.length) {
			//begin with the body element
			this.result.push(document.body);
		}

		//array to hold all elements found
		var matches = new Array();
	
		//for each element in our current results...
		for(var i=0; i<this.result.length; i++) {
			//find elements inside of the specified type...
			var found = this.result[i].getElementsByTagName(this.css);

			//and add each one...
			for(var j=0; j<found.length; j++) {
				//to the new result set
				matches.push(found[j]);
			}
		}

		//apply results
		this.result = matches;
	},

	get_by_class : function() {
		var css = this.css.split(".");

		/*
		 * if the user specified a set of tags to 
		 * look through, we get those first
		 */
		if(css[0]) {
			this.css = css[0];
			this.get_by_tag();
		}

		//array to hold all elements found
		var matches = new Array();

		//for each element in our current result set...
		for(var i=0; i<this.result.length; i++) {
			//convenience...
			var css_class = this.result[i].className;

			//if the classes match...
			if(css_class.match(css[1])) {
				//add element to the result set
				matches.push(this.result[i]);
			}
		}

		//apply results
		this.result = matches;
	},

	/*
	 * apply a function to each element in the 
	 * current result set
	 */
	each : function(f) {
		//for each element in the result set...
		for(var i=0; i<this.origin.length; i++) {
			//assign the function...
			this.origin[i].temp = f;
			
			//execute...
			this.origin[i].temp();
			
			//and remove
			this.origin[i].temp = null;
		}
	},

	//onclick shortcut
	click : function(f) {
		this.each(function(){
			this.onclick = f;
		});
	},

	//onmouseover shortcut
	over : function(f) {
		this.each(function(){
			this.onmouseover = f;
		});
	},

	//onmouseout shortcut
	out : function(f) {
		this.each(function(){
			this.onmouseout = f;
		});
	},

	//onmousedown shortcut
	down : function(f) {
		this.each(function(){
			this.onmousedown = f;
		});
	},
	
	//onkeydown shortcut
	keydown : function(f) {
		this.each(function(){
			this.onkeydown = f;
		});
	},

	//onmousedown shortcut
	up : function(f) {
		this.each(function(){
			this.onmouseup = f;
		});
	},

	//onmousedown shortcut
	blur : function(f) {
		this.each(function(){
			this.onblur = f;
		});
	},
	
	//onfocus shortcut
	focus : function(f) {
		//if they passed a function
		if(f) {
			//attach it to the onfocus event
			this.each(function(){
				//like all the others
				this.onfocus = f;
			});
		}
		
		//otherwise
		else {
			//focus this input
			this.origin[0].focus();
		}
	},

	//fake css :hover for IE6
	hover : function(css_class) {
		this.each(function(){
			this.onmouseover = function() {
				this.className += ' ' + css_class;
			}
			this.onmouseout = function() {
				var exp = eval('/' + css_class + '/');
				this.className = this.className.replace(exp, '');
			}
		});
	},

	//document.createElement shortcut
	create : function(node, attributes) {
		//create the element
		var node = document.createElement(node);
		
		//if they've passed attributes...
		if(attributes) {
			//loop through them all
			for(x in attributes) {
				//and attach them to the new node
				eval("node." + x + "='" + attributes[x] + "'");
			}
		}
		
		//send it on back
		return dom.get(node);
	},

	before : function(node) {
		//loop through nodes and...
		this.each(function(){
			//append them before the specified element
			node.parentNode.insertBefore(this, node);
		});
		
		//give something back
		return this;
	},

	inside : function(node) {
		//loop through nodes and...
		this.each(function(){
			//append them before the specified element
			node.appendChild(this);
		});
		
		//give something back
		return this;
	},
	
	append : function(node) {
		//loop through nodes and...
		this.each(function(){
			//append them before the specified element
			this.appendChild(node);
		});
		
		//give something back
		return this;
	},

	/*
	 * find an element's position on the page.
	 * variation of ppk original function
	 */
	xy : function(obj) {
		//create some empty vars
		var curleft = curtop = 0;

		//add the offset values
		do {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}

		//while there is one...
		while(obj = obj.offsetParent)

		//and return the result
		return [curleft,curtop];
	},

	/*
	 * returns a computed css value for a specific 
	 * element. supposedly somewhat unreliable, but 
	 * seems to work fine for me
	 */
	get_style : function(element,prop) {
		//for internet explorer...
		if(element.currentStyle) {
			//we have something special
			return element.currentStyle[prop];
		}

		//everyone else...
		else {
			//uses another method
			return document.defaultView.getComputedStyle(element,null).getPropertyValue(prop);
		}
	},
	serverCall: function(path, func){
		if (window.XMLHttpRequest){
			request = new XMLHttpRequest(); 
		}else if (window.ActiveXObject){
			request = new ActiveXObject("Microsoft.XMLHTTP");
		}
		request.onreadystatechange = function(){
			if (request.readyState == 4 && request.status == 200){
				eval(func + '(request.responseText)'); 
			}
		}

		request.open('GET', path, true);
		request.send(null);
	},
	plugin: function(path){ dom.serverCall(path,"eval"); }
}
// Code to include the formFunctions library
dom.ready(
	function(){ 
		if(document.getElementsByTagName("form").length >= 1){
			dom.plugin("/ui/js/formFunctions.js");
		}
	}
);

function $(e){return document.getElementById(e);}