// ajax.js
// 
// 12/18/08 JLD 12243 modify myGlobalHandlers for Firefox 3 enforcement
// 12/11/07 JLD 9865  add request.responseXML.documentElement to list of properties for parsed XML object
// ??/??/07 JLD 10443 allow multiple AJAX request types per page load
//
// Commented 5/10/06 JLD
// 
// Note: 	This library includes functions used in the Prototype javascript library.
//			Any page using this file must also link to prototype.js.
//

// 10443: index to these arrays is passed into external fxns (xmlLoad et al)
var xmlMoz = new Array();			// 10443: array of Mozilla XML DOM docs
var xmlIE = new Array();			// 10443: array of IE XML DOM docs
var xmlString = new Array();		// 10443: array of strings holding XML returned from AJAX call

//var xmlMoz;					// Mozilla XML DOM doc
//var xmlIE;					// IE XML DOM doc
//var xmlString;					// string holding XML returned from AJAX call

var parser; 					// Mozilla-only XML parser

var xslLoaded = false;			// for determining whether to reload XSL document
var useXSLT = true;				// if user specifies XSLT transform, run one, else skip it
var useAfterRequestXML = false; 	// whether or not to execute user-defined code during requestXMLfinished function

var isIE = (window.ActiveXObject);
var isOtherSafe = (document.implementation && document.implementation.createDocument);

///////////////////////////////////////////////////////////////
//	loadXML extension to Prototype AJAX object
///////////////////////////////////////////////////////////////
if (isOtherSafe)
{
	Document.prototype.loadXML = function(strXML) 
	{
		//create a DOMParser
		var objDOMParser = new DOMParser();
		//create new document from string
		var objDoc = objDOMParser.parseFromString(strXML, "text/xml");  
		//make sure to remove all nodes from the document
		while (this.hasChildNodes())
		{
			this.removeChild(this.lastChild);
		}
		//add the nodes from the new document
		for (var i=0; i < objDoc.childNodes.length; i++) 
		{            
			//import the node
			var objImportedNode = this.importNode(objDoc.childNodes[i], true);            
			//append the child to the current document
			this.appendChild(objImportedNode);
		} //End: for
	} //End: function
}

var myGlobalHandlers = 
{
	onCreate: function()
	{
		if ($("systemWorking")) // 12243
			Element.show('systemWorking');
	},

	onComplete: function() 
	{
		if(Ajax.activeRequestCount == 0)
		{
			if ($("systemWorking")) // 12243
				Element.hide('systemWorking');
		}
	}
};

Ajax.Responders.register(myGlobalHandlers);

/////////////////////////////////////////////////////////////////
// XMLLOAD(): take input XML and feed into DOM document object
/////////////////////////////////////////////////////////////////
function xmlLoad(xmlStr, xmlIndex) 	// 10443: add argument xmlIndex for multiple XML objects
{
	if (!(xmlIndex))
		xmlIndex = 0;
	
	try
	{
		if (isIE)
		{
			xmlIE[xmlIndex] = new ActiveXObject("Microsoft.XMLDOM");
			xmlIE[xmlIndex].async="false";
			xmlIE[xmlIndex].loadXML(xmlStr);
			return xmlIE[xmlIndex]; // 9865
		}
		else if (isOtherSafe)
		{
			parser = new DOMParser();
			xmlMoz[xmlIndex] = parser.parseFromString(xmlStr, "text/xml"); 					
			return xmlMoz[xmlIndex]; // 9865
		}
	}
	catch (e)
	{
		alert('Error during string override fetch (XML Load: ' + e.description + '); please contact DSI Support.');
	}
}
/////////////////////////////////////////////////////////////////
// REQUESTXML(): page calls this function to get XML back
/////////////////////////////////////////////////////////////////
function requestXML(url, params)
{
	try
	{
		var myAjax = new Ajax.Request( url, params );
	}
	catch(e)
	{
		alert('Error during string override fetch (getXML: ' + e.description + '); please contact DSI Support.');
	}
}

/////////////////////////////////////////////////////////////////
// EXTRACTNODE(): get a specific node from the XML objects
/////////////////////////////////////////////////////////////////
function extractNode(nodeName, arrayIndex, xmlIndex) 	// 10443: add argument xmlIndex for multiple XML objects
{
	if (!(xmlIndex))
		xmlIndex = 0;
	
	var retval;
	
	try
	{
		if (isIE)
		{
			retval = xmlIE[xmlIndex].getElementsByTagName(nodeName)[arrayIndex];
		}
		else if (isOtherSafe)
		{
			retval = xmlMoz[xmlIndex].getElementsByTagName(nodeName)[arrayIndex];
		}
	}
	catch(e)
	{
		alert('Error during selected override fetch (extractNode: ' + e.description + '); please contact DSI Support.');
	}
	
	return retval;
}

/////////////////////////////////////////////////////////////////
// EXTRACTNODEVALUE(): get a node value out of a node extract
/////////////////////////////////////////////////////////////////
function extractNodeValue(node, nodeName, suppressUndefined)
{
	return Try.these
		(
		// tag content
		function() {return node.getElementsByTagName(nodeName)[0].firstChild.nodeValue;},
		function() {if (suppressUndefined) return "";}
		);
}

/////////////////////////////////////////////////////////////////
// EXTRACTNODEVALUES(): get a list of all matching node values
/////////////////////////////////////////////////////////////////
function extractNodeValues(node, nodeName, delimitor, showNumbers, numAttName)
{
	return Try.these
		(
		function() 
		{
			var list = node.getElementsByTagName(nodeName);
			var output = "";
			for (var i=0;i<list.length;i++)
			{
				if (output != "")
				{
					output += delimitor;
				}
				if (showNumbers)
				{
					output += ("^" + list[i].getAttribute(numAttName) + " = ");
				}
				output += list[i].firstChild.nodeValue;
			}
			return output;
		}
		);
}

/////////////////////////////////////////////////////////////////
// EXTRACTATTVALUE(): get an attribute value out of a node extract
/////////////////////////////////////////////////////////////////
function extractAttValue(node, nodeName, attName, suppressUndefined)
{
	return Try.these
		(
		// child tag attribute
		function() {return node.getElementsByTagName(nodeName)[0].getAttribute(attName);},
		// root tag attribute
		function() {return node.getAttribute(attName);}
		);
}

/////////////////////////////////////////////////////////////////
// SERIALIZEFORM(): crunch form into a string for XML posting
/////////////////////////////////////////////////////////////////
function serializeForm(formName)
{
	//var form = $(formName);
	//var form = document.forms[formName];
	var serial = Form.serialize(document.forms[formName]);  // call to Prototype library
	return serial;
}

////////////////////////////////////////////////////////////////////////////
// XMLRESPONSEPARSE(): digest DSI-standard AJAX response, return values when they exist
////////////////////////////////////////////////////////////////////////////
function xmlResponseParse(req, xmlIndex) 	// 10443: add xmlIndex argument for multiple objects
{
	if (!(xmlIndex))
		xmlIndex = 0;
	
	try
	{
		var retval = { code: null, msg: null, id: null, sqlcode: null, sqlerror: null, redirect: null, responseText: null, xmlChunk: null, xmlDoc: null }; // 9865 added explicit inits of responseText, xmlChunk, xmlDoc
		
		var xmlString 		= xmlLoad(req.responseText, xmlIndex);				// make a parsed XML object
		var xmlChunk 		= extractNode("dsixml", 0, xmlIndex);		// pull root tag "<dsixml>" [10443: add xmlIndex argument]
	
		retval.responseText	= req.responseText;							// response text, to facilitate access
		retval.xmlChunk		= xmlChunk;									// the tag element, to facilitate customization
		retval.xmlDoc 		= xmlString;								// 9865 return this for access to parsed XML document object
		retval.code 		= extractNodeValue(xmlChunk, "code", false);		// result code
		retval.msg 			= extractNodeValue(xmlChunk, "msg", false);		// result message
		retval.id 			= extractNodeValue(xmlChunk, "id", false);			// if new row inserted, ID comes here
		retval.sqlcode 		= extractNodeValue(xmlChunk, "sqlcode", false);	// sqlcode from EXCEPTION block
		retval.sqlerror 	= extractNodeValue(xmlChunk, "sqlerror", false);	// sql message from EXCEPTION block
		retval.redirect		= extractNodeValue(xmlChunk, "redirect", false);	// this code comes from PKG_SESSION on timeout
		
		//alert("code = " + retval.code + "\nid = " + retval.id + "\nmsg = " + retval.msg + "\nsqlcode = " + retval.sqlcode + "\nsqlerror = " + retval.sqlerror + "\nredirect = " + retval.redirect); 
	
		return retval;
	}
	catch(e)
	{
		alert('Error during string override fetch (xmlResponseParse: ' + e.description + '); please contact DSI Support.');
	}
}

