var U; 
var UTIL = U = new function() {
	var t=this;
	t.D = t.def = function(e) { return (typeof(e) != 'undefined'); }
	t.Try = function() { for (var fn,i = 0; ( fn = arguments[i] ); i++) try { return fn(); } catch(e) { } }
	
	t.forEach = function(a, fn, o) { for (var l=a.length,i = 0; i<l; i++) (o) ? fn.call(o, a[i]) : fn(a[i]); }
	t.from = function(a, f, fn, o) { for (var l=a.length,i = f; i<l; i++) (o) ? fn.call(o, a[i]) : fn(a[i]); }
	t.indexOf = function(a, v, f) { for (var i = (U.D(f)) ? f : 0,l = a.length; i < l; i++) if (a[i] == v) return i; return -1; }
	t.lastIndexOf = function(a, v, f) { for (var i = Math.min((U.D(f)) ? f : a.length, a.length - 1); i >= 0; i--) if (a[i] == v) return i; return -1;}
	t.every = function(a, fn, o) { for (var l=a.length,i = 0; i < l; i++) if ( !((o) ? fn.call(o, a[i]) : fn(a[i]) )) return false; return true; }
	t.some = function(a, fn, o) { for (var l=a.length,i = 0; i < l; i++) if ( (o) ? fn.call(o, a[i]) : fn(a[i]) ) return true; return false; }
	t.filter = function(a, fn, o) { for (var r = [],l=a.length,i = 0; i < l; i++) if ( (o) ? fn.call(o, a[i]) : fn(a[i]) ) r.push(a[i]); return r;	}
	t.map = function(a, fn, o) { for (var r = [],l=a.length,i = 0; i < l; i++) r.push ( (o) ? fn.call(o, a[i]) : fn(a[i]) ); return r; }
	t.contains = function(a, v) { return (U.indexOf(a, v) > -1); },
	t._bind = function(o, k, fn) { if (!o.prototype[k]) o.prototype[k] = function(b,c, d) { return fn(this, b, c, d) } }
	t.deleteItem = function(a, v) { var i; while ((i = a.indexOf(v)) >= 0) a.splice(i, 1); }
	t.swapItems = function(a, i, j) { var e = a[i]; a[i] = a[j]; a[j] = e; };
	t.moveItems = function(a, i, j, l) { l = l || 1; if (j > i) j -= l; var r = a.splice(i, l); r.unshift(j, 0); a.splice.apply(a, r); }
	t.copy = function(o) { var key,r = { }; for (key in o) r[key] = o[key]; return r; }
	t.shallow = function(a) { var i=a.length-1,r = []; if (i>=0) do { r.unshift(a[i]) } while (i--); return r; }
	
	t.forEach(['moveItems','deleteItem','forEach','from','indexOf','lastIndexOf','every','some','filter','map','contains'], function(k) {t._bind(Array, k, t[k]); });

	t.copy = function(o) {
		var result, k;
		
		if (U.isArray(o)) { result = [ ]; o.forEach(function(e) { result.push(U.copy(e)) }); }
		else if (U.isObject(o)) { result = { }; for (k in o) { result[k] = U.copy(o[k]); }; }
		else result = o;
	
		return result;
	}
	
	t.multiSplit = function(s) {
		if (!arguments[1]) return s;
		var a = s.split(arguments[1]);
		var e,i,d = [ '' ], r = [];
		for (i=2,e;(e=arguments[i]);i++) d.push(e);
		for (i=0;(i<a.length);i++) { 
			d[0] = a[i];
			r.push(t.multiSplit.apply(this, d));
		}
		return r;
	}
	
	t.isFunction = function(a) { return (typeof(a) == 'function'); }
	t.isObject = function(a) { return (a && typeof(a) == 'object') || U.isFunction(a); }
	t.isAlien = function(a) { return U.isObject(a) && typeof(a.constructor) != 'function'; }
	t.isArray = function(a) { return U.isObject(a) && a.constructor == Array; }

	t.FN = function(o, fn) { 
		for (var args=[], i=2, len=arguments.length; i<len; i++) args.push(arguments[i]);
		return function() { return fn.apply(o, args) }
	};
	
	t.entityEncoder1 = /%([0-9a-fA-F][0-9a-fA-F])/g;
	t.entityEncoder2 = /%u([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])/g;
	t.entityDecoder1 = /&\#x([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]);/g;
	t.entityDecoder2 = /&\#x([0-9a-fA-F][0-9a-fA-F]);/g;
	t.encodeEntities = function(str) { str = str.toString(); return escape(str).replace(/%20/g, ' ').replace(t.entityEncoder2, '&\#x$1;').replace(t.entityEncoder1, '&\#x$1;');	}
	t.decodeEntities = function(str) { str = str.toString(); return unescape(str.replace(t.entityDecoder1, '%u$1').replace(t.entityDecoder2, '%$1')); }
	t.fromEntities = function(s) {  var t=document.createElement("textarea"); t.innerHTML=s.replace(/</g,"&lt;").replace(/>/g,"&gt;"); return t.value; }
	
	t.toInt = function(val, d) { d=d||0; val = parseInt(val, 10); return (isNaN(val))?d:val; }
	
	t.compare = function(s1, s2) { var key; for (key in s1) if (s1[key]!=s2[key]) return false; return true; }
	
	t.structMerge = function(e) {
		for (var key,i=1,e1;(e1=arguments[i]); i++) {
			for (key in e1) e[key] = U.D(e[key])?e[key]:e1[key];
		}
		return e;
	}
	t.toInt = function(i) {
		var r,type=typeof(i);
		switch(type) {
			case 'number'	: return Math.round(i);
			case 'string'	: return (isNaN(r=parseInt(i,10))?0:r);
		}
		return 0;
	}
	t.max = function(n) { for (var i=1;i<arguments.length;i++) n=Math.max(n,arguments[i]); return n; }
	
	t.colour = function(c) { c = c.toString(); while (c.length<6) c='0'+c; return c; }
}

var DOM = new function() {
	
	this.__trash = [ ];
	
	this.get = function(e) {
		if(typeof(e)!='string') return e;
		return U.Try(function() { return document.getElementById(e); }, function() { return document.all[e]; }, function() { return null; } );
	}
	
	this.structure = function(s, top, h) {
		if (U.isFunction(s)) return s();
		s.t = s.t || 'div';
		var key, item, index, ele = (s.f) ? s.f() : document.createElement(s.t);
		top = top || ele;
		
		if (h) h.appendChild(ele);
		
		if (s.r) top[s.r] = ele;
		if (s.a) for (key in s.a) ele.setAttribute(key, s.a[key]);
		if (s.e) { ele.ooCleanupQ = []; for (key in s.e) { ele.ooCleanupQ.push[key]; ele[key] = s.e[key]; } }
		if (U.D(s.x)) ele.appendChild(document.createTextNode(s.x));
		if (s.s) s.s.forEach(function(item) { ele.appendChild (DOM.structure(item, top)); }, this);
		if (s.sl) s.sl.forEach(function(item) { ele.appendChild (DOM.structure({ cn: item }, top)); }, this);
		if (s.y) for (key in s.y) ele.style[key] = s.y[key];
		if (s.tr) s[key] = top;
		if (s.d) DHTML.sizeTo(ele, s.d[0],s.d[1]);
		if (U.D(s.W)) DHTML.setWidth(ele, s.W);
		if (U.D(s.H)) DHTML.setHeight(ele, s.H);
		if (U.D(s.X)) DHTML.divX(ele, s.X);
		if (U.D(s.Y)) DHTML.divY(ele, s.Y);
		if (s.cn) ele.className = s.cn;
		if (U.D(s.id)) ele.id = s.id;
		if (s.c) { DHTML.bind.apply(DHTML, [ ele ].concat(s.c)); }			
		
		for (key in s) if (key.charAt(0)=='_') ele[key.substring(1)]=s[key];

		return ele;
	}

	this.div = function(cn, html, id, t) {
		t = t || 'div';
		var r = document.createElement(t);
		
		r.className = cn;
		if (id) r.id = id;
		if (html) r.innerHTML = html;
		
		return r;
	}
	
	this.getElements = function() { var result={}; U.forEach(arguments, function(a) { result[a] = DOM.get(a); } ); return result; },

	this.parentOf = function(o, p) {
		if (U.isArray(p)) return p.some(function(e) { return DOM.parentOf(o, e); });

		var parent = o;
		if (p == o) return true;
		
		while (parent = parent.parentNode) {
			if (p == parent) return true;
		}
		
		return false;
	}
	
	this.trash = function() {
		for (var i=0;i<arguments.length;i++) DOM.__trash.push(arguments[i]);
	}
	
	this.emptyTrash = function() {
		var e;
		if (!this.trashEle) this.trashEle = DOM.structure({ y: { top: '-100px', position: 'absolute', height: '1px', display: 'none' }, e: { stat: 'trashNode' } });
		
		while (this.__trash.length) {
			e=this.__trash.pop();
			if (e) {
				if (e.ooState=='active') OO.dispose(e);
				e.innerHTML = '';
				this.trashEle.appendChild(e);
			}
		}
		this.trashEle.innerHTML = '';

	}
	
}