function Ajax (ttl) {

	var event_func;

	var xmlhttp;
	var use_xml					= false;
	//var use_ajax_loader_div		= false;
	//ajax_loader_div	= null;
	if (!Ajax.instances)
		Ajax.instances = 0;
		

	var instance = Ajax.instances++;
	
	var REQUEST_GET		= 0;
	var REQUEST_HEAD	= 1;
	var REQUEST_POST	= 2;
	var REQUEST_XML		= 3;
	
	var timeout			= null;
	var time_to_live	= (ttl) ? ttl:5;
	
	var helper			= new Helper;
	var self			= this;
	
	/*with (document) {
		write('<div id="ajax_ajax_loader_div" style="position:absolute; top: 0px; left: 0px; color: black; background-color: gray; opacity: 0.5; -moz-opacity: 0.5; filter:alpha(opacity=50); display:none; z-index: 1111; text-align: center; vertical-align: middle;"><br><br>Loading data...</div>');
	}*/
	/*ajax_loader_div							= document.createElement("div");
	ajax_loader_div.style.position			= "absolute";
	ajax_loader_div.style.top				= "0px";
	ajax_loader_div.style.left				= "0px";
	ajax_loader_div.style.color				= "#000";
	ajax_loader_div.style.backgroundColor	= "gray";
	ajax_loader_div.style.zIndex			= "1111";
	ajax_loader_div.style.textAlign			= "center";
	ajax_loader_div.style.verticalAlign		= "middle";
	ajax_loader_div.style.display			= "none";
	ajax_loader_div.innerHTML				= "<br><br>Loading data...";
	ajax_loader_div.setAttribute("id", "ajax_ajax_loader_div"+instance, false);*/
	//helper.setOpacity(ajax_loader_div, 0.5);
	//helper.waitForBody(function(){document.body.appendChild(ajax_loader_div);});	
	
	
	this.request_get = function (src_file, params, request_func, func_param, use_loader, xml) {
		use_xml = xml;		
		use_ajax_loader_div	= false;
		event_func = request_func;
		this.request(src_file, params, REQUEST_GET, func_param);
	}
		
	this.request_post = function (src_file, params, request_func, func_param, use_loader, xml) {
		use_xml = xml;		
		use_ajax_loader_div	= false;
		event_func = request_func;
		this.request(src_file, params, REQUEST_POST, func_param);
	}
	
	this.request_head = function (src_file, params, request_func, func_param, use_loader, xml) {
		use_xml = xml;		
		use_ajax_loader_div	= false;
		event_func = request_func;
		this.request(src_file, params, REQUEST_HEAD, func_param);
	}
	
	this.request_xml = function (src_file, params, request_func, func_param, use_loader) {
		use_xml = true;		
		use_ajax_loader_div	= false;
		event_func = request_func;
		this.request(src_file, params, REQUEST_XML, func_param);
	}
	
	
	function getRequester () {
		try {
			if (window.ActiveXObject) {
				for (var i=5; i; i--) {
					try {
						if (i == 2) {
							xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
						} else {
							xmlhttp = new ActiveXObject("Msxml2.XMLHTTP." + i + ".0");
						}
						break;
					} catch (excNotLoadable) {
						xmlhttp = false;
					}
				}
			} else if (window.XMLHttpRequest) {
				xmlhttp = new XMLHttpRequest();
			}
		} catch (excNotLoadable) {
			xmlhttp = false;
		}
	}
	
	
	this.request = function (src_file, params, request_type, func_param) {
		if (!params)
			params = '';

		if (isNaN(request_type))
			request_type = REQUEST_GET;

		if (xmlhttp) {
			free(); //window.setTimeout(function(){self.request(src_file, params, request_type, func_param);}, Math.round(Math.random()*100));
		}

		if (!xmlhttp) {
				getRequester();
		}
				
		/*ajax_loader_div.style.display = "none";
		if (use_ajax_loader_div) {
			window_dim = helper.getInnerDimension();
			helper.resizeTo(ajax_loader_div, window_dim[0], window_dim[1]);
			ajax_loader_div.style.display = "block";
		}*/
		if (timeout)
			clearTimeout(timeout);
		timeout = window.setTimeout(function(){self.handle_timeout(func_param);}, time_to_live*1000); 
		

		if (request_type != REQUEST_HEAD && (params && params.substr (0, 1) == '&' || params.substr(0, 1) == '?'))
			params = params.substring (1, params.length);


		var dataReturn = params ? params : src_file;

		switch (request_type) {
			case REQUEST_XML:
				params = "xml=" + params;
				
			case REQUEST_POST:
				xmlhttp.open("POST", src_file, true);
				xmlhttp.setRequestHeader("Pragma", "no-cache");
				xmlhttp.setRequestHeader("Cache-Control", "must-revalidate");
				xmlhttp.setRequestHeader("If-Modified-Since", document.lastModified);
				xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
				xmlhttp.setRequestHeader("Content-length", params.length);
				break;

			case REQUEST_HEAD:
				xmlhttp.open("HEAD", src_file, true);
				params = null;
				break;
			
			default:
				var p_file = src_file + (params ? '?' + params : '');
				xmlhttp.open("GET", p_file, true);
				params = null;
		}

		xmlhttp.onreadystatechange = function(){self.process_response(func_param);}

		xmlhttp.send(params);

		return dataReturn;
	}

	
	this.process_response = function (func_param) {
		switch (xmlhttp.readyState) {
			
			case 0:	// uninitialized
			
			case 1: // loading
			
			case 2: // loaded
			
			case 3: // interactive
				break;

			case 4: // complete
				/*if (ajax_loader_div && ajax_loader_div.style && ajax_loader_div.style.display)
					ajax_loader_div.style.display = "none";*/
				try {
					if (xmlhttp.status == 200) {
						clearTimeout(timeout);
						parse_data(func_param);
					} else {
						clearTimeout(timeout);
						//alert("AJAX error!\n HTTP status = " + xmlhttp.status + "\n" + xmlhttp.statusText);
						free();
						event_func(false, func_param);
					}
				} catch (e) {
				}
		}
	}

	
	this.handle_timeout = function (func_param) {
		//alert("AJAX error!\n Timeout");
		/*if (ajax_loader_div)
			ajax_loader_div.style.display = "none";	*/
		event_func(false, func_param);
		free();
	}
	
	
	function free () {
		if (xmlhttp) {
			try {
				xmlhttp.abort();
			} catch (e) {
			}
			xmlhttp = false;
		}	
	}
	
	function parse_data(func_param) {
		if (use_xml) {
			event_func(xmlhttp.responseXML, func_param);
			free();
		} else {
			event_func(xmlhttp.responseText, func_param);
			free();
		}
	}

}
