/*****************
VERSIE - 0 - 20
*****************/ 

	var AJAX = {
		getRequestObject : function(){
			var _oXmlHttpRequest;
			if (window.XMLHttpRequest) { // Mozilla, Safari,...
				try 
				{
					_oXmlHttpRequest = new XMLHttpRequest();
					
				}
				catch (e) 
				{
					HTML.writeToElement("Permission UniversalBrowserRead denied.","debug", true);
				}
			} 
			else if (window.ActiveXObject) 
			{ // IE
				try 
				{
					_oXmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");
				}
				catch (e) 
				{
					try 
					{
						_oXmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");
					} 
					catch (e) {
						HTML.writeToElement("Error create ActiveXObject.","debug", true);
					}
				}
			}

			if (!_oXmlHttpRequest) 
			{
				HTML.writeToElement("Giving up :( Cannot create an XMLHTTP instance","debug", true);
				return false;
			}

			return _oXmlHttpRequest;
		
		}
	}

	AJAX.Request = function(){
		// INIT
		this.init(arguments[0], arguments[1]);
	}

	AJAX.Request.prototype = {
		init: function(strURL, oOptions){
			this.strURL = strURL;
			// SET DEFAULT PARAMS WITH OPTIONS
			this.oOptions = Object.extend({
												method: "post",
												asynchronous: true,
												parameters: "",
												responseEl: "",
												preloader: true,
												preloaderText: "loading ...",
												responseType: "html",
												responseAppend: false,
												responseAppendPosition: "bottom",
												customHandler: false
												}, oOptions
											);
			// ASSERT OPTIONS
			this.assertOptions();
			// GET XMLHTTP OBJECT
			this.oRequest = AJAX.getRequestObject();
			this.request(strURL);
		},
		
		customHandler: function(){
			HTML.writeToElement("add following code for custom handler:<br /><i>"+
				"AJAX.Request.prototype.customHandler = function([arguments]){<br />"+
				"[put your code here ....]<br />"+
				"}</i>"	
				, this.oOptions.responseEl, true);
		},
		
		request: function(strURL){
			/*prototype library code*/
			//get parameters
			var parameters = this.oOptions.parameters || '';
			if (parameters.length > 0) parameters += '&_=';

			this.strURL = strURL;
			if (this.oOptions.method == 'get' && parameters.length > 0){
		    this.strURL += (this.strURL.match(/\?/) ? '&' : '?') + parameters;
			}
			/*prototype library code*/
			
			if (navigator.userAgent.indexOf("MSIE") == -1) {/*fix ff; to make XMLHTTPRequest from local system*/
				var strLocation = new String(window.location);
				if(strLocation.indexOf("http://") == -1){
					/**********************************
					Privilege represents permissions to access a specific target. The following table lists JavaScript built in privilege and the targets associated with them.
					Reading of sensitive browser data.
					This allows the script to pass the same origin check when reading from any document.
					**********************************/
					netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
				}
			}
			
			//startup request	
			this.oRequest.open(this.oOptions.method, this.strURL, this.oOptions.asynchronous, this.oOptions.username != "" ? this.oOptions.username : "", this.oOptions.password != "" ? this.oOptions.password : "");
			//set headers
			this.setRequestHeaders();
			//set handler
			this.oRequest.onreadystatechange = this.onStateChange.bind(this);
			//add post/get data
			var body = this.oOptions.postBody ? this.oOptions.postBody : parameters;
			//start request
			
			this.oRequest.send(this.oOptions.method == 'post' ? body : null);

		},

		onStateChange: function(){
			if(this.oRequest.readyState == 4){
				
				if(this.oOptions.customHandler == true){
					if (this.oOptions.responseType == "text" || this.oOptions.responseType == "html") {
						this.customHandler(this.oRequest.responseText);
					}
					else if(this.oOptions.responseType == "xml"){
						this.customHandler(this.oRequest.responseXML);
					}
					else if(this.oOptions.responseType == "none"){
						// helemaal nix ;)
					}
				}
				else if(this.oOptions.customHandler == false){
					this.responseHandler();
				}
			}
			else if ((this.oRequest.readyState != 4) && (this.oOptions.preloader==true)){
				this.loadingHandler();
			}
		},

		responseHandler: function(){
			if(this.oOptions.responseType == "html"){
				HTML.writeToElement(this.oRequest.responseText, this.oOptions.responseEl, this.oOptions.responseAppend, this.oOptions.responseAppendPosition);
			}
			else if (this.oOptions.responseType == "text"){
				HTML.writeTextToElement(this.oRequest.responseText, this.oOptions.responseEl);
			}
			else if(this.oOptions.responseType == "xml"){
				HTML.writeToElement(this.oRequest.responseXML, this.oOptions.responseAppend);
			}
			else if(this.oOptions.responseType == "none"){
				// nix ;)
			}
		},

		loadingHandler: function(){
			if(this.oOptions.responseType == "html"){
				HTML.writeToElement(this.oOptions.preloaderText, this.oOptions.responseEl, this.oOptions.responseAppend, this.oOptions.responseAppendPosition);
			}
			else if (this.oOptions.responseType == "text"){
				HTML.writeTextToElement(this.oOptions.preloaderText, this.oOptions.responseEl);
			}
		},

		assertOptions: function(){
			if(this.oOptions.method != "post" && this.oOptions.method != "get"){
				this.oOptions.method = "post";
				// HTML.writeToElement("ASSERT method", "debug", true);
			}

			if(this.oOptions.asynchronous != true && this.oOptions.asynchronous != false){
				this.oOptions.asynchronous = true;
				// HTML.writeToElement("ASSERT asynchronous", "debug", true);
			}
			if(this.oOptions.preloader != true && this.oOptions.preloader != false){
				this.oOptions.preloader = true;
				// HTML.writeToElement("ASSERT preloader", "debug", true);
			}
			if(this.oOptions.responseType != "none" && this.oOptions.responseType != "html" && this.oOptions.responseType != "text" && this.oOptions.responseType != "xml"){
				this.oOptions.responseType = "none"
				// HTML.writeToElement("ASSERT responseType", "debug", true);
			}
			if(this.oOptions.username != undefined){
				if(this.oOptions.username.length >= 45){
					this.oOptions.username = "";
					//HTML.writeToElement("ASSERT username", "debug", true);
				}
			}
			if(this.oOptions.password != undefined){
				if(this.oOptions.password.length >= 45){
					this.oOptions.password = "";
					//HTML.writeToElement("ASSERT password", "debug", true);
				}
			}
			
			if(this.oOptions.responseAppend == undefined){
				this.oOptions.responseAppend = false;
			}

			if(this.oOptions.responseAppendPosition != "bottom" && this.oOptions.responseAppendPosition != "top"){
				this.oOptions.responseAppendPosition = "bottom";
			}
			
			/*if(this.oOptions.responseEl != ""){
				this.oOptions.responseEl
			}*/
			/*
			if(this.oOptions.customHandler){
				this.oOptions.customHandler
			}*/
		},

		/*prototype library functions*/
		setRequestHeaders: function() {
			var requestHeaders = ['X-Requested-With', 'XMLHttpRequest'];

			if (this.oOptions.method == 'post') {
				requestHeaders.push('Content-type', 'application/x-www-form-urlencoded');

				/* Force "Connection: close" for Mozilla browsers to work around
				 * a bug where XMLHttpReqeuest sends an incorrect Content-length
				 * header. See Mozilla Bugzilla #246651. 
				 */
				if (this.oRequest.overrideMimeType){
					requestHeaders.push('Connection', 'close');
				}
			}

			if (this.oOptions.requestHeaders){
				requestHeaders.push.apply(requestHeaders, this.oOptions.requestHeaders);
			}

			for (var i = 0; i < requestHeaders.length; i += 2){
				this.oRequest.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
			}
		}
		/*prototype library functions*/
	}
	
	
	/*prototype library functions*/
	Function.prototype.bind = function() {
		var __method = this, args = arguments, object = args[0];
		return function() {
			return __method.apply(object, arguments); 
		}
	}

	Object.extend = function(destination, source) {
		for (property in source) {
			destination[property] = source[property];
		}
		return destination;
	}
	/*prototype library functions*/






		