/*
Each instance of ckAjaxObj will have a corresponding ckAjaxUIObj so that multiple asynchronous actions can
occur on the page and each occurence can show their own UI progress/icon/whatever

Prerequisites:
	fillOptions() :: advancedForms.js :: processing eDoc type of "optionsCollection"
*/
function ckAjaxUIObj() {
	this.debugSendWindowContainer = null;
	this.debugReceiveWindowContainer = null;
	this.progressWindowContainer = null;
	this.progressWindowFrame = null;
	this.progressIconImage = null;
	return this;
	
}
ckAjaxUIObj.prototype.showProgressWindow = function(sMessage) {
	if (!this.progressWindowContainer) this._createProgressWindow();
	if (this.progressWindowContainer) {

		var width = document.body.clientWidth;
		var height = document.body.clientHeight;

		var centerX = (width / 2); //FOR SOME REASON, calling document.body.clientWidth causes the screen to flash
		var leftX = (centerX - 200) //dynamically determining progressWindowContainer width did not work...so hardcode
		this.progressWindowContainer.style.left = leftX;
		this.progressWindowContainer.style.top = ((height / 2) + (document.body.scrollTop-50));
		this.progressWindowContainer.innerHTML = sMessage;
		this.progressWindowContainer.style.display="block";
		this.progressWindowContainer.style.fontWeight="bold";
		this.progressWindowContainer.style.zIndex = 100;
		
		this.progressWindowFrame.style.left=leftX - 1;
		this.progressWindowFrame.style.top =this.progressWindowContainer.style.top;
		this.progressWindowFrame.style.width =this.progressWindowContainer.clientWidth;
		this.progressWindowFrame.style.display = "block";
		this.progressWindowFrame.style.zIndex = 0;
		
		
	} else throwConsoleErroror("ckAjaxUIObj.showProgressWindow","Progress window could not be created");
}
ckAjaxUIObj.prototype.hideProgressWindow = function() {
	if (this.progressWindowContainer) this.progressWindowContainer.style.display="none";
	if (this.progressWindowFrame) this.progressWindowFrame.style.display="none";
}
ckAjaxUIObj.prototype.showProgressIcon = function(oField) {
	var arguments = ckAjaxUIObj.prototype.showProgressIcon.arguments;
	
}
ckAjaxUIObj.prototype.hideProgressIcon = function(oField) {
	var arguments = ckAjaxUIObj.prototype.hideProgressIcon.arguments;
	
}
ckAjaxUIObj.prototype.setDebugSend = function(ajaxUniqueID,sURL,sText,aHeaders) {
	
	try {
		if (oApplication) {
			//if this script is being used with the global application object, check it's setting to determine if we should activate
			//  the debug windows.  This was designed this way because there are numerous instances of the Ajax object that can
			//  be used in localized functions.  It would be impossible to dynamically activate the windows from the browser address
			//  bar for debugging on production machines unless we have a global app variable
			if ((!this.debugSendWindowContainer) && (oApplication.bAjaxDebug)) this.showDebugWindows();
		}
		//TEMPORARY TO ALWAYS SHOW DEBUG
		if (!this.debugSendWindowContainer) this.showDebugWindows();
	} catch(oError) { 
		//fail silently if no oApplication 
	}
	
	try {	
		//With multiple ajax objects on page, any one of them could have created debug windows, so need to check for page element each time
	
		if (this.debugSendWindowContainer = (this.debugSendWindowContainer || document.getElementById("ajax.debugSendWindowContainer"))) {
			var sTemp = '<b style="color:#0000FF">SEND (' + ajaxUniqueID + '):</b><br/><b>URL:' + sURL + '</b><br/>'
			if (aHeaders) {
				for (var key in aHeaders) sTemp += '<b>[Header] ' + key + ":</b>" + aHeaders[key] + "<br/>";
			}

			sText = sText.replace(/\n/g,"<br/>");
			sText = sText.replace(/\</g,"&lt;");
			sText = sText.replace(/\>/g,"&gt;");
			sText = sText.replace(/\&/g,"<br/>&");
			
			sText = "<hr>" + sTemp + "<br/>" + sText + "<hr>";
			this.debugSendWindowContainer.innerHTML += sText;
		}
	} catch (oError) {
		throwConsoleErroror("ckAjaxUIObj.setDebugSend",oError)
	}
}
ckAjaxUIObj.prototype.setDebugReceive = function(ajaxUniqueID,sText) {
	try {
		if (oApplication) {
			if ((!this.debugReceiveWindowContainer) && (oApplication.bAjaxDebug)) this.showDebugWindows();
		}
	} catch(oError) { 
		//fail silently if no oApplication
	}
	
	try {
		if (this.debugReceiveWindowContainer = (this.debugReceiveWindowContainer || document.getElementById("ajax.debugReceiveWindowContainer"))) {
			sText = sText.replace(/</g,"&lt;").replace(/>/g,"&gt;");
			sText = sText.replace(/\n/g,"<br/>");
			sText = '<b style="color:#00FF00">RECEIVE (' + ajaxUniqueID + '):</b><br/>' + sText;
			sText = "<hr>" + sText + "<hr>"; //separate since multiple receive instances may 
			this.debugReceiveWindowContainer.innerHTML += sText;
		}
	} catch (oError) {
		throwConsoleErroror("ckAjaxUIObj.seetDebugReceive",oError)
	}
	
}
ckAjaxUIObj.prototype.showDebugWindows = function() {
	//intended primarily to be called manually from the address bar when needed. Only create and clear the content if not already created.
	//Instead of checking this.debugSendWindowContainer, need to check for the actual element on the page since multiple Ajax objects could be created.  All should use the same debug windows.

	var checkSendContainer = document.getElementById("ajax.debugSendWindowContainer");
	var checkReceiveContainer = document.getElementById("ajax.debugReceiveWindowContainer");
	
	if (checkSendContainer) this.debugSendWindowContainer = checkSendContainer;
	if (checkReceiveContainer) this.debugReceiveWindowContainer = checkReceiveContainer;
	
	if ((!this.debugSendWindowContainer) || (!this.debugReceiveWindowContainer)) {
		this._createDebugWindows();
		if (this.debugSendWindowContainer) {
			this.debugSendWindowContainer.innerHTML = '<b>Ajax POST data will appear here.</b><hr/>';
			this.debugSendWindowContainer.style.display="block";
			this.debugSendWindowContainer.style.zIndex = 100;
		} else throwConsoleError("ckAjaxUIObj.showDebugWindows","Debug send window could not be created");
		
		if (this.debugReceiveWindowContainer) {
			this.debugReceiveWindowContainer.innerHTML = '<b>Ajax response data will appear here.</b><hr/>';
			this.debugReceiveWindowContainer.style.display="block";
			this.debugReceiveWindowContainer.style.zIndex = 101;
		} else throwConsoleError("ckAjaxUIObj.showDebugWindows","Debug receive window could not be created");
	}
}


/*-------------------------------------------------------------------------------------------
Default Return Handler
	--takes action based on eDoc type and parameters/value within the XML.  
	--this is automatically called if no returnHandler specified when calling loadXML() or postForm()
	--the only code in here should be for completely generic (non-app specific) handling
-------------------------------------------------------------------------------------------*/
ckAjaxUIObj.prototype.defaultReturnHandler = function(aStatus) {
	var statusCode = aStatus[0];
	var statusText = aStatus[1];
	var oAjax = aStatus[2];

	//oAjax.oUI.hideProgressWindow(); //always???
	if (statusCode == 200) {
		try {
			var returnValue = "";
			var oNode, oChildNode;
			var oRootNode;
			if (oRootNode = oAjax.oXMLDOM.documentElement) {
				var docType = oRootNode.getAttribute("type");
				switch (docType) {
					case "optionsCollection" : returnValue = oAjax.oUI._processResponse_optionsCollection(oRootNode); //the "this" keyword will not work since this is a returnHandler called from another object
						break;
					case "messageCollection" : returnValue = oAjax.oUI._processResponse_messageCollection(oRootNode);
						break;
					case "text/javascript" :
						var regex = /^\s*<script.*?>([\s\S]+?)<\/script>/;
						var aMatches = oAjax.responseText.match(regex);
						var scriptBlock = RegExp.$1;
						
						var regex = /^\s*<!\[CDATA\[.*?>([\s\S]+?)\]\]>/;
						var aMatches = scriptBlock.match(regex);
						var scriptBlock = RegExp.$1;
						
						if (scriptBlock != "") eval(scriptBlock);
						returnValue=true;
						break;
					case "error" :
						alert("error found");
						break;
					default : returnValue = false; //return value indicating that the default return handler did not find anything to process
				}
			} 
			return(returnValue);
			
		} catch(oError) {
			//do not throw any error because this function is called after all ajax calls and not every call will return an XML document.  Some returns are just HTML.
			return false;
		}
	} else {	
		if (statusCode == 0) {
			oAjax.oUI._processResponse_error(null,statusCode,"oXMLHttp Response Status","An HTTP status code of zero ('0') was returned. No status text information is available");
		} else {
			oAjax.oUI._processResponse_error(null,statusCode,"oXMLHttp Response Status",statusText);
		}
	}
}
/*-------------------------------------------------------------------------------------------

PRIVATE RESPONSE HANDLERS

-------------------------------------------------------------------------------------------*/
ckAjaxUIObj.prototype._processResponse_JSONerror = function(oResponse) {
	try {
		
		var sBlankHTML = "";
		var sInvalidHTML = "";
		var aBlankErr, aInvalidErr;
		var bOnlyBlankInvalid;
			
		if (aBlankErr = oResponse.error.aBlank) {
			if (aBlankErr.length > 0) {
				sBlankHTML = 'The following may not be <b>blank</b>: ';
				for (var index=0; index < aBlankErr.length; index++) {
					sBlankHTML += (index > 0 ? ", " : "") + aBlankErr[index];
				}
				sBlankHTML += "<br/>";
			}
		}
		if (aInvalidErr=oResponse.error.aInvalid) {
			if (aInvalidErr.length > 0) {
				sInvalidHTML = 'The following are <b>not valid</b>:<ul style="list-style-type:square;margin-top:1px">'
				for (var index=0; index < aInvalidErr.length; index++) {
					sInvalidHTML += '<li>' + aInvalidErr[index] + '</li>';
				}
				sInvalidHTML += '</ul>'
			}
		}
		var sErrHTML = ""
		for (var index=0; index < oResponse.error.aError.length; index++) {
			sErrHTML += oResponse.error.aError[index].desc + '<br/>';
		}
		if (sBlankHTML != '' || sInvalidHTML !='') {
			bOnlyBlankInvalid = (sErrHTML=="");
			if (!bOnlyBlankInvalid) {
				sErrHTML += '<ul style="list-style-type:none">';
				if (sBlankHTML != '') sErrHTML += '<li>' + sBlankHTML + (sInvalidHTML != "" ? "<br/>" : "") + '</li>';
				if (sInvalidHTML != '') sErrHTML += '<li>' + sInvalidHTML + '</li>';
				sErrHTML += '</ul>';
			} else {
				if (sBlankHTML != '') sErrHTML = sBlankHTML + (sInvalidHTML != "" ? "<br/>" : "");
				if (sInvalidHTML != '') sErrHTML += sInvalidHTML
			}
		}
		
		if ((oFloatingWindow) && (oFloatingWindow.bShowing)){
			oFloatingWindow.showError(sErrHTML);
		} else {
			displayError("",sErrHTML);
			if ((oFloatingWindow) && (oFloatingWindow.bShowingWait)) oFloatingWindow.hide();
		}

		return true;

	} catch(oError) {
		throwConsoleError("ckAjaxUIObj._processResponse_JSONerror",oError);
	}
}

ckAjaxUIObj.prototype._processResponse_error = function(oRootNode) {
	try {
		var oNode, oChildNode;
		var args = ckAjaxUIObj.prototype._processResponse_error.arguments
		var errNumber = (args.length >= 2 ? args[1] : "");
		var errSource = (args.length >= 2 ? args[2] : "");
		var errDescription = (args.length >= 2 ? args[3] : "");
		var errRequestData, errParamData;

		if (oRootNode) {
			for (var index=0; index < oRootNode.childNodes.length; index++) {
				oNode = oRootNode.childNodes[index];

				switch (oNode.nodeName) {
					case "error" :
						for (var subIndex=0; subIndex < oNode.childNodes.length; subIndex++) {
							oChildNode = oNode.childNodes[subIndex];

							switch (oChildNode.nodeName) {
								case "number" : errNumber = oChildNode.firstChild.nodeValue; break;
								case "source" : errSource = oChildNode.firstChild.nodeValue; break;
								case "description" : errDescription = oChildNode.firstChild.nodeValue; break;
							}
						}
					case "requestData","parameterData" :
						for (var subIndex=0; subIndex < oNode.childNodes.length; subIndex++) {
							oChildNode = oNode.childNodes[subIndex];

							switch (oChildNode.nodeName) {
								case "parameter" : //work on this later
							}
						}
						break;
				}
			}
		}
		
		var oSpan, oErrorContainer;
		if (oFloatingWindow) {
			oFloatingWindow.showError(errNumber,errSource,errDescription,oAjax.lastURL);
		}
		return true;

	} catch(oError) {
		throwConsoleError("ckAjaxUIObj._processResponse_error",oError);
	}
}

ckAjaxUIObj.prototype._processResponse_forcedRedirect = function(oRootNode) {
	try {
		var oNode, oChildNode;
		var sMessage = "";
		var sURL = "";

		for (var index=0; index < oRootNode.childNodes.length; index++) {
			oNode = oRootNode.childNodes[index];
			switch (oNode.nodeName) {
				case "message" : sMessage = oNode.text;
					sMessage = sMessage.replace(/^ */,"").replace(/ *$/,""); //trim
					break;
				case "url" : sURL = oNode.text;
					break;
			}
		}
		if (sMessage != "") alert(sMessage);
		if (sURL != "") document.location.href=sURL;
		
		return true;

	} catch(oError) {
		throwConsoleError("ckAjaxUIObj._processResponse_forcedRedirect",oError);
	}
}
ckAjaxUIObj.prototype._processResponse_optionsCollection = function(oRootNode) {
	var oNode, oChildNode, oNamedNodeMap;
	try {
		for (var index=0; index < oRootNode.childNodes.length; index++) {
			oNode = oRootNode.childNodes[index];
			if (oNode.nodeName == "options") {
				var selectID, oSelect;
				if ((selectID = oNode.getAttribute("selectID")) && (oSelect=document.getElementById(selectID))) {
					var selectedValue = oNode.getAttribute("selectedValue");
					var nameValueArr = new Array();
				
					for (var childIndex = 0; childIndex < oNode.childNodes.length; childIndex++) {
						oChildNode = oNode.childNodes[childIndex];
						if (oChildNode.nodeName=="option") {
							if(oNamedNodeMap = oChildNode.attributes) { //using a map of the attributes allows custom attributes to be added to the valueArr which is passed to the fillOptions() function so the attributes can be added to the OPTION tag
								var valueArr = new Array();
								for (var attrIndex=0; attrIndex < oNamedNodeMap.length; attrIndex++) {
									var oNamedNode = oNamedNodeMap.item(attrIndex);
									valueArr[oNamedNode.nodeName] = oNamedNode.nodeValue;
								}
								//use firstChild.nodeValue for Mozilla compatibility
								nameValueArr[childIndex] = new nameValueObj(oChildNode.firstChild.nodeValue,valueArr);
							}
						}
					}
					
					//filling a select box is not application specific, so the actual action is taken directly within this function and no values are returned
					fillOptions(oSelect,nameValueArr,selectedValue)

				} else throw new Error("Unable to find/access SELECT control (id:" + selectID + ") to populate");
			}
		}
		return true;
	} catch(oError) {
		throwConsoleError("ckAjaxUIObj._processResponse_optionsCollection",oError);
		return false;
	}
}


ckAjaxUIObj.prototype._processResponse_messageCollection = function(oRootNode) {
	try {
		var oNode, oChildNode;
		var messageType = "";
		var sMessage;
		var aMessageTypes = new Array();
		for (var index=0; index < oRootNode.childNodes.length; index++) {
			oNode = oRootNode.childNodes[index];
			
			if (oNode.nodeName == "messages") {
				for (var childIndex = 0; childIndex < oNode.childNodes.length; childIndex++) {
					oChildNode = oNode.childNodes[childIndex];
					if (oChildNode.nodeType != 3) { //no #text
						messageType = oChildNode.getAttribute("type");
						sMessage = oChildNode.firstChild.nodeValue;
						if (sMessage != "") {
							var aMessages = aMessageTypes[messageType];
							if (!aMessages) {
								var aMessages = new Array();
								aMessageTypes[messageType] = aMessages;
							}
							aMessages[aMessages.length] = sMessage
						}
					}
				} 
			}
		}
		
		//since each application this may be used with is different, how the messages are displayed at this
		//  point is something that should be handled outside this object
		return aMessageTypes;

	} catch(oError) {
		throwConsoleError("ckAjaxUIObj._processResponse_messageCollection",oError);
	}
}
/*-------------------------------------------------------------------------------------------

PRIVATE

-------------------------------------------------------------------------------------------*/

ckAjaxUIObj.prototype._createProgressWindow = function() {
	var oDiv = document.createElement('DIV');
	if (oDiv) {
		//<div id="ajax.progressWindowContainer" align="center" width="400" height="147" class="progressWindowLayer" ></div>');
		oDiv.id = "ajax.progressWindowContainer";
		oDiv.style.textAlign="center";
		oDiv.style.width="400px";
		oDiv.style.height="147px";
		oDiv.className="progressWindowLayer";
		
		document.body.appendChild(oDiv);
		this.progressWindowContainer = document.getElementById("ajax.progressWindowContainer");
	}
	
	var oFrame = document.createElement('IFRAME');
	if (oFrame) {
		//'<iframe src="/web/images/spacer.gif" id="ajax.progressWindowFrame" frameborder="0" class="hiddenIFrame" scrolling="no" width="400" height="147"></iframe>');
		oFrame.id="ajax.progressWindowFrame";
		oFrame.className="hiddenIFrame";
		oFrame.src="/web/images/spacer.gif";
		oFrame.scrolling="no";
		oFrame.width="400";
		oFrame.height="147";
		oFrame.frameBorder="0";
		
		document.body.appendChild(oFrame);
		this.progressWindowFrame = document.getElementById("ajax.progressWindowFrame");
	}
}
ckAjaxUIObj.prototype._createDebugWindows = function() {
	//debug windows may already exist on screen from other instances of this object.  Do not recreat if so.
	this.debugSendWindowContainer = document.getElementById("ajax.debugSendWindowContainer");
	if (!this.debugSendWindowContainer) {
		var oDiv = document.createElement('DIV');
		if (oDiv) {
			oDiv.id = "ajax.debugSendWindowContainer";
			oDiv.style.height = "300px";
			oDiv.style.overflowY = "auto";
			oDiv.style.border="1px solid #000099";
			oDiv.style.backgroundColor="#FFFFFF";
			oDiv.style.margin="5px";
			oDiv.style.padding="10px";
			document.body.appendChild(oDiv);
			this.debugSendWindowContainer = document.getElementById("ajax.debugSendWindowContainer");
		} else throw new Error("Unable to create debug send container");
	}

	this.debugReceiveWindowContainer = document.getElementById("ajax.debugReceiveWindowContainer");
	if (!this.debugReceiveWindowContainer) {
		var oDiv = document.createElement('DIV');
		if (oDiv) {
			oDiv.id = "ajax.debugReceiveWindowContainer";
			oDiv.style.height = "300px";
			oDiv.style.overflowY = "auto";
			oDiv.style.border="1px solid #009900";
			oDiv.style.backgroundColor="#FFFFFF";
			oDiv.style.margin="5px";
			oDiv.style.padding="10px";
			document.body.appendChild(oDiv);
			this.debugReceiveWindowContainer = document.getElementById("ajax.debugReceiveWindowContainer");
		} else throw new Error("Unable to create debug receive container");
		
	}

}

