/*
    AjaxLib 1.0
    Copyright (C) 2008  Lucas Rezende Coutinho <lrclucas@gmail.com>
 
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    Ex:
    ajax = new Ajax();
    ajax.request({
    	url:'foo.php',
    	data:{'foo':'bar'},
    	success:function(response){
		alert(response);
	}
*/
function Ajax(){
	xmlhttp = null; //Objeto xml http request
	browser = { //Implementações futuras... bug cache IE
		firefox:false,
		ie:false,
		safari:false,
		opera:false,
		getBrowser:function(){
			userAgent = navigator.userAgent.toLowerCase();
			this.safari = /webkit/.test( userAgent );
			this.opera = /opera/.test( userAgent );
			this.ie = /msie/.test( userAgent ) && !/opera/.test( userAgent );
			this.firefox = /mozilla/.test( userAgent ) && !/(compatible|webkit)/.test( userAgent );
		}
	};
	var settings = {
		url:null, //Url obrigatório
		method:'get', //Método 
		async:true,//Indica que a comunicação irá ser assíncrona ou não. Default true
		type:'json', //Tipo de requisição : json,xml ou texto
		data:null, //Dados
		user:null, //Caso tenha usuário
		password:null, //Caso tenha senha
		loading:function(){},
		beforeSend:function(){
			document.getElementsByTagName('body')[0].style.cursor='wait';
		},
		complete:function(){
			document.getElementsByTagName('body')[0].style.cursor='default';
		},
		success:function(){}
	};
	
	function init(){
		this.browser.getBrowser();
		try { 
			this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); 
		} catch (e) { 
			try { 
				this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); 
			} catch (E) { 
				this.xmlhttp = false; 
			} 
		} 
		if  (!this.xmlhttp && typeof  XMLHttpRequest != 'undefined' ) { 
			try  { 
				this.xmlhttp = new  XMLHttpRequest(); 
			} catch  (e) { 
				this.xmlhttp = false ; 
			} 
		}
	}
	function autoSettings(user_settings){
		var new_settings={};
		for (i in settings)
			new_settings[i] = settings[i];
		if (user_settings)
		{
			for(i in user_settings)
				new_settings[i] = user_settings[i];
		}
		settings = new_settings;
		return true;
	}
	function checkResponse(){
		if(xmlhttp.readyState==0)
			settings.beforeSend();
		if (xmlhttp.readyState==1)
			settings.loading();
		if (xmlhttp.readyState==2)
			settings.complete();
		if (xmlhttp.readyState==4)
		{
			if (xmlhttp.status==200)
			{
				if (xmlhttp.responseText!=null)
				{
					if (settings.type.toLowerCase()=='json')
					{
						responseText = xmlhttp.responseText;
						if (typeof(responseText=='object') && responseText!='')
						{
							responseText = responseText.replace(/[\n\r]/g,"");
							responseText = eval ("("+responseText+")");
						}
					}
					else if (settings.type.toLowerCase()=='xml')
						responseText = xmlhttp.responseXML;
					else						
						responseText = xmlhttp.responseText;
					settings.success(responseText,xmlhttp.status);
				}
			}
			else
			{
				alert(xmlhttp.status);
			}
		}
	}
	function sizeOf(object){
		//Tamanho objeto
		var j = 0 ;
		for (i in object)
			j++;
		return j;
	}
	function parseUrl(){
		url = '?';
		size = sizeOf(settings.data);
		j = 1;
		for (i in settings.data)
		{
			(j!=size)?url += i+'='+settings.data[i]+'&':url += i+'='+settings.data[i];
			j++;
		}
		settings.url = settings.url+url;
	}
	
	init();//Inicializando o objeto xmlhttprequest
	return {
		request:function(settings_user){
			autoSettings(settings_user);
			if (settings.url==null)
			{
				alert('URL para requisição vazia.');
			}
			else
			{
				if (toString(typeof(settings.data))!='string')
				{
					parseUrl();//Converte o objeto para o formato url encode
				}
				else
					settings.url = settings.url+'?'+settings.data;
					
				xmlhttp.open(settings.method,settings.url,settings.async,settings.user,settings.password);
				xmlhttp.setRequestHeader("X-Requested-With", "XMLHttpRequest");
				if (settings.method.toLowerCase()=='post')
				{
					var data = settings.data.split(split("\?"))[1];
					xmlhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
					xmlhttp.setRequestHeader("Content-length", data.length);	
					xmlhttp.setRequestHeader("Connection", "close");
				}
				xmlhttp.onreadystatechange = checkResponse;
				xmlhttp.send(null);
			}
		}
	}
}