//~ coding: utf8
var Delegate = {};
	Delegate.create = function(o, f) {
		var c = function() {
			var a=[];
			for(var i=0; i<arguments.length; i++) {a[i]=arguments[i];}
			return arguments.callee.args[1].apply(arguments.callee.args[0], a);
		}	
		c.args = arguments;
		return c;
	}		

if (!window.XMLHttpRequest)
    XMLHttpRequest = function () {
        var _xhr_ = false;
        try { _xhr_ = new ActiveXObject("Msxml2.XMLHTTP");}
        catch (e) {
            try {_xhr_ = new ActiveXObject("Microsoft.XMLHTTP");}
            catch(e) {_xhr_ = false;};
        }
        return _xhr_;
    }
// ----------------------------------------------------

function Ajax(m, a) {
	var test = new XMLHttpRequest();
	if(test == false) return false;
	this.XHR = null;
	this.method = m || 'POST';
	this.isAsynchrone = a || true;
	this.canceled = false;
	this.eventIsLoading = true;
	this.eventIsLoaded  = true;
	this.eventIsInteractive = true;
	this.eventIsComplete = true;
}

function Error(m) {
	this.message = m;
}

Ajax.prototype.request = function (url, data) {

	this.canceled = false;
	this.eventIsLoading = true;
	this.eventIsLoaded  = true;
	this.eventIsInteractive = true;
	this.eventIsComplete = true;

	this.url  = url;
	this.datas = null;
	this.XHR = new XMLHttpRequest();
	
	this.XHR.onreadystatechange = Delegate.create(this, this.onStateChange);
	
	if(this.method.toUpperCase() == 'GET') this.url+='?'+this.linearizeDatas(data);
	else this.datas = this.linearizeDatas(data);
	
	this.XHR.open(this.method, this.url, this.isAsynchrone);
	if(this.method.toUpperCase() == 'POST') this.XHR.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
	
	this.XHR.send(this.datas)
}

Ajax.prototype.onStateChange = function() {	
		try {
			if(this.XHR.readyState>3 && this.XHR.status != 200) { 
				throw new Error(
					'An XHR error Appends\n \tEtat XHR :'+this.XHR.readyState+'\n \tStatus XHR : '+this.XHR.status+' !'
				);
			}
		} catch (E) {
			//~ this.XHR.abort();
			if(null != this.onError && !this.canceled) this.onError(E.message);
			this.canceled = true;
		}
		if(!this.canceled) {
			switch(this.XHR.readyState) {
			case 1: 
				if(this.eventIsLoading) {
					this.eventIsLoading = false;
					this.callBack(this.onLoading, this.XHR.readyState);
				}
				break;
			case 2: 
				if(this.eventIsLoaded) {
					this.eventIsLoaded = false;
					this.callBack(this.onLoaded, this.XHR.readyState); 
				}
				break;
			case 3: 
				if(this.eventIsInteractive) {
					this.eventIsInteractive = false;
					this.callBack(this.onDatas, this.XHR.readyState); 
				}
				break;
			case 4: 
				if(this.eventIsComplete) {
					this.eventIsCompete = false;
					this.callBack(this.onComplete, this.XHR); 
				}
				break;
			}
		}
}

Ajax.prototype.callBack = function(func, args) {
	if(null!= func) func(args)
}

Ajax.prototype.linearizeDatas = function(o) {
	var a = [];
	for(var z in o) { a.push(z+'='+o[z]); }
	return a.join('&');
}