lib.x({
	ajax:function(uri,options/*,autoExecute*/) {
		if(this === lib) {
			return new lib.ajax(uri,options,arguments[2]);
		}
		if(uri == '')
			uri = './';
		else if(!uri)
			throw ('Url não definida.');
		
		var free = true;//Status
		options = options || {};
		
		lib.x(options,lib.x({
			method:'get',//Metodo
			uri:uri,
			async:true,
			postData:null,//Dados
			callBack:null,
			timeout:10,//Timeout em segundos
			errors:[]//Log de erros
		},this));
		this.timeout *= 1000;
		this.method = this.method.toUpperCase();//Metodo sempre em maiusculo
		
		if(this.method == 'GET' && this.postData != null) {//QueryString
			this.uri += (this.uri.indexOf('?') > 0 ? '&' : '?') + lib.toQuery(this.postData);
			this.postData = null;//problemas no IE
		}
		else if(this.postData != null) {
			this.postData = lib.toQuery(this.postData);
		}
		
		var tryCallBack = function() {
			try{
				var complete = this.http.readyState == 4;
				this.callBack(this.http,complete);
				if(complete) {
					this.abort();
				}
			}
			catch(e) {
				this.errors.push(e);
			}
		};
		
		var tryTimeout = function() {
			if(this.onTimeout) {
				try {
					this.onTimeout(this.http);
				}
				catch(e) {
					this.errors.push(e);
				}
			}
			this.abort();
		};
		
		this.abort = function() {
			if(this.async) {
				clearInterval(this.onreadystatechange);
				clearTimeout(this.ontimeout);
				this.ontimeout = this.onreadystatechange = null;
			}
			this.http.abort();
			this.http = null;
			free = true;
		};
		
		this.open = function() {
			if(free) {
				free = false;
				this.http = window.ActiveXObject? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();//IE7 tem problemas com XMLHttpRequest
				this.http.open(this.method,this.uri,this.async,this.user,this.pass);
				
				if(this.method == 'POST')
					this.http.setRequestHeader('Content-type','application/x-www-form-urlencoded');
				
				this.http.setRequestHeader('requestType','XMLHttpRequest');
				
				if(this.async) {
					this.onreadystatechange = setInterval(lib.binder(this,tryCallBack),15);
					this.ontimeout = setTimeout(tryTimeout,this.timeout);
				}
				
				this.http.send(this.postData);
				
				if(!this.async)
					lib.binder(this,tryCallBack)();
			}
		};
		if(arguments[2] !== false)
			this.open();
	},
	toQuery:function(obj,sep) {
		sep = sep || '&';
		var _return = '';
		for(var prop in obj)
			_return += prop + '=' + escape(obj[prop]) + sep;
		
		return _return;
	}
});