// JavaScript Document
function Ajax(){

	this.launch = null;	
	
	this.xmlhttp = undefined;
	this.method = undefined;
	this.url = undefined;	
	this.async = true;
	this.type = "TEXT"; 
	this.mime = "";
	
	this.modified = false;
	this.timeout = 0;
	this.loop = 0;
	this.delay = 1000;	
	this.queue = false;
	
	
	var arg = "";
	var get = "";
	var post = "";
	var spend = 0;
	var header = new Array();	
	var handler = {};
	var data = "";
	var ready = true;
	var fetch = null;
	var count = 0;	
	var pause = false;
	var queue = false;
	
	var settimeout = undefined;
	var settimeloop = undefined;

	
	//----------------------------------------------------------------------------------	
	this.construct = function (){
		ready = true;				
		if(settimeout != undefined){
			clearTimeout(settimeout);
			settimeout = undefined;
		}		
		if (window.XMLHttpRequest){
			try{
				this.xmlhttp = new XMLHttpRequest();
			}catch (e){
			}
		}else if (window.ActiveXObject) {
			try{
				this.xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
			}catch (e){
				try{
					this.xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
				}catch (e){
				}
			}
		}

								
		
		var self = this;
		this.xmlhttp.onreadystatechange = function(){
			
			self.callback("progress");
			switch(self.xmlhttp.readyState){
				case 0:
				break;					
				case 1:
				break;
				case 2:
					self.callback("send");
				break;
				case 3:
					if(self.xmlhttp.status == 200){
						self.callback("load");
						if(settimeout != undefined){
							clearTimeout(settimeout);
							settimeout = undefined;
						}						
					}else{
						self.callback("error");
					}
				break;					
				case 4:
					if(self.xmlhttp.status == 200){
						var d = new Date();
						spend = d.getTime() - spend;	

						if(settimeout != undefined){
							clearTimeout(settimeout);
							settimeout = undefined;
						}
						

						if(self.type == "XML"){
							data = self.xmlhttp.responseXML;
						}else{
							data = self.xmlhttp.responseText;
						}	
						
						if(fetch != undefined && typeof(fetch) == "function"){
							var prepare = fetch(data);
							if(prepare != undefined){
								data = prepare;
							};
						}	
						
						self.callback("data");
						self.construct();	
						self.repeat();
					}else if(self.xmlhttp.status == 301){
						self.callback("moved");
						self.construct();						
					}else if(self.xmlhttp.status == 404){
						self.callback("notfound");
						self.construct();
					}else{
						self.callback("loading");
						self.construct();
						self.repeat();
					}
				break;
				default:
					self.callback("error");
					self.construct();
				break;					
			}					
		}
		
		return null;
	};
	//----------------------------------------------------------------------------------	
	this.send = function (){
		if(this.url != undefined && this.url != "" && ready == true){
			count++;
			data = "";			
			spend = 0;
			ready = false;
			pause = false;
			
			get = get.substr(0,1) == "&" ? get.substr(1) : get;
			post = post.substr(0,1) == "&" ? post.substr(1) : post;			
		
			if(get != ""){
				arg = (this.url.indexOf("?") == -1 ? "?"+get : "&"+get);
			}
			if(this.method == undefined){
				this.method = post.length != "" ? "POST" : "GET";
			}
			var d = new Date(); 
			spend = d.getTime();

			if(this.timeout>0){
				self = this;
				settimeout = setTimeout(function(){self.timeabort();}, self.timeout);			
			}
			
			this.launch = new Date();
			this.callback("start");
			this.xmlhttp.open(this.method, this.url+arg, this.async);
			
			

			for(var i=0; i<header.length; i++){
				this.xmlhttp.setRequestHeader(header[i][0], header[i][1]);
			}
			if(this.modified == true){
				this.xmlhttp.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
			}
			if(this.mime != "" && this.xmlhttp.overrideMimeType != undefined){
				this.xmlhttp.overrideMimeType(this.mime);
			}			
			if(this.method == "GET"){
				return this.xmlhttp.send(null); 
			}else{
				this.xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				return this.xmlhttp.send(post);
			}
		}else{
			return null;
		}
	};
	//----------------------------------------------------------------------------------	
	this.repeat = function (){
		if(pause == false){
			var self = this;
			if(this.loop == -1){
				settimeloop = setTimeout(function(){self.send();}, self.delay);
			}else if(self.loop > 1 && self.loop > count){
				settimeloop = setTimeout(function(){self.send();}, self.delay);
			}	
			return true;
		}else{
			return false;			
		}
	}		
	//----------------------------------------------------------------------------------		
	this.data = function(){
		return data;
	}
	//----------------------------------------------------------------------------------	
	this.abort = function (){
		if(ready == false){
			this.xmlhttp.abort();
			this.callback("abort");
			this.construct();
			return true;
		}else{
			return false;
		}
	};
	//----------------------------------------------------------------------------------	
	this.timeabort = function (){
		if(ready == false){
			var d = new Date();
			d = d.getTime() - spend;

			if(this.timeout > 0 && this.timeout < d){
				this.xmlhttp.abort();
				this.callback("timeout");
				this.construct();
				return true;
			}else{
				return false;
			}
			
		}else{
			return false;
		}
	}
	//----------------------------------------------------------------------------------	
	this.kill = function (){
		pause = true;		
		if(settimeloop != undefined){
			clearTimeout(settimeloop);
		}			
		return true;
	}
	//----------------------------------------------------------------------------------	
	this.state = function (){
		return this.xmlhttp.readyState;
	};	
	//----------------------------------------------------------------------------------	
	this.status = function (){
		return this.xmlhttp.status;
	};
	//----------------------------------------------------------------------------------	
	this.statustext = function (){
		return this.xmlhttp.statusText;
	};	
	//----------------------------------------------------------------------------------	
	this.responseheader = function (header){
		return this.xmlhttp.getResponseHeader(header);
	};		
	//----------------------------------------------------------------------------------	
	this.responseheaders = function (){
		return this.xmlhttp.getAllResponseHeaders();
	};		
	//----------------------------------------------------------------------------------	
	this.loaded = function (){
		return this.xmlhttp.responseText.length;
	};		
	//----------------------------------------------------------------------------------	
	this.total = function (){
		if(this.xmlhttp.readyState == 4 && this.xmlhttp.status == 200){
			return this.loaded();
		}else{
			var result = this.xmlhttp.getResponseHeader("Content-Length");
			return result != undefined && result != null ? result : 0;			
		}
	};	

	//----------------------------------------------------------------------------------		
	this.get = function (value, name){
		return get = this.serialize(value, name);
	}
	//----------------------------------------------------------------------------------		
	this.post = function (value, name){
		return post = this.serialize(value, name);
	}	
	//----------------------------------------------------------------------------------		
	this.header = function (name, value){
		if(name != undefined && value != undefined && name != "" && value != "" && value[0] != undefined && value[1] != undefined){
			header.push([name, value]);
			return true;
		}else{
			return false;
		}
	}
	//----------------------------------------------------------------------------------	
	this.spend = function (){
		return spend;
	}
	//----------------------------------------------------------------------------------	
	this.count = function (){
		return count;
	}	
	//----------------------------------------------------------------------------------	
	this.fetch = function (value){
		if(value != undefined && typeof(value) == "function"){
			fetch = value;
			return true;
		}else{
			return false;			
		}
	}	
	//----------------------------------------------------------------------------------		
	this.serialize = function (value, name){
		this.variables = "";
		switch(typeof(value)){
			case "object":
				for(var i in value){
					var n = (name != undefined && name != "" ? name+"["+i+"]" : i);
					this.variables += this.serialize(value[i], n);
				}		
			break;
			case "string":
			case "number":
				if(name != undefined && name != ""){
					this.variables += "&"+name+"="+value;
				}

			break;		
			default:
			break;		
		}
		return this.variables;
	}		
	//----------------------------------------------------------------------------------		
	this.error = function (){
		
	}
	//----------------------------------------------------------------------------------	
	this.ready = function (){
		if(ready == true){
			return true;
		}else{
			return false;
		}
	}
	//----------------------------------------------------------------------------------	
	this.callback = function(e){
		if(e != undefined && handler[e] != undefined && typeof(e) == "string" && typeof(handler[e]) == "function") {
			var callback = handler[e];
			callback.call(this);
			return true;
		}else{
			return false;
		}
	}
	//----------------------------------------------------------------------------------	
	this.eventHandlerAdd = function(e, value){
		if(e != undefined && value != undefined && typeof(e) == "string" && typeof(value) == "function") {
			handler[e] = value;
			return true;
		}else{
			return false;
		}
	}
	//----------------------------------------------------------------------------------	
	this.eventHandlerRemove = function(e, value){
		if(e != undefined && value != undefined && typeof(e) == "string" && handler[e] != undefined) {
			delete handler[e];
			return true;
		}else{
			return false;
		}		
	}	
	//----------------------------------------------------------------------------------
	this.construct();
}
