function $(id) {

	return document.getElementById(id);
}


var global = function() {

	var obj = {},
		trimregexp = /^\s+|\s+$/g;

	obj.trim = function(s) { return s.replace(trimregexp,''); };

	obj.d2h = function(d) { return d.toString(16); };

	obj.h2d = function(h) { return parseInt(h,16); };

	obj.getvalbounds = function(val,min,max) {

		var val = Math.max(val,min);
		return Math.min(val,max);
	};

	obj.getquerystring = function() { return window.location.search.replace(/^\?/,''); };

	obj.addhtmlclass = function(name) {

		// fetch <html> node
		var el = document.getElementsByTagName('html'),
			regexp = new RegExp('(^| )' + name + '( |$)');

		if (!el.length) return;
		el = el[0];

		// check if class name already exists
		if (regexp.test(el.className)) return;
		el.className = obj.trim(el.className + ' ' + name);
	};

	return obj;
}();


global.event = function() {

	var obj = {},
		doc = document,
		win = window,
		eventcache = [],
		mozmousescroll = 'DOMMouseScroll';

	obj.add = function(o,type,func) {

		if (win.addEventListener) {
			// W3
			o.addEventListener(type,func,false);

			// mouse wheel event for Mozilla browsers
			// Opera & Safari attach with o.addEventListener('mousewheel',func,false) above
			if (iseventmousewheel(type)) o.addEventListener(mozmousescroll,func,false);

			return;
		}

		if (win.attachEvent) {
			// IE
			// methods here to fix 'this' upon event call, correct passing of the event object
			// and event tracking (eventcache) to allow memory cleanup on document unload
			var fname = type + func,
				ename = 'e' + fname;

			o[ename] = func;
			o[fname] = function() { return o[ename](win.event); };
			o.attachEvent('on' + type,o[fname]);
			eventcache[eventcache.length] = { o: o,type: type,func: func };
		}
	};

	obj.remove = function(o,type,func) {

		if (win.removeEventListener) {
			// W3
			o.removeEventListener(type,func,false);

			// mouse wheel event for Mozilla browsers
			if (iseventmousewheel(type)) o.removeEventListener(mozmousescroll,func,false);

			return;
		}

		if (win.detachEvent) {
			// IE
			var fname = type + func;

			o.detachEvent('on' + type,o[fname]);
			o[fname] = null;
			o['e' + fname] = null;
		}
	};

	function iseventmousewheel(type) { return (type == 'mousewheel'); }

	obj.preventdefault = function(e) {

		if (e.preventDefault) {
			e.preventDefault();
			return;
		}

		e.returnValue = false; // IE equivalent
	};

	obj.gettarget = function(e) {

		// W3/IE target
		var target = e.target || e.srcElement;

		// defeat Safari bug
		return (target.nodeType == 3) ? target.parentNode : target;
	};

	obj.getrelatedtarget = function(e) {

		// W3/IE related target
		return e.relatedTarget || ((e.type == 'mouseover') ? e.fromElement : ((e.type == 'mouseout') ? e.toElement : false));
	};

	obj.getmouseposition = function(e) {

		// W3
		if (e.pageX || e.pageY) return {
			x: e.pageX,
			y: e.pageY
		};

		// IE
		var docbody = doc.body,
			docel = doc.documentElement;

		if (e.clientX || e.clientY) return {
			x: e.clientX + docbody.scrollLeft + docel.scrollLeft,
			y: e.clientY + docbody.scrollTop + docel.scrollTop
		};

		// can't determine mouse position
		return { x: 0,y: 0 };
	};

	obj.getmousewheeldir = function(e) {

		// e.detail for Mozilla & Opera, e.wheelData for IE & Safari
		// returns -1 for up movements, 1 for down movements
		return (((e.detail) ? (e.detail * -1) : e.wheelDelta) < 0) ? 1 : -1;
	};

	obj.ismouseenterleave = function(el,e) {

		var rel = obj.getrelatedtarget(e);
		return !(!rel || ischildof(el,rel));
	};

	function ischildof(parent,child) {

		if (!child) return false;
		if (parent == child) return true;

		// call ischildof() recursively
		return ischildof(parent,child.parentNode);
	}

	obj.getkeycode = function(e) { return e.keyCode || e.which; };

	if (win.detachEvent) {
		// setup IE event cleanup routine to run on document unload
		obj.add(win,'unload',function() {

			// cycle eventcache array and remove all events to avoid IE memory leaks
			for (var i = 0,j = eventcache.length;i < j;i++) {
				obj.remove(eventcache[i].o,eventcache[i].type,eventcache[i].func);
			}

			eventcache = null;
		});
	}

	return obj;
}();
