/*
V.08042804
A.Alex.li
D.AJAX Object
Copyright (c) 2008, Eachnet All rights reserved.
*/
var Ajaxer=function(){	
	Ajaxer.extend(this,Ajaxer.settings);
	this.request=function(s){		
		Ajaxer.extend(this,s);
		if(this.data)this.data=Ajaxer.param(this.data);
		//add ajax events handler
		if(this.onStart)this.event.add("onStart",this.onStart);
		if(this.onComplete)this.event.add("onComplete",this.onComplete);
		if(this.onTimeout)this.event.add("onTimeout",this.onTimeout);
		if(this.onException)this.event.add("onException",this.onException);
		if(this.onParseError)this.event.add("onParseError",this.onParseError);
		// if data is available, append data to url for get requests
		if(this.data && this.method.toLowerCase()=="get"){
			this.url+=(this.url.match(/\?/)?"&":"?")+this.data;
			this.data=null;			
		}
		//if no cache, append random number to url for get requests
		if(!this.cache && this.method.toLowerCase()=="get"){
			this.url+=(this.url.match(/\?/)?"&":"?")+"r="+Math.random();
		}
		//create the request object
		var xml=window.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest();
		//open the socket
		this.async=true;
		xml.open(this.method,this.url,this.async);
		//setRequestHeader
		if(this.data)xml.setRequestHeader("Content-Type", this.contentType);
		xml.setRequestHeader("X-Requested-With", "XMLHttpRequest");
		//timeout checker
		if(this.async && this.timeout>0){
			setTimeout(
				function(){
					if(xml)xml.abort();
					this.event.trigger("onTimeout",{url:me.url,method:me.method,data:me.data});
				},this.timeout
			);
		}
		var me=this;
		this.event.trigger("onStart");
		//state change listener	
		xml.onreadystatechange=function(){	
			if(xml.readyState==4){		
				if(xml.status==200){					
					try{				
						var data=Ajaxer.httpData(xml,me.dataType);						
					}catch(e){
						me.event.trigger("onParseError",e);
					}
					me.event.trigger("onComplete",data);
				}else{
					me.event.trigger("onException",{url:me.url,method:me.method,data:me.data,status:xml.status});
				}
			}
		}
		try{
			xml.send(this.data);
		}catch(e){}
	};
	this.post=function(url,data,callback,dataType){
		if(Ajaxer.isFunction(data)){
			callback=data;
			data=null;
		}
		this.request({
			url:url,
			data:data,
			onComplete:callback,
			method:"post",
			dataType:dataType
		});
	};
	this.get=function(url,data,callback,dataType){
		if(Ajaxer.isFunction(data)){
			callback=data;
			data=null;
		}
		this.request({
			url:url,
			data:data,
			onComplete:callback,
			method:"get",
			dataType:dataType
		});
	};
	this.event={
		events:{},
		add: function(type,handler){			
			if(typeof type=="string" && Ajaxer.isFunction(handler))this.events[type]=handler;			
		},
		trigger: function(){
			if(typeof arguments[0]=="string")type=arguments[0];
			if(this.events[type]){
				var arg=[];
				for(var i=1,l=arguments.length;i<l;i++){
					arg.push(arguments[i]);
				}
				this.events[type].apply(this,arg);
			}		
		}
	}
}
Ajaxer.extend=function(){
	var target = arguments[0] || {};
	var len=arguments.length;
	if(len==1)target=this;
	for(var i=0;i<len;i++){
		var prop=arguments[i];
		if(prop!=null){
			if(target==prop)continue;
			for(var j in prop){
				if(prop!=undefined)target[j]=prop[j];
			}
		}
	}
	return target;
};
Ajaxer.extend({
	settings: {
		method: "get",
		timeout: 0,
		contentType: "application/x-www-form-urlencoded",
		async: true,
		data: null,
		dataType: null,
		cache: false
	},
	$: function(id){
		return document.getElementById(id);
	},	
	param: function(p){
		var a=[];
		for(var i in p){
			a.push(encodeURIComponent(i)+"="+encodeURIComponent(p[i]));
		}
		return a.join("&").replace(/%20/g, "+");	
	},
	isFunction: function(f){
		return !!f && typeof f != "string" && !f.nodeName && 
		f.constructor != Array && /function/i.test( f + "" );
	},
	httpData: function(data,type){
		var ct=data.getResponseHeader("content-type");		
		var isXML= type == "xml" || !type && ct && ct.indexOf("xml") >= 0;
		data=isXML ? data.responseXML : data.responseText;
		return data;
	}
});