////////////////////////////////////////////
// PostBack and AjaxPostBack
////////////////////////////////////////////

/*
 * Linas Ablonskis: 2007-09-11, Added check to qcodo.dequeuAjaxQueue that prevent
 * sending request if source control is no more (destroyed by previous response).
 *
 * Linas Ablonskis: 2007-12-20, Added support for control start scripts in AJAX response
 * handler.
 *
 * Linas Ablonskis: 2008-07-04, Added graceful error recovery attempt mechanism.
 */

	//error window object
	qcodo.objErrorWindow = null;

	qcodo.postBack = function(strForm, strControl, strEvent, strParameter) {
		var objForm = document.getElementById(strForm);
		objForm.Qform__FormControl.value = strControl;
		objForm.Qform__FormEvent.value = strEvent;
		objForm.Qform__FormParameter.value = strParameter;
		objForm.Qform__FormCallType.value = "Server";
		objForm.Qform__FormUpdates.value = this.formUpdates();
		objForm.Qform__FormCheckableControls.value = this.formCheckableControls(strForm, "Server");
		objForm.submit();
	};

	qcodo.formUpdates = function() {
		var strToReturn = "";
		for (var intIndex = 0; intIndex < qcodo.controlModifications.length; intIndex++) {
			strToReturn += qcodo.controlModifications[intIndex] + "\n";
		};

		qcodo.controlModifications = new Array();
		return strToReturn;
	};

	qcodo.formCheckableControls = function(strForm, strCallType) {
		var objForm = document.getElementById(strForm);
		var strToReturn = "";

		for (var intIndex = 0; intIndex < objForm.elements.length; intIndex++) {
			if (((objForm.elements[intIndex].type == "checkbox") ||
				 (objForm.elements[intIndex].type == "radio")) &&
				((strCallType == "Ajax") ||
				(!objForm.elements[intIndex].disabled))) {

				// CheckBoxList
				if (objForm.elements[intIndex].id.indexOf('[') >= 0) {
					if (objForm.elements[intIndex].id.indexOf('[0]') >= 0)
						strToReturn += " " + objForm.elements[intIndex].id.substring(0, objForm.elements[intIndex].id.length - 3);

				// RadioButtonList
				} else if (objForm.elements[intIndex].id.indexOf('_') >= 0) {
					if (objForm.elements[intIndex].id.indexOf('_0') >= 0)
						strToReturn += " " + objForm.elements[intIndex].id.substring(0, objForm.elements[intIndex].id.length - 2);

				// Standard Radio or Checkbox
				} else {
					strToReturn += " " + objForm.elements[intIndex].id;
				};
			};
		};

		if (strToReturn.length > 0)
			return strToReturn.substring(1);
		else
			return "";
	};

	qcodo.ajaxQueue = new Array();

	qcodo.postAjax = function(strForm, strControl, strEvent, strParameter, strWaitIconControlId) {
		 //alert(strForm + " " + strControl + " " + strEvent + " " + strParameter);

		// Figure out if Queue is Empty
		var blnQueueEmpty = false;
		if (qcodo.ajaxQueue.length == 0)
			blnQueueEmpty = true;

		// Enqueue the AJAX Request
		qcodo.ajaxQueue.push(new Array(strForm, strControl, strEvent, strParameter, strWaitIconControlId));

		// If the Queue was originally empty, call the Dequeue
		if (blnQueueEmpty)
			qcodo.dequeueAjaxQueue();
	};

	qcodo.clearAjaxQueue = function() {
		qcodo.ajaxQueue = new Array();
	};

	/**
	 * Starts error recovery attempt.
	 */
	qcodo.startAjaxRecovery = function()
	{
		//hide wait icon
		if (qcodo.objAjaxWaitIcon)
			qcodo.objAjaxWaitIcon.style.display = 'none';

		//forget all pending AJAX requests
		qcodo.clearAjaxQueue();

		//open recovery panel to begin recovery process
		mtpsip.er.beginRecovery();
	}

	qcodo.objAjaxWaitIcon = null;

	qcodo.dequeueAjaxQueue = function() {
		if (qcodo.ajaxQueue.length > 0) {
			strForm = this.ajaxQueue[0][0];
			strControl = this.ajaxQueue[0][1];
			strEvent = this.ajaxQueue[0][2];
			strParameter = this.ajaxQueue[0][3];
			strWaitIconControlId = this.ajaxQueue[0][4];

			//check if previous AJAX response has not destroyed source control
			if( strControl != '' && document.getElementById(strControl) == null
				&& document.getElementById(strControl+"_ctl") == null )
			{
				//control is no more, forget this AJAX request
				qcodo.ajaxQueue.reverse();
				qcodo.ajaxQueue.pop();
				qcodo.ajaxQueue.reverse();

				//process next AJAX request, if any
				if (qcodo.ajaxQueue.length > 0)
					qcodo.dequeueAjaxQueue();

				//discontinue processing of forgotten request
				return;
			}

			//display WaitIcon (if applicable)
			if (strWaitIconControlId) {
				this.objAjaxWaitIcon = this.getWrapper(strWaitIconControlId);
				if (this.objAjaxWaitIcon)
					this.objAjaxWaitIcon.style.display = 'inline';
			};

			//collect postback data
			var objForm = document.getElementById(strForm);
			objForm.Qform__FormControl.value = strControl;
			objForm.Qform__FormEvent.value = strEvent;
			objForm.Qform__FormParameter.value = strParameter;
			objForm.Qform__FormCallType.value = "Ajax";
			objForm.Qform__FormUpdates.value = qcodo.formUpdates();
			objForm.Qform__FormCheckableControls.value = this.formCheckableControls(strForm, "Ajax");

			var strPostData = "";
			for (var i = 0; i < objForm.elements.length; i++) {
				switch (objForm.elements[i].type) {
					case "checkbox":
					case "radio":
						if (objForm.elements[i].checked) {
							var strTestName = objForm.elements[i].name + "_";
							if (objForm.elements[i].id.substring(0, strTestName.length) == strTestName)
								strPostData += "&" + objForm.elements[i].name + "=" + objForm.elements[i].id.substring(strTestName.length);
							else
								strPostData += "&" + objForm.elements[i].id + "=" + "1";
						};
						break;

					case "select-multiple":
						var blnOneSelected = false;
						for (var intIndex = 0; intIndex < objForm.elements[i].options.length; intIndex++)
							if (objForm.elements[i].options[intIndex].selected) {
								strPostData += "&" + objForm.elements[i].name + "=";
								strPostData += objForm.elements[i].options[intIndex].value;
							};
						break;

					default:
						strPostData += "&" + objForm.elements[i].id + "=";

						// For Internationalization -- we must escape the element's value properly
						var strPostValue = objForm.elements[i].value;
						if (strPostValue) {
							strPostValue = strPostValue.replace(/&/g, escape('&'));
							strPostValue = strPostValue.replace(/\+/g, "%2B");
						};
						strPostData += strPostValue;
						break;
				};
			};

			var strUri = objForm.action;

			//get XMLHttpRequest object
			var objRequest;
			if (window.XMLHttpRequest) {
				objRequest = new XMLHttpRequest();
			} else if (typeof ActiveXObject != "undefined") {
				objRequest = new ActiveXObject("Microsoft.XMLHTTP");
			};

			//prepare XMLHttpRequest for postback
			if (objRequest) {
				objRequest.open("POST", strUri, true);
				objRequest.setRequestHeader("Method", "POST " + strUri + " HTTP/1.1");
				objRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");

				/**
				 * Handles request ready state change.
				 */
				objRequest.onreadystatechange = function() {
					if (objRequest.readyState == 4) {
						var pendingCmd = "none";

						try {
							var objXmlDoc = objRequest.responseXML;

							if ((!objXmlDoc) || (!objXmlDoc.documentElement)) {
								//close previous error window if any
								if( qcodo.objErrorWindow != null )
								{
									try	{
										qcodo.objErrorWindow.close();
									}catch(hiddenException){}
									qcodo.objErrorWindow = null;
								}

								//alert about error, display error window
								alert("An error occurred during AJAX Response parsing. Response was not interpreted as XML. \r\n\r\nThe response text will appear in a new popup.");
								qcodo.objErrorWindow = window.open('about:blank', 'qcodo_error','menubar=no,toolbar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=1000,height=700,left=50,top=50');

								qcodo.objErrorWindow.focus();
								qcodo.objErrorWindow.document.write(objRequest.responseText);

								//try recovering
								qcodo.startAjaxRecovery();

								//
								return;
							} else {
								var intLength = 0;

								//execute start scripts
								var objXmlStartCommands = objXmlDoc.getElementsByTagName('startCommand');
								intLength = objXmlStartCommands.length;

								for (var intIndex = 0; intIndex < intLength; intIndex++) {
									if (objXmlStartCommands[intIndex] && objXmlStartCommands[intIndex].firstChild) {
										var strCommand = objXmlStartCommands[intIndex].firstChild.nodeValue;
										if(qcodo.isBrowser(qcodo.FIREFOX))
											strCommand = objXmlStartCommands[intIndex].textContent;

										pendingCmd = strCommand;
										eval(strCommand);
									};
								};
								pendingCmd = "none";

								// Go through Controls
								var objXmlControls = objXmlDoc.getElementsByTagName('control');
								intLength = objXmlControls.length;

								for (var intIndex = 0; intIndex < intLength; intIndex++) {
									var strControlId = objXmlControls[intIndex].attributes.getNamedItem('id').nodeValue;

									var strControlHtml = "";
									if(objXmlControls[intIndex].firstChild)
										strControlHtml = objXmlControls[intIndex].firstChild.nodeValue;

									//NOTE: this is done (in 2 more places) because sometimes FF splits text node into several adjacent smaller nodes
									//which is correct behavior according to W3C spec. What about other browsers ?
									if(qcodo.isBrowser(qcodo.FIREFOX))
										strControlHtml = objXmlControls[intIndex].textContent;

									// Perform Callback Responsibility
									if (strControlId == "Qform__FormState") {
										var objFormState = document.getElementById(strControlId);
										objFormState.value = strControlHtml;
									} else
									{
										var objSpan = document.getElementById(strControlId + "_ctl");
										if (objSpan)
										{
											var objSpanType = $(objSpan).attr('type');
											switch (objSpanType)
										   	{
												case 'tr':
													$(objSpan).html(strControlHtml);
													break;

												default:
      	                            				objSpan.innerHTML = strControlHtml;
      		                         				break;
                                 			}
										} //if(objSpan)
									};//else
								};//for

								// Go through Commands
								var objXmlCommands = objXmlDoc.getElementsByTagName('command');
								intLength = objXmlCommands.length;

								for (var intIndex = 0; intIndex < intLength; intIndex++) {
									if (objXmlCommands[intIndex] && objXmlCommands[intIndex].firstChild) {
										var strCommand = objXmlCommands[intIndex].firstChild.nodeValue;
										if(qcodo.isBrowser(qcodo.FIREFOX))
											strCommand = objXmlCommands[intIndex].textContent;

										pendingCmd = strCommand;
										eval(strCommand);
									};
								};
								pendingCmd = "none";
							};
						} catch (objExc)
						{
							//close previous error window if any
							if( qcodo.objErrorWindow != null )
							{
								try	{
									qcodo.objErrorWindow.close();
								}catch(hiddenException){}
								qcodo.objErrorWindow = null;
							}

							//display warning about error
							alert(objExc.message + "\r\non line number " + objExc.lineNumber + "\r\nin file " + objExc.fileName);
							alert(
								"An error occurred during AJAX Response handling.\r\n\r\n"+
								"The error response will appear in a new popup.\r\n\r\n"+
								"Pending command is:\r\n"+pendingCmd);
							qcodo.objErrorWindow = window.open('about:blank', 'qcodo_error','menubar=no,toolbar=no,location=no,status=no,scrollbars=yes,resizable=yes,width=1000,height=700,left=50,top=50');
							qcodo.objErrorWindow.focus();
							qcodo.objErrorWindow.document.write(objRequest.responseText);

							//try recovering
							qcodo.startAjaxRecovery();

							//
							return;
						};

						// Perform the Dequeue
						qcodo.ajaxQueue.reverse();
						qcodo.ajaxQueue.pop();
						qcodo.ajaxQueue.reverse();

						//hide the WaitIcon (if applicable)
						if (qcodo.objAjaxWaitIcon)
							qcodo.objAjaxWaitIcon.style.display = 'none';

						// If there are still AjaxEvents in the queue, go ahead and process/dequeue them
						if (qcodo.ajaxQueue.length > 0)
							qcodo.dequeueAjaxQueue();
					};
				};

				objRequest.send(strPostData);
			};
		};
	};



//////////////////
// Qcodo Shortcuts
//////////////////

	qc.pB = qcodo.postBack;
	qc.pA = qcodo.postAjax;

