	DomUtils = function () {

		return {

			/* Gets previous sibling ignoring empty text nodes
				Gets previous
				If text node gets previous again */
				
			getPrevious: function(el) {
							 
				var previous = $.id(el).previousSibling;
				
				while(previous.nodeType == 3)
					previous = previous.previousSibling;
				
				return previous;
			},

			/* Gets next sibling ignoring empty text nodes
				Gets next
				If text node gets previous again */
							 
			getNext: function(el) {	
						 
				var next = $.id(el).nextSibling;
				
				while(next.nodeType == 3)
					next = next.nextSibling;
				
				return next;
			},

			/* Gets all children ignoring text nodes. Returns array
				Gets all children
				Makes new array
				Loops through children and pushes non-text nodes into the array */			

			getChildren: function(el) {
							 
				var parent = $.id(el);
				var allChildren = parent.childNodes;
				var children = new Array();
				
				for(var i = 0; i < allChildren.length; i++) {
					if(allChildren[i].nodeType != 3)
						children.push(allChildren[i]);
				}

				return children;
			},

			getViewXY: function() {

				var x,y;
				
				if (self.innerHeight) {
					x = self.innerWidth;
					y = self.innerHeight;
				}
				
				else if (document.documentElement && document.documentElement.clientHeight) {
					x = document.documentElement.clientWidth;
					y = document.documentElement.clientHeight;
				}
				
				else if (document.body) {
					x = document.body.clientWidth;
					y = document.body.clientHeight;
				}

				return {x: x, y: y};
			},


			getDocXY: function() {

				var margin = parseInt(DomUtils.getStyle(document.body,'margin-bottom')) + parseInt(DomUtils.getStyle(document.body,'margin-top'));
	
				var Xa = (Xa = document.documentElement.clientWidth)? Xa: -1; //IE and Mozilla window width
				var Xb = (Xb = document.body.offsetWidth + margin)? Xb: -1; //IE and Mozilla document width
				var Xc = (Xc = document.body.clientWidth)? Xc: -1; //exceptions
				var Xd = (Xd = document.body.scrollWidth)? Xd: -1; //exceptions
				var Xe = (Xe = self.innerWidth)? Xe: -1; //alt IE and Mozilla window width

				var sortedX = [Xa,Xb,Xc,Xd,Xe].sortNumb(); //sort all possible widths

				var Ya = (Ya = window.innerHeight + window.scrollMaxY)? Ya: -1; //IE and Mozilla scroll height
				var Yb = (Yb = document.documentElement.clientHeight)? Yb: -1;  //IE and Mozilla window height
				var Yc = (Yc = document.documentElement.scrollHeight)? Yc: -1; //Opera and Safari scroll height
				var Yd = (Yd = document.body.offsetHeight + margin)? Yd: -1; //IE and Mozilla body height
				var Ye = (Ye = document.body.scrollHeight)? Ye: -1; //exceptions
				var Yf = (Yf = document.body.clientHeight)? Yf: -1; //exceptions
				var Yg = (Yg = self.innerHeight)? Yg: -1; //alt IE and Mozilla window height

				var sortedY = [Ya,Yb,Yc,Yd,Ye,Yf,Yg].sortNumb(); //sort all possible heights

				return {x: sortedX[sortedX.length-1], y: sortedY[sortedY.length-1]} //return largest width and largest height
			},

			getScroll: function() {

				var l,t;

				if(document.documentElement && document.documentElement.scrollTop) {
					l = document.documentElement.scrollLeft;
					t = document.documentElement.scrollTop;
				}
				
				else if(document.body) {
					l = document.body.scrollLeft;
					t = document.body.scrollTop;
				}
				
				return {l: l, t: t};
			},

			getTrueOffset: function(el) {
							   
				var el = $.id(el);
				var l = 0, t = 0;
				
				do {
					l += el.offsetLeft || 0;
					t += el.offsetTop || 0;
					el = el.offsetParent;
				}
				while (el);
				
				return {l: l, t: t};
			},	

			getPosOffset: function(el) {

				var el = $.id(el);
				var l = el.offsetLeft + document.body.offsetLeft;
				var t = el.offsetTop + document.body.offsetTop;
				var parent = el.parentNode;

				while (parent.nodeName != 'BODY') {
					var ps = DomUtils.getStyle(parent,'position')

					if(ps == 'absolute' || ps == 'relative')
						break;

					l += parent.offsetLeft || 0;
					t += parent.offsetTop || 0;

					parent = parent.parentNode;
				}

				return {l: l, t: t};
			},

			makeAbsolute: function(el, complete) {

				var el = $.id(el);

				if(el.style.position == 'absolute')
					return;

				el.oldLeft = DomUtils.getStyle(el,'left');
				el.oldTop = DomUtils.getStyle(el,'top');
				el.oldWidth = DomUtils.getStyle(el,'width');
				el.oldHeight = DomUtils.getStyle(el,'height');
				el.oldParent = el.parentNode;
				el.oldSibling = el.nextSibling;

				var offset = (complete == true)? DomUtils.getTrueOffset(el): DomUtils.getPosOffset(el);
				var left = offset.l;
				var top = offset.t;
				var width = el.clientWidth;
				var height = el.clientHeight;

				el.style.position = 'absolute';
				el.style.left = left + 'px';
				el.style.top = top + 'px';
				el.style.width = width + 'px';
				el.style.height = height + 'px';
			},

			makeRelative: function(el) {

				var el = $.id(el);

				if(el.style.position == 'relative')
					return;

				el.style.position = 'relative';
				el.style.left = el.oldLeft;
				el.style.top = el.oldTop;
				el.style.width = el.oldWidth;
				el.style.height = el.oldHeight;
			},

			setAnyAttribute: function(el,attribute,value) {

				var el = $.id(el);

				switch(attribute) {
					
					case "style":
						document.all?
							el.style.setAttribute("cssText", value):
							el.setAttribute("style", value);
							break;
							
					case "className":
						document.all?
							el.setAttribute("className", value):
							el.setAttribute("class", value);
							break;	    
							
					default:
						el.setAttribute(attribute, value);
				}
			},

			getAnyAttribute: function(el,attribute) {

				var el = $.id(el);
				if(!el)
					return false;

				switch(attribute) {
					
					case "style":
						var value = document.all?
							el.style.getAttribute("cssText"):
							el.getAttribute("style");
							break;
							
					case "class":
						value = document.all?
							el.getAttribute("className"):
							el.getAttribute("class");
							break;

					default:
						value = el.getAttribute(attribute);
				}

				return value;
			},

			//Equalises 'getComputedStyle(') W3 DOM method, 'currentStyle' property of Microsoft, and 'style' property
			getStyle: function(el,property) {
	
				var el = $.id(el);
				var styleList;
				
				var value = el.style[property.toFirstUpper()];
				
				if(property == 'opacity') {
					var regexp = /alpha\s?\(\s?opacity\s?=/ig;
					if(value.match && value.match(regexp))
						value = value.parseInts();	
				}
				
				if(!value) {
					if (document.defaultView && document.defaultView.getComputedStyle) {
						styleList = document.defaultView.getComputedStyle(el,null);
						value = styleList.getPropertyValue(property);
						value = value.toFirstUpper();
					}

					else if(el.currentStyle) 
						value = el.currentStyle[property.toFirstUpper()]
				}

				return value == 'auto'? null: value;    
			},
	
			//equalises IE and W3 DOM opacity settings
			setStyle: function(el,property,value) {

				var el = $.id(el);
				var property = property.toFirstUpper();

				if(property == 'opacity') {
					el.style.opacity = value;
					el.style.filter = "alpha(opacity=" + value * 100 + ")";
				}

				else 
					el.style[property] = value;
			},

			addClassName: function(element, className) {
				if(!$.id(element))
					return;
				var string = this.getAnyAttribute(element, 'class');
				if(string.indexOf(className) == -1)
					string += ' ' + className;
				this.setAnyAttribute(element, 'className', string)
			},
			
			removeClassName: function(element, className) {
				if(!$.id(element))
					return;
				var string = this.getAnyAttribute(element, 'class');
				if(string == false)
					return;
				string = string.replace(className, '');
				this.setAnyAttribute(element, 'className', string);
			},

			//**** NEEDS TO COME OUT. Need seperate Animation and Fade class ****/
			fade: function (el, dir, vis, time, step, end) { 
				var obj = $.id(el);
				if (typeof time == 'undefined') time = 100;
				if (typeof step == 'undefined') step = 100;
				if (typeof end == 'undefined' && dir > 0) end = 0.9999;
				if (typeof end == 'undefined' && dir < 0) end = 0;
	    
				if(obj.timer == null) {
					obj.timer=0;
					obj.opacity=0;
				}

				if(obj.timer!==0) {
					clearInterval(obj.timer);
					obj.timer=0;
				}
	    
				if(obj.style.visibility !== 'visible') 
					obj.style.visibility = 'visible';
				
				obj.timer = setInterval(fadeloop, time/step);
	   
				function fadeloop() {
					obj.opacity += dir/step;
					if ((dir > 0 && obj.opacity >= end) || (dir < 0 && obj.opacity <=end)) {
						obj.opacity = end;
							if(typeof vis !== undefined) {
								obj.style.visibility = vis;
								clearInterval(obj.timer);
							}
					}
					obj.style.opacity = obj.opacity;
					obj.style.filter = "alpha(opacity=" + obj.opacity * 100 + ")";
				}
			},

			//**** Maybe unnecessary but if keep should probably go in ElementHandler ****/
			swap: function(el, newPlace) {	

				var current = $.id(el);
				var parent = current.parentNode;
				var other = $.id(newPlace);
				var current_new = current.cloneNode(true);
				var other_new = other.cloneNode(true);
	    
				parent.replaceChild(current_new, other);
				parent.replaceChild(other_new, current);
			},

			//**** Decide what to do with these when redo Display. Something needs to lose them, or inherit ****/
			show: function() {

				for(var i = 0; i < arguments.length; i++) {
					var el = $.id(arguments[i]);

					el.style.visibility = 'visible';
					el.style.display = 'block';
				}
			},

			hide: function() {

				for(var i = 0; i < arguments.length-1; i++) {
					var el = $.id(arguments[i]);

					el.style.visibilty = 'hidden';
					if(arguments[arguments.length-1] == true)
						el.style.display = 'none';
				}
			}
	    }

	}();
