/** 
 * @fileoverview 
 * <h3>SAF (Standard Action Forms) Validation</h3>
 * Client-side validation routines for all forms that have a <code>class</code>  
 * attribute of
 * <code>saf</code>
 * (ex. <code>&lt;form id="sampleform" action="." method="post"  
 * class="saf"&gt;</code>).
 *
 * @version 2.5
 *
 * @author Matt Dertinger
 * @author Yun Qian
 *
 * @see /c/06/saf.css for presentation rules
 * @see <var>SAFRULE</var> object within saf/conf.js file for the related 
 * validation rules.
 * @see the <var>SAF_l10._ERRORMSG</var> object within 
 * saf/l10n/safmessages_en.js for associated localized error messages in English
 * @see the <var>SAF_l10._ERRORMSG</var> object within safl10n/safmessages_es.js 
 * for associated localized error messages in Spanish
 * @see the <var>SAF_l10._ERRORMSG</var> object within 
 * saf/l10n/safmessages_zh-Hant.js for associated localized error messages in 	
 * Chinese
 *
 */
function addEvent(obj, evtType, fn, useCapture){
	if (obj.addEventListener){
		obj.addEventListener(evtType, fn, useCapture);
		return true;
	} else if (obj.attachEvent){
		var r = obj.attachEvent("on"+evtType, fn);
		return r;
	} else {
		obj['on'+evtType] = fn;
		return true;
	}
}

var safTimer = setTimeout('',2000);
var thisFld;
var xmlHttp;

/**
 * Construct a new safHandler class.
 * @class This class represents an instance of a safHandler.
 * @constructor
 *
 * @return A new instance of a safHandler.
 *
 */
function safHandler() {
	/* Member Variables */
	/**
	 * Stores boolean regarding whether a field validates or not.
	 * @type boolean
	 *
	 */
	this.isError = 0;
	this.setSAF = function() {
		var i, j;
		for (i = document.getElementsByTagName('form').length; i != 0; i--) {
			if (document.getElementsByTagName('form')[i-1].className.indexOf("saf") != -1) {
				
				this.f = document.forms[i-1];
				
				//addEvent(this.f,"submit",safObj.validateAll,false);
				for (j = this.f.elements.length; j != 0; j--) {
					var el = this.f.elements[j-1];
					/** If <var>el</var> is not a member of the SAFTYPE array 
					 * or the array item is set to false, then continue to 
					 * next form element.
					 *
					 * @see /j/06/constants.js for SAFTYPE array 
					 */
					if(!el.type) continue;
					if (typeof SAFTYPE[el.type] == "undefined" || SAFTYPE[el.type] == 0) continue;
					addEvent(el,"blur",safObj.setBlur,false);
					addEvent(el,"focus",safObj.setFocus,false);
					if (el.type == "select-one") {
						//addEvent(el,"change",safObj.setChange,false);
					} else if (el.type == "radio" || el.type == "checkbox") {
					//	addEvent(el,"click",safObj.setClick,false);
					} 
					//safObj.setLoad(el);
				}
			}
		}
	}
}

/* SAF Validate Methods */

/**
 * This method returns a Boolean value (true or false) depending on whether a  
 * field validates or not.
 * @extends safHandler
 * @type Boolean
 *
 */
var xmlHttp = null;
safHandler.prototype.validate = function() {
	/* Local Variable to store the object reference of the current field being validated */
	thisFld = this.fld;
	var fld = this.fld;
	if (typeof arguments[0] != 'undefined') {
		fld = document.getElementById(arguments[0]);
	}
	xmlHttp = Ajax.getTransport();
	var action = fld.form.action;
	var url = action.replace("/action/","/action/validate_")+"?" + Form.serialize(fld.form);
	xmlHttp.open("GET", url, true);
	xmlHttp.onreadystatechange = this.callback;
	xmlHttp.send(null);
}

safHandler.prototype.callback = function() {
	var fld = safObj.fld;
	if (xmlHttp.readyState == 4) {
		if (xmlHttp.status == 200) {
			var response = "\u00A0";
			var lis = xmlHttp.responseXML.getElementsByTagName("li");
			for(var i=0;i<lis.length;i++){
				if(lis[i].getAttribute('id') == fld.name.replace(SAFRULE._MASK["DIGITS"],'')){
					response = lis[i].firstChild.nodeValue;
					break;
				}
			}
			safObj.isError = (response != "\u00A0") ? 1 : 0; 
			safObj.messageHandler(response);
		}
	}
}

/* SAF Message Handler, used to display information to the site visitor after a
 * a call to the validate() method 
 */
safHandler.prototype.messageHandler = function(response) {
	var fld = this.fld;
	
//	var fldId = (/* isMultiple || */ fld.type == "radio") ? fld.id.replace(SAFRULE._MASK["DIGITS"],'') : fld.id;
	var fldId = fld.id.replace(SAFRULE._MASK["DIGITS"],'');
	var elemMsg;
	var parentEL;
	var siblingEL;

	if (getAncestorByTagName(fld,'dl')!=null)
		parentEL = getAncestorByTagName(fld,'dl');
	else
		parentEL = fld;

	if (document.getElementById(fldId+"-errors-row")!=null)
		siblingEL = document.getElementById(fldId+"-errors-row");

	
	var elemMsgId = fldId + "Msg";
	
	if (fld.type == "radio")
		elemMsgId = fld.name + "Msg";
	if (document.getElementById(elemMsgId)) {
		elemMsg = document.getElementById(elemMsgId);
		
		if (!elemMsg.firstChild) {
			elemMsg.appendChild(document.createTextNode('&#xA0;'));
		}
	} else {
		elemMsg = createXhtmlElement('dd');
		elemMsg.id = elemMsgId;
		elemMsg.className = "fieldmessage";
		elemMsg.appendChild(document.createTextNode('&#xA0;'));
		if(parentEL)
			parentEL.appendChild(elemMsg);
	}
	if(parentEL){
		if (this.isError) {
			if (parentEL.className.indexOf('error') == -1) {
				parentEL.className += " error";
			}
		} else {
			parentEL.className = parentEL.className.replace(" error","");
			parentEL.className = parentEL.className.replace("error","");
		}
		parentEL.className = parentEL.className.replace(" focus","");
	}else{
		if (this.isError) {
			if (elemMsg.className.indexOf('error') == -1) {
				elemMsg.className += " error";
			}
		} else {
			elemMsg.className = elemMsg.className.replace(" error","");
			elemMsg.className = elemMsg.className.replace("error","");
		}
	
	}
	if (siblingEL)
	{
		if (this.isError)
		{
			if (siblingEL.className.indexOf('error') == -1)
				siblingEL.className += " error";
		}
		else
		{
			siblingEL.className = siblingEL.className.replace(" error","");
			siblingEL.className = siblingEL.className.replace("error","");
		}
	}

/** Added by Kunal Bhatia; kunal.bhatia@compuware.com 

	The following if/else statement was added for check order status form so that when both orderNumber anf lastName have the same error then we are to show the error only once
**/
	var response_trimmed = response.substr(0, response.length-1);
	if (elemMsgId=="lastNameMsg" && (document.getElementById("orderNumberMsg").firstChild!=null && document.getElementById("orderNumberMsg").firstChild.nodeValue==response_trimmed))
		elemMsg.firstChild.nodeValue = "";
	else
	{
		if (elemMsgId=="orderNumberMsg" && (document.getElementById("lastNameMsg").firstChild!=null && document.getElementById("lastNameMsg").firstChild.nodeValue==response_trimmed))
			document.getElementById("lastNameMsg").firstChild.nodeValue = "";
		elemMsg.firstChild.nodeValue = response_trimmed;
	}
	
}

/* SAF Event Handler Methods */
safHandler.prototype.setFocus = function(obj) {
	this.fld = obj.target ? obj.target : obj.srcElement? obj.srcElement : obj;
	beforeSubmit = false;
	if (!this.fld.className) this.fld.className = "";
	var fldId = (this.fld.id) ? this.fld.id : "";
/*	var parentDL = getAncestorByTagName(this.fld,'dl');
	if (parentDL.className.indexOf('focus') == -1) {
		parentDL.className += " focus";
	}
	*/
	var waitToValidate = (this.fld.type == "radio" || this.fld.type == "checkbox") ? 1 : 0;
	if (waitToValidate && fldId.lastIndexOf("0") == -1) {
		clearTimeout(safTimer);
	}
}

safHandler.prototype.setBlur = function(obj) {
	safObj.fld = obj.target ? obj.target : obj.srcElement? obj.srcElement : obj;
	safTimer = setTimeout("safObj.validate()",200);
}

var safObj;
var initSAF = new domFunction(function() {
		if (typeof safHandler == "function") {
			safObj = new safHandler();
			safObj.setSAF();
		}
	}, { 'footer' : 'id' } );