var Class = {
	create: function() {
		return function() { this.initialize.apply(this, arguments); }
	}
}

Object.extend = function(destination, source) {
	for (property in source)
		destination[property] = source[property];
	return destination;
}

Function.prototype.bind = function(object) {
	var __method = this;
	return function() { return __method.apply(object, arguments); }
}

function $() {
	var elements = new Array();
	for (var i = 0; i < arguments.length; i++) {
		var element = arguments[i];
		if (typeof element == 'string')
			element = document.getElementById(element);
		if (arguments.length == 1) 
			return element;
		elements.push(element);
	}
	return elements;
}

document.getElementsByRegex = function(r) {
	var children = document.getElementsByTagName('*') || document.all;
	var elements = new Array();
	for (var i=0; i<children.length; i++) {
		if (children[i].id.match(r))
			elements.push(children[i]);
	}
	return elements;
}

Ajax = Class.create();
Ajax.prototype = {
	initialize: function (o) {
		this.method = o.method || 'get';
		this.data = o.data || '';
		this.before = o.before;
		this.after = o.after;
		this.url = o.url;

		if (this.url == null)
			throw ('usage: Ajax object needs url');
		if (typeof(this.after) != 'function')
			throw('usage: Ajax object needs an "after" which is a function');

		if (window.ActiveXObject)
			this.r = new ActiveXObject('Microsoft.XMLHTTP');
		else if (window.XMLHttpRequest)
			this.r = new XMLHttpRequest();
		else throw('transport: unavailable');

		this.r.open(this.method, this.url, true);
		this.r.onreadystatechange = this.handler.bind(this);
		if (this.method.match(/^post$/i))
			this.r.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
		if (this.before) this.before();
		this.r.send(this.data);
	},

	handler: function () {
		if (this.r.readyState != 4) return;
		var answer, exc;
		if (this.r.status == 200 || this.r.status == 304) {
			try {
				answer = eval('('+this.r.responseText+')');
				this.after(true, answer, null);
			}
			catch (exc) { this.after(false, null, 'json: malformed') }
		}
		else
			this.after(false, null, 'http: '+this.r.statusText);
	}
};
