// ----------------------------------------------
// PRAjax - JavaScript code
// (C) Maarten Balliauw
// http://prajax.sf.net
// Version: PRAjax Transport v$PRAJAXVER$
// ----------------------------------------------

// Class base
function PRAjaxTransport () {}

// ----------------------------------------------
// Properties
// ----------------------------------------------

// Inner transport object (XMLHttpRequest or IFrame reference)
PRAjaxTransport.prototype.objTransport = null;

// Inner callback function
PRAjaxTransport.prototype.fnCallback = function (data) {};

// Inner error function
PRAjaxTransport.prototype.fnError = function () {};

// ----------------------------------------------
// Methods
// ----------------------------------------------
PRAjaxTransport.prototype.Create = function (callbackFunction, errorFunction, forceIframe) {
	// Create a self-reference
	var _this = this;
	
	// Add callback and error functions
	if (typeof(callbackFunction) == 'function') {
		_this.fnCallback = callbackFunction;
	}
	if (typeof(errorFunction) == 'function') {
		_this.fnError = errorFunction;
	}
	
	// Try creating an inner transport object as XMLHttpRequest
	if (forceIframe == false) {
		try {
			// Use native object
			_this.objTransport = new XMLHttpRequest();
		} catch (ex1) {
			try {
				// Newest Microsoft ActiveX object
				_this.objTransport = new ActiveXObject("Msxml2.XMLHTTP");
			} catch (ex2) {
				try {
					// Older Microsoft ActiveX object
					_this.objTransport = new ActiveXObject("Microsoft.XMLHTTP");
				} catch (ex3) {
					// Never mind...
					_this.objTransport = null;
				}
			}
		}
	}
	
	// Eventually, try creating an inner transport object as IFrame
	if (forceIframe == true || _this.objTransport == null) {
		try {
			// Create IFrame fallback
			_this.objTransport = document.createElement('iframe');
			_this.objTransport.setAttribute('id', 'prajax_iframe_fallback_' + Math.floor(Math.random()*9999));
			_this.objTransport.setAttribute('name', _this.objTransport.getAttribute('name'));
			_this.objTransport.setAttribute('src', 'javascript:void(0)');							
			_this.objTransport.style.display = 'none';
			_this.objTransport.style.position = 'absolute';
			document.getElementsByTagName('body')[0].appendChild(_this.objTransport);
		} catch (ex4) {			
			alert('[PRAjaxTransport error] Your browser does not support XMLHttpRequest object, IFrame object or similar alternatives');
		}
	}
	
	// Add ready state handler
	if (!_this.objTransport.src) {
		_this.objTransport.onreadystatechange = function () {
			if (_this.objTransport.readystate == 4 || _this.objTransport.readyState == 4) { // TODO: Check final version of IE7
				try {
					if (_this.objTransport.status == 200) {
						_this.fnCallback(_this.objTransport.responseText);
					} else {
						alert("[PRAjaxTransport error] XMLHttpRequest did not return status code 200, but returned " + _this.objTransport.status + " instead:\n" + _this.objTransport.statusText);
						_this.fnError();
					}
				} catch (exFFBug) { }
				_this.objTransport.onreadystatechange = function() {};
						
				delete _this.objTransport;
			}
		};
	} else {
		PRAjaxUtil.addEvent(_this.objTransport, 'load', function () {
						if (_this.objTransport != null) {
							var data = _this.objTransport.contentWindow.document.getElementsByTagName('body')[0].innerHTML;
									
							if (data) {
								callbackFunction(data);
	
								try {
									document.getElementsByTagName('body')[0].removeChild(_this.objTransport);
								} catch (ex) {}
								_this.objTransport = null;
							}
						}
				}, false);
	}	
}

// Perform a request
PRAjaxTransport.prototype.PerformRequest = function (uri, post_data, callbackFunction, errorFunction, openCallCount) {
	// Create a self-reference
	var _this = this;
	
	// If there are > 2 open Ajax calls, force the use of an IFrame. Several browsers do not support more than 2 simultaneous XMLHttpRequests.
	var forceIFrame = false;
	if (openCallCount > 2) {
		forceIFrame = true;
	}
	
	// Get a transport
	_this.Create(callbackFunction, errorFunction, forceIFrame);
	
	// Create the request
	if (!_this.objTransport.src) {
		_this.objTransport.open("POST", uri, true);
		_this.objTransport.setRequestHeader("Method", "POST " + uri + " HTTP/1.1");
		_this.objTransport.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		_this.objTransport.send(post_data);
	} else {
		// Create IFrame request
		var codeForm = '';
		codeForm += '<body onload="document.prajax_form.submit();">';
		codeForm += '<form name="prajax_form" action="' + uri + '" method="POST">';
				
		// Add form elements
		var aElements = post_data.split('&');
		var i = 0;
		var count = aElements.length;
		for (i = 0; i < count; i++) {
			codeForm += '<input type="hidden" name="' + aElements[i].substr(0, aElements[i].indexOf('=')) + '" value="' + aElements[i].substr(aElements[i].indexOf('=') + 1) + '">';
		}
				
		// Close form
		codeForm += '</form>';
		codeForm += '</body>';
				
		// Add form to document
		var i = _this.objTransport.getAttribute('id');
		_this.objTransport.contentWindow.document.open();
		_this.objTransport.contentWindow.document.write(codeForm);
		_this.objTransport.contentWindow.document.close();
	}
}
