function $(element) { 
	return (typeof(element) == "string") ? document.getElementById(element) : element;
}

/* Hash/Object functions */
var Hash = {
	extend: function(a, b) {
		var hsh = {};
		for(var k in a) { hsh[k] = a[k]; }
		for(var k in b) { hsh[k] = b[k]; }
		return hsh;
	},

	update: function(source, hsh) { for(var k in a) { source[k] = hsh[k]; } },

	isArray: function(obj) {
		return obj instanceof Array;
	},

	isString: function(obj) {
		return (typeof obj == 'string');
	},

	toQueryString: function(source) {
		var queryString = [];
		var i = 0;
		if(source['tagName'] && source.tagName == 'FORM') {
			var elems = source.elements;
			for(var j=0;j<elems.length;j++) { 
				var el = elems[j];
				if (!el.disabled && el.type != 'submit' && el.name) {
					if((el.type != 'radio' && el.type != 'checkbox') || el.checked) {
						queryString[i++] = encodeURIComponent(el.name) + '=' +  encodeURIComponent(el.value); 
					}
				}
			}
		} else {
			for (var property in source) queryString[i++] = encodeURIComponent(property) + '=' + encodeURIComponent(source[property]);
		}
		return queryString.join('&');
	}
};

/* Array functions */
var A = {
	iter:function(arr, fn) { for(var i = 0; i < arr.length; i++) { fn(arr[i]); } },
	iteri:function(arr, fn) { for(var i = 0; i < arr.length; i++) { fn(arr[i], i); } },
	iterrev:function(arr, fn) { for(var i = (arr.length - 1); i >= 0; i--) { fn(arr[i]); } },
	map:function(arr, fn) { 
		var a = [];
		for(var i=0; i < arr.length; i++) {
			a[i] = fn(arr[i]);
		}
		return a;
	},

	createArray: function(v) {
		if(Hash.isArray(v) && !Hash.isString(v))
			return v;
		else if(!v)
		return [];
		else
			return [v];
	}
};

/* DOM Element functions */
var Element = {
	show: function(id) { 
		var el = $(id);
		el.style.display = "";
		return el;
	}, 
	hide: function(id) {
		var el = $(id);
		el.style.display = "none";
		return el;
	},
	visible: function(id) { return ($(id).style.display != "none"); },
	toggle: function(id) { return (Element.visible(id) ? Element.hide(id) : Element.show(id)); }
};

var F = {
	callLater: function(fn, interval) {
		var gn = function() { fn(); };
		window.setTimeout(gn, interval);
	},
	bind: function(fn, scope, extra_args) {
		var s = (scope || window);
		extra_args = A.createArray(extra_args);
		return function() {
			var args = A.map(arguments).concat(A.createArray(extra_args));
			return fn.apply(scope, args);	
		};
	}
};

/* XMLHTTP */
/* quirksmode.org */
var AJAX = { 
	sendRequest: function(url,callback,postData) {
		var req = AJAX.createXMLHTTPObject();
		if (!req) return;
		var method = (postData) ? "POST" : "GET";
		req.open(method,url,true);
		req.setRequestHeader('User-Agent','XMLHTTP/1.0');
		if (postData)
			req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
		req.onreadystatechange = function () {
			if (req.readyState != 4) return;
			if (req.status != 200 && req.status != 304) {
				return;
			}
			callback(req);
		}
		if (req.readyState == 4) return;
		req.send(postData);
	},

	XMLHttpFactories: function() {
		return [
		function () {return new XMLHttpRequest()},
		function () {return new ActiveXObject("Msxml2.XMLHTTP")},
		function () {return new ActiveXObject("Msxml3.XMLHTTP")},
		function () {return new ActiveXObject("Microsoft.XMLHTTP")}
		];
	},

	createXMLHTTPObject: function() {
		var xmlhttp = false;
		var factories = AJAX.XMLHttpFactories();
		for (var i=0;i<factories.length;i++) {
			try {
				xmlhttp = factories[i]();
			}
			catch (e) { continue; }
			break;
		}
		return xmlhttp;
	},

	update: function(url,id,postData) {
		AJAX.sendRequest(url, function(req) { $(id).innerHTML = req.responseText; }, postData);		
	},

	responseToXMLDoc: function(req) { return req.responseXML.documentElement; },

	loadXMLDoc: function(url, callback, postData) { 
		AJAX.sendRequest(url, function(req) { callback(AJAX.responseToXMLDoc(req)); }, postData); 
	},
	
	evalScripts: function(url, postData) { AJAX.sendRequest(url, function(req) { return eval(req.responseText); }, postData); }, 

	xmlNodeText: function(n) { return (n.textContent || n.innerText || n.text) },

	serializeForm: function (form) { 
		var qs = Array();
		var i = 0;
		var elems = form.elements;
		for(var i=0;i<elems.length;i++) {
			qs[i] = encodeURIComponent(elems[i].name) + '=' +  encodeURIComponent(elems[i].value)
		}     
		return qs.join('&');
	}

}; 

var Effect = {
	// Yellow fade technique
	_shades: {1:'ff', 2:'ee', 3:'dd', 4:'cc', 5:'bb', 6:'aa', 7:'99'},
	highlight: function(elm, i) {
        elm = $(elm);
        if(!i && i != 0) i = 7;
        if(i == 0) {
					elm.style.backgroundColor = "transparent";
					return;
        }
        elm.style.backgroundColor = '#ffff' + Effect._shades[i];
				F.callLater(F.bind(Effect.highlight, this, [elm, i-1], true), 200);
    }
};
