/*jslint white: true, browser: true, devel: true, onevar: true, undef: true, nomen: true, eqeqeq: true, plusplus: true, bitwise: true, regexp: true, newcap: true, immed: true */

/**
	@fileoverview The heart of eOne's Ajax processes.
	@version 11.5
*/

var errorElemID = '',
	hasEoneErrors = false;

/**
	@description Returns the inner content of an XML node<br />
					Note: Makes use of Mozilla's XMLSerializer object (after browser sniffing)
	@since Pre-v11.5
	@param {XML NODE} thisNode The parent node from which to start looking.
	@param {STRING} qryNodeName The name of the XML node whose value you want returned.
	@returns {STRING?} The value of the node requested, as a string.
	@example displayName = getNodeValue(childNodes[j], 'DisplayName');	//	{@link #publishResponseXML}
*/
var getNodeValue = function (thisNode, qryNodeName) {
	var qryNode = thisNode.getElementsByTagName(qryNodeName),
		nodes = qryNode[0].childNodes,
		browser = navigator.appName,
		nodeVal = '';

	if (nodes && nodes.length > 0) {
		if (browser === "Netscape") {
			nodeVal += (new XMLSerializer()).serializeToString(nodes[0]);
		} else {
			nodeVal += nodes[0].xml;
		}
	}

	return nodeVal;
};

/**
	@description Handles publishing the XML received from the XHR Response<br />
					Note: Uses Mozilla's XMLSerializer Object (after browser sniffing)
	@since Pre-v11.5
	@param {XHR Response Obj} req The response object returned by the XHR request
	@param {STRING} tag The tag name of the container node in the XHR response.
	@requires getNodeValue
	@requires writeScriptTagsToDOM
	@requires hasEoneErrors (Global)
	@returns {STRING?} The content of the response, either as errors or as new HTML, in a string.
	@example publishResponseXML(req, 'xml');	//	{@link #ajaxShopResponse}
*/
var publishResponseXML = function (obj, tag) {
	var respXMLNodes = obj.responseXML.getElementsByTagName(tag),
		respXMLNode = respXMLNodes[0],
		browser = navigator.appName,
		nodes = respXMLNode.childNodes,		// each child node of the response xml should be published to the document when a div element ID matches the child's node name
		nodeName,
		thisSeg,
		nodeVal,
		childNodes,
		displayName,
		returnHtml,
		i, j;		// counters

	if (typeof window.removeLoadMessage === 'function') {
		removeLoadMessage();
	}

	for (i = 0; i < nodes.length; i += 1) {
		nodeName = nodes[i].nodeName;
		thisSeg = nodeName;

		if (nodeName === 'error') {
			hasEoneErrors = true;

			thisSeg = errorElemID;

			if (document.getElementById(thisSeg)) {
				nodeVal = '';
				childNodes = nodes[i].childNodes;
				document.getElementById(thisSeg).innerHTML = "";

				for (j = 0; j < childNodes.length; j += 1) {
					displayName = getNodeValue(childNodes[j], 'DisplayName');

					if (!displayName || displayName.length  === 0 || displayName === 'null') {
						displayName = '';
					} else {
						displayName += ' ';
					}

					nodeVal = nodeVal + displayName + getNodeValue(childNodes[j], 'Msg') + '<br/>';
				}

				returnHtml = nodeVal.replace("<![CDATA[", "");
				returnHtml = returnHtml.replace("]]>", "");
				
				document.getElementById(thisSeg).innerHTML = returnHtml;
				writeScriptTagsToDOM(thisSeg);
				document.getElementById(thisSeg).focus();
			}
		} else {
			if (document.getElementById(thisSeg)) {
				nodeVal = '';
				childNodes = nodes[i].childNodes;

				for (j = 0; j < childNodes.length; j += 1) {
					if (browser === "Netscape") {
						nodeVal += (new XMLSerializer()).serializeToString(childNodes[j]);
					} else {
						nodeVal += childNodes[j].xml;
					}
				}

				returnHtml = nodeVal.replace("<![CDATA[", "");

				while (returnHtml.indexOf("<![CDATA[") > -1) {
					returnHtml = returnHtml.replace("<![CDATA[", "");
				}

				while (returnHtml.indexOf("]]>") > -1) {
					returnHtml = returnHtml.replace("]]>", "");
				}

				while (returnHtml.indexOf(" </textarea>") > -1) {
					returnHtml = returnHtml.replace(" </textarea>", "</textarea>");
				}

				while (returnHtml.indexOf("\t</textarea>") > -1) {
					returnHtml = returnHtml.replace("\t</textarea>", "</textarea>");
				}

				document.getElementById(thisSeg).innerHTML = returnHtml;
				writeScriptTagsToDOM(thisSeg);
			}
		}
	}

	return nodeVal;
};

/**
	@description General-purpose XHR Request function &mdash; utilized in nearly all eOne Ajax processes.<br />
					Note: Uses eval()
	@since Pre-v11.5
	@param {STRING} parms The parameter string for the request.
	@param {???} errorDivID Meant to indicate the container for errors. Not used???
	@param {FUNCTION} [response = ajaxShopResponse] The function to be called upon response.
	@requires hasEoneErrors (Global)
	@requires prototype.js
	@example ajaxShop(parms, errorDivID, response);	//	{@link #populateStates}
*/
var ajaxShop = function (parms, errorDivID, response) {
	var url = '/servlet/AJAXActionServlet',
		myAjax;

	response = response || 'ajaxShopResponse';

	hasEoneErrors = false;

	myAjax = new Ajax.Request(url, {method: 'post', parameters: parms, onComplete: eval(response), encoding: 'UTF-8' });
};

/*		Test this out, eliminates "eval()"
		Calls Ajax.Request		(for jQuery Conversion)
var ajaxShop = function (parms, errorDivID, response) {
	var url = '/servlet/AJAXActionServlet',
		Ajax;

	if (typeof response !== 'function') {
		response = 'ajaxShopResponse';
	}
	var myAjax = new Ajax.Request(url, {method: 'post', parameters: parms, onComplete: response, encoding:'UTF-8'});
};
*/

/**
	@description Default XHR repsonse function for eOne processes.
	@since Pre-v11.5
	@param {XHR Response Object} req The XHR Response object.
	@requires publishResponseXML
	@example ajaxShopResponse(req);	//	{@link #populateStatesResponse}
	@see ajaxShop
*/
var ajaxShopResponse = function (req) {
	var ajaxResponseElements = req.responseXML.getElementsByTagName('ajaxActionResponse');

	if (ajaxResponseElements.length > 0) {
		publishResponseXML(req, 'xml');
	}
};

/**
	@description Works to replicate the (non-existant) functionality (typeof a === 'array')<br />
						From pg. 61 of "JavaScript: The Good Parts", by Douglas Crockford. Copyright 2008 Yahoo! Inc, 978-0-596-51774-8
	@param {Object} value The object being tested.
	@return {BOOLEAN} If value is an Array, the function returns true.
	@example } else if (isArray(formNames) === false) {	//	{@link getFormData}
*/
var isArray = function (value) {
	return value && typeof value === 'object' && typeof value.length === 'number' && typeof value.splice === 'function' && !(value.propertyIsEnumerable('length'));
};

/**
	@description Send in an Array of formNames and retrieve All name/value pairs for a POST
	@author Revised by John Arthur (v11.5)
	@since v11.5
	@param formNames The names of the forms to search through.
	@param {STRING} [exceptions = ''] A list of form element names that should not be added to the return string.
	@requires isArray
	@return {STRING} The equivalent of the url "search" (?...) string (less the "?").
	@example var parms = getFormData(thisForm.name, '', '', 'false', 'true'),	//	{@link submitAsAJAX}
*/
var getFormData = function (formNames, exceptions) {
	var data = '',
		form,
		fields,
		j, i;

	exceptions = exceptions || '';

	if (typeof formNames === 'string') {
		formNames = formNames.split(",");
	} else if (isArray(formNames) === false) {
		return data;
	}

	for (j = 0; j < formNames.length; j += 1) {
		form = parent.document.forms[formNames[j]];
		fields = form.elements;

		for (i = 0; i < fields.length; i += 1) {
			if (fields[i].type && fields[i].type.indexOf("button") === -1 && fields[i].type.indexOf("submit") === -1) {
				if (exceptions.indexOf(fields[i].name) === -1) {
					if (fields[i].type.indexOf("checkbox") > -1) {
						if (fields[i].checked) {
							data += fields[i].name + "=" + escape(fields[i].value) + "&";
						} else {
							data += fields[i].name + "=&";
						}
					} else if (fields[i].type.indexOf("radio") > -1) {
						if (fields[i].checked) {
							data += fields[i].name + "=" + escape(fields[i].value) + "&";
						}
					} else {
						data += fields[i].name + "=" + escape(fields[i].value) + "&";
					}
				}
			}
		}
	}

	//EONEDEBUG.log(data);

	return data;
};

/**
	@description Sets the submit event listener on a specific form to submit the form via XHR.
	@since Pre-v11.5
	@param {DOM OBJECT} thisForm The form to be submitted via XHR.
	@param {STRING} ID of the error container node.
	@requires getFormData (Global)
	@requires hasEoneErrors (Global)
	@requires prototye.js
	@example tempForm.onsubmit = function(){submitAsAJAX(this, errorDivID); return false;}	//	{@link #addAJAXEventToForm}
*/
var submitAsAJAX = function (thisForm, errorDivID) {
	var parms = getFormData(thisForm.name, '', '', 'false', 'true'),
		url = '/servlet/AJAXActionServlet',
		myAjax;

	if (typeof window.loadMessage === 'function') {
		loadMessage(thisForm);
	}

	errorElemID = errorDivID;
	hasEoneErrors = false;

	myAjax = new Ajax.Request(url, { method: 'post', parameters: parms, onComplete: ajaxShopResponse, encoding: 'UTF-8'});
};

/**
	@description Sets submit events to XHR Requests on specified form.
	@author Revised by John Arthur (v11.5) - Created the {@link ajaxSubmit} to avoid creating a function in a loop. #JSLint
	@since v11.5
	@param {STRING} formName The name attribute of the form to be submitted via XHR.
	@param {STRING} errorDivID The name of the container node for error messages.
	@see ajaxSubmit (inner function)
*/
var addAJAXEventToForm = function (formName, errorDivID) {
	var forms = document.getElementsByTagName('form'),
		tempForm,
		/**
			@description submits the form as Ajax
			@author John Arthur (v11.5)
			@since v11.5
			@inner
			@see addAJAXEventToForm
		*/
		ajaxSubmit = function () {
				submitAsAJAX(this, errorDivID);
				return false;
			},
		i;

	for (i = 0; i < forms.length; i += 1) {
		tempForm = forms[i];

		if (tempForm.name === formName) {
			tempForm.onsubmit = ajaxSubmit;
			tempForm.submit = ajaxSubmit;
		}
	}
};

/**
	@description Used to hijack a link's click event, and submit a request for the page via XHR.<br />
					Note: Makes use of global ajaxActionEnabled<br />
	@since Pre-v11.5
	@requires prototype.js
	@param {URL String} thisHref The value of the link's href attribute.
	@example &lt;eoneHREF href="/Shop?dsp=checkoutbilladdrlist" secure="y" class="button buttonEdit" onClick="javascript:openCheckoutHref(this.href);return false;"&gt;Edit&lt;/eoneHREF&gt;
*/

var openCheckoutHref = function (thisHref) {
	var errorDivID,
		parms,
		url,
		myAjax;

	if (ajaxActionEnabled && ajaxActionEnabled === 'true') {
		errorDivID = "defaultErrorDivID";
		parms = thisHref.substring(thisHref.indexOf("?") + 1);
		//alert(parms);
		//ajaxSendRequest('/servlet/AJAXActionServlet?'+parms, 'POST', errorDivID, 'actionprocessed', 'xml', 'actionParse', '', '', '', 'false');
		url = '/servlet/AJAXActionServlet';
		myAjax = new Ajax.Request(url, { method: 'post', parameters: parms, onComplete: ajaxShopResponse, encoding: 'UTF-8'});
	} else {
		window.open(thisHref);
	}
};
