

red.prototype.dom = {
	
	onload: [],
	
	load: function() {
		if (arguments.callee.done) {
			return false;
		}
		arguments.callee.done = true;
		for (i = 0;i < red.prototype.dom.onload.length;i++) {
			red.prototype.dom.onload[i]();
		}
	},

	ready: function ( fireThis ) {
		red.prototype.dom.onload.push(fireThis);
		
		// Test if browser uses Mozilla/Opera scheme:
		if (document.addEventListener) {
			document.addEventListener("DOMContentLoaded", red.prototype.dom.load, null);
		}
		
		//  Next we use a test for KHTML/Webkit/Safari.
		if (/KHTMl|WebKit/i.test(navigator.userAgent)) {
			var timer = setInterval(function() {
				if (/loaded|complete/.test(document.readyState)) {
					clearInterval(timer);
					delete timer;
					red.prototype.dom.load();
				}
			}, 10);
		}
	
		//  For IE we use a tricky way to take advantage of the defer
		if (/MSIE/i.test(navigator.userAgent) && !/opera/i.test(navigator.userAgent)) {
			var script = document.createElement("script");
			script.type = "text/javascript";
			script.setAttribute("id", "__ie_onload");
			script.setAttribute("defer","defer");
			script.src = "javascript:void(0)";
			document.getElementsByTagName("head")[0].appendChild(script);
			script.onreadystatechange=function() {
				if (this.readyState=="complete") {
					red.prototype.dom.load();
				}
			};
		}
		script = null;
		// Use window.onload for unsupported browsers.
		window.onload = red.prototype.dom.load;
	},
		
	byid : function(id){
		return document.getElementById(id);
	},
	
	byclass : function ( name, tag ) {
		var results = new Array();
		var classCheck = new RegExp("(^|\\s)" + name + "(\\s|$)");
		var elems = red.prototype.dom.bytag(tag || "*");
		var len = elems.length;
		for (var i = 0; i < len; i++) {
			if (classCheck.test(elems[i].className)) {
				results.push(elems[i]);
			}
		}
		return results;
	},
	
	bytag : function ( name, elem ) {
        return (elem || document).getElementsByTagName(name);
    },
	
	$ : function ( elem ) {
		if(red.prototype.is_object(elem)){
			return elem;
		}
		else if(red.prototype.is_string(elem)){
			var idCheck = new RegExp("^#");
			var classCheck = new RegExp("^.");
			if (idCheck.test(elem)) {
				elem = elem.replace(/\#/g,"");
				return red.prototype.dom.byid(elem);
			}
			else if (classCheck.test(elem)) {
				elem = elem.replace(/\./g,"");
				return red.prototype.dom.byclass(elem);
			}
			else {
				return red.prototype.dom.bytag(elem);
			}
		}	
	},
	
	//
	//achtung: liefert immer einen Array zurück
	//
	
	bycss : function ( selector ) {
		var tokens = selector.split(" ");
				
		var currentContext = new Array(document);
		for (var i = 0; i < tokens.length; i++) {
			token = tokens[i].replace(/^\s+/,"").replace(/\s+$/,"");
			if (token.indexOf("#") > -1) {
				var bits = token.split("#");
				var tag = bits[0];
				var id = bits[1];
				var element = red.prototype.dom.byid(id);
												
				if (tag && element.nodeName.toLowerCase() != tag) {
					return new Array();
				}
				currentContext = new Array(element);
				continue;
			}
			if (token.indexOf(".") > -1) {
				var bits = token.split(".");
				var tag = bits[0];
				var className = bits[1];
				if (!tag) {
					tag = "*";
				}
				var found = new Array;
				var foundCount = 0;
				for (var j = 0; j < currentContext.length; j++) {
					var elements;
					if (tag == "*") {
						elements = red.prototype.dom.bytag("*", currentContext[j]);
					} 
					else {
						elements = red.prototype.dom.bytag(tag, currentContext[j]);
					}
					for (var k = 0; k < elements.length; k++) {
						found[foundCount++] = elements[k];
					}
				}
				currentContext = new Array();
				var currentContextIndex = 0;
				for (var j = 0; j < found.length; j++) {
					if (found[j].className && found[j].className.match(new RegExp("\\b" + className + "\\b"))) {
						currentContext[currentContextIndex++] = found[j];
					}
				}
				continue;
			}
			if (token.match(/^(\w*)\[(\w+)([=~\|\^\$\*]?)=?"?([^\]"]*)"?\]$/)) {
				var tag = RegExp.$1;
				var attrName = RegExp.$2;
				var attrOperator = RegExp.$3;
				var attrValue = RegExp.$4;
				if (!tag) {
					tag = "*";
				}
				var found = new Array();
				var foundCount = 0;
				for (var j = 0; j < currentContext.length; j++) {
					var elements;
					if (tag == "*") {
						elements = red.prototype.dom.bytag("*", currentContext[j]);
					} 
					else {
						elements = red.prototype.dom.bytag(tag, currentContext[j]);
					}
					for (var k = 0; k < elements.length; k++) {
						found[foundCount++] = elements[k];
					}
				}
				currentContext = new Array();
				var currentContextIndex = 0;
				var checkFunction; 
				switch (attrOperator) {
					case "=":
						checkFunction = function(e) { return (e.getAttribute(attrName) == attrValue); };
						break;
					case "~":
						checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp("\\b" + attrValue + "\\b"))); };
						break;
					case "|":
						checkFunction = function(e) { return (e.getAttribute(attrName).match(new RegExp("^" + attrValue + "-?"))); };
						break;
					case "^":
						checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) == 0); };
						break;
					case "$":
						checkFunction = function(e) { return (e.getAttribute(attrName).lastIndexOf(attrValue) == e.getAttribute(attrName).length - attrValue.length); };
						break;
					case "*":
						checkFunction = function(e) { return (e.getAttribute(attrName).indexOf(attrValue) > -1); };
						break;
					default :
					checkFunction = function(e) { return e.getAttribute(attrName); };
				}
				currentContext = new Array();
				var currentContextIndex = 0;
				for (var j = 0; j < found.length; j++) {
					if (checkFunction(found[j])) {
						currentContext[currentContextIndex++] = found[j];
					}
				}
				continue; 
			}
			if (!currentContext[0]){
				return;
			}
			tag = token;
			var found = new Array();
			var foundCount = 0;
			for (var j = 0; j < currentContext.length; j++) {
				var elements = red.prototype.dom.bytag(tag, currentContext[j]);
				for (var k = 0; k < elements.length; k++) {
					found[foundCount++] = elements[k];
				}
			}
			currentContext = found;
		}
		return currentContext;
	},
	
	prev : function ( elem ) {
		do {
			elem = elem.previousSibling;
		} 
		while (elem && (elem.nodeType == 3 && !/\S/.test(elem.nodeValue)));
		return elem;
	},
	
	next : function ( elem ) {
		do {
			elem = elem.nextSibling;
		} 
		while (elem && (elem.nodeType == 3 && !/\S/.test(elem.nodeValue)));
		return elem;
	},
	
	first : function ( elem ) {
		elem = elem.firstChild;
		return elem && (elem.nodeType == 3 && !/\S/.test(elem.nodeValue)) ?
		red.prototype.dom.next(elem) : elem;
	},
	
	last : function ( elem ) {
		elem = elem.lastChild;
		return (elem.nodeType == 3 && !/\S/.test(elem.nodeValue)) ?
		red.prototype.dom.prev( elem ) : elem;
	},
	
	childs : function ( elem ) {
		theChildren = new Array();
		var tempNodes = elem.childNodes;
		for (var i = 0; i < tempNodes.length; i++) {
			if (tempNodes[i].nodeType == 1 || (tempNodes[i].nodeType == 3 && !/\S/.test(elem.nodeValue))) {
				theChildren.push(tempNodes[i]);
			}
		}
		return theChildren;
	},
	
	parent : function ( elem ) {
		return elem.parentNode;
	},
	
	ancestor : function ( elem, num ) {
		num = num || 1;
		for (var i = 0; i < num; i++) {
			if (elem != null) {
				elem = elem.parentNode;
			}
		}
		return elem;
	},
	
	text : function ( e ) {
		var t = "";
		e = e.childNodes || e;
		for ( var i = 0; i < e.length; i++ ) {
			t += e[i].nodeType != 1 ?
			e[i].nodeValue : red.prototype.dom.text(e[i].childNodes);
		}
		return t;
	},
	
	insert : function (elem, parent) {
		if(parent == null){
			document.body.appendChild(elem);
		}
		else{
			parent.appendChild(elem);
		}
	},
	
	insertBefore : function(elem, elemB){	
		elemB.parentNode.insertBefore(elem, elemB);
	},
	
	insertAfter : function(elem, elemA){	
		elemA.parentNode.insertBefore(elem, elemA.nextSibling);
	},
	
	remove : function ( elem ) {
		elem.parentNode.removeChild(elem);
	},
	
	create : function (typ,parent) {
		var newele = document.createElement(typ);
		red.prototype.dom.insert(newele,parent);
		return newele;
	},
	
	element : function(typ){
		return document.createElement(typ);
	},
	
	make : function ( string ) {
		var temp = document.createElement("div");
		temp.innerHTML = string;
		return temp;
	},
	
	clear : function (elem){
		var childs = red.prototype.dom.childs(elem);
		for(var i=0;i<childs.length;i++){
			red.prototype.dom.remove(childs[i]);
		}
	}
		


};