/** 
 * SAF (Standard Action Forms) Validation 
 * Client-side validation routines for all forms that have a class attribute of
 * saf (ex. <form id="sampleform" action="." method="post" class="saf">).
 *
 * @version 2.0
 *
 * @author Matt Dertinger
 * @author Yun Qian
 *
 * @see /c/06/saf.css for presentation rules
 * @see SAFRULE object within saf/conf.js file for the related validation 
 * rules.
 * @see the SAF_l10._ERRORMSG object within saf/l10n/safmessages_en.js for associated 
 * localized error messages in English
 * @see the SAF_l10._ERRORMSG object within safl10n/safmessages_es.js for associated 
 * localized error messages in Spanish
 * @see the SAF_l10._ERRORMSG object within saf/l10n/safmessages_zh-Hant.js for 
 * associated localized error messages in Chinese
 *
 */

var safTimer = setTimeout('',2000);

function safHandler() {
	/* Member Variables */
//	this.f;
//	this.fld;
	this.isError = 0;
	this.checkMultiple = "";
	this.isCancel = false;
	this.setSAF = function() {
		var i, j;
		for (i = document.forms.length; i != 0; i--) {
			if (document.forms[i-1].className.indexOf("saf") != -1) {
				this.f = document.forms[i-1];
			//	this.f.onsubmit = function() { return safObj.validateAll(this); };
			//	addEvent(this.f,"submit",function() { return safObj.validateAll(safObj.f); });
				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 (el.type == "submit"){ addEvent(el,"click",safObj.checkSubmit,false); continue; }
					if (typeof SAFTYPE[el.type] == "undefined" || SAFTYPE[el.type] == 0) continue;
					//el.onblur = function() { safObj.setBlur(this); };
					//el.onfocus = function() { safObj.setFocus(this); };
					addEvent(el,"blur",safObj.setBlur,false);
					addEvent(el,"focus",safObj.setFocus,false);
					if (el.type == "select-one") {
						//el.onchange = function() { safObj.setChange(this); };
						addEvent(el,"change",safObj.setChange,false);
					} else if (el.type == "radio" || el.type == "checkbox") {
						//el.onclick = function() { safObj.setClick(this); };
						addEvent(el,"click",safObj.setClick,false);
					} 
					safObj.setLoad(el);
				}
			}
		}
	}
}

safHandler.prototype.checkSubmit = function(obj) {
	obj = obj.target ? obj.target : obj.srcElement? obj.srcElement : obj;
	if (obj.name.toLowerCase().indexOf("cancel") != -1)
		safObj.isCancel = true;
}

var n;
/* SAF Validate Methods */
safHandler.prototype.validate = function() {
	/* Local Variable to store the object reference of the current field being validated */
	var fld = this.fld;
	if(typeof arguments[0] != 'undefined')
		fld = document.getElementById(arguments[0]);
	
	/* local string variable to store the validation rules assigned to the current field being validated */
	var vRules = fld.className;
	
	/* Match objects for Regular Expression Literals */

	var reMask = /MASK(\S+)/.exec(vRules);
	
	var reRequiredIf = /IF-(\S+)/.exec(vRules);
	var reCharLimit = /CHARLIMIT(\S+)/.exec(vRules);
	var reCompare = /COMPARE-(\S+)/.exec(vRules);
	
	/* Local Boolean Variables */
	/* Store validation rules to apply to the current field being validated */
	var isRequired = (vRules.indexOf("REQUIRED") != -1 && vRules.indexOf('IF-') == -1) ? 1 : 0;
	var isRequiredIf = (vRules.indexOf('IF-') != -1) ? 1 : 0;
	var isMask = (vRules.indexOf('MASK') != -1) ? 1 : 0;
	var isCharLimit = (vRules.indexOf('CHARLIMIT') != -1) ? 1 : 0;
	var isMultiple = (vRules.indexOf('HAS') != -1) ? 1 : 0;
	var isCompare = (vRules.indexOf('COMPARE') != -1) ? 1 : 0;
	if (isCompare) var compareRule = reCompare[1].split("-");
	var isUnique = (vRules.indexOf('UNIQUE') != -1) ? 1 : 0;
	if(isUnique) { this.doUnique(fld);}
	if(vRules.indexOf('HAS') != -1)
		n = vRules.substr(vRules.indexOf('HAS')+3,1);
	
	/* Store validation results for the current field being validated */
	var isRequiredErr = (isRequired && (fld.value.replace(/^\s+/, '') == "" || (fld.type == "radio" && !this.validateChecked(fld.form[fld.name])))) ? 1 : 0;
	
	var isRequiredIfErr = (isRequiredIf && !this.validateRequiredIf(reRequiredIf[1])) ? 1 : 0;
	
	var isMaskErr = 0;
	if(vRules.indexOf('HAS') == -1)
		isMaskErr = (isMask && (fld.value != "" && !this.validateMask(reMask[1]))) ? 1 : 0;
	var isCharLimitErr = (isCharLimit && !this.validateCharLimit(reCharLimit[1])) ? 1 : 0;
	/* Need to finish conditional statement for multipleErr */
//	var isMultipleErr = (isMultiple && fld.value == "") ? 1 : 0;
	var isMultipleErr = (isMultiple && this.validateMultiple(fld)) ? 1 : 0;
	
	var isCompareErr = (isCompare && this.validateCompare(compareRule[0],compareRule[1])) ? 1 : 0;

	this.isError = (isRequiredErr || isRequiredIfErr || isCharLimitErr || isMaskErr || isMultipleErr || isCompareErr) ? 1 : 0;

	/* local string variable to store the value of the current field's title attribute */
	var fldTitle = (fld.type == "radio") ? fld.form[fld.name][0].title : (isMultiple)? document.getElementById(fld.id.replace(/\d/g,'') + '0').title : fld.title;
	
	if(reMask && reMask.length>1 && isMultiple)
		reMask[1] = reMask[1].replace(/\d/g,'') ;
	/* local string variable to store the text of the message to be returned */
	var vMessage = (isRequiredErr) ? SAF_l10n._ERRORMSG["REQUIRED"] + fldTitle.toLowerCase() : (isRequiredIfErr) ? SAF_l10n._ERRORMSG["REQUIRED"] + fldTitle.toLowerCase(fld) : (isMaskErr)? fldTitle + SAF_l10n._ERRORMSG[reMask[1]] :(isMultipleErr) ? fldTitle + SAF_l10n._ERRORMSG["MULTIPLE"] : (isCharLimitErr) ? fldTitle + SAF_l10n._ERRORMSG["CHARLIMIT0"] + reCharLimit[1] + SAF_l10n._ERRORMSG["CHARLIMIT1"] : (isCompareErr) ? fldTitle + SAF_l10n._ERRORMSG["COMPARE"] + document.getElementById(compareRule[1]).title.toLowerCase() :"\u00A0";
	
	this.messageHandler(isMultiple,vMessage);
	if (this.isError) {
		return 0;
	}
	return 1;
}

var beforeSubmit = false;
safHandler.prototype.validateAll = function(obj) {
	if (safObj.isCancel){return true;}
	var f = obj.target ? obj.target : obj.srcElement? obj.srcElement : obj;
	beforeSubmit = true;
	if (document.getElementById(f.id+"-backenderror")){
		var backenderror = document.getElementById(f.id+"-backenderror")
		backenderror.className = "dn";
		}
	var i;
	var containsErrors = 0;
	var flds = f.elements;
	for (i = flds.length; i != 0; i--) {
		var fld = flds[i-1];	
		if (typeof SAFTYPE[fld.type] == "undefined" || SAFTYPE[fld.type] == 0) continue;
		safObj.fld = fld;
		if (!safObj.validate()){containsErrors = 1;}
	}
	if (containsErrors) {
		 scrollTo(0,0);
		if(obj.target) cancelHref(obj);
		return false;
	}

	return true;
}

safHandler.prototype.doUnique = function(fld){
	var num= fld.id.substr(fld.id.length-1,1);
	var relatedFldId = "";
	if(fld.className.indexOf("UNIQUE-") != -1){
		var fldClass = fld.className.split(" ");
		for(var i=0; i< fldClass.length;i++){
			if(fldClass[i].indexOf("UNIQUE-") != -1){
				relatedFldId = "_"+fldClass[i].replace("UNIQUE-","");
			}
		}
	}
	while (document.getElementById(fld.id.replace(/\d/g,++num)) !=null) {
		var elem = document.getElementById(fld.id.replace(/\d/g,num));
		if(elem.value==fld.value){
			document.getElementById(elem.id+relatedFldId).value = "";
			elem.selectedIndex = 0;
		}
		var elemValue =elem.value;
		var newitem = 1;
		if(elem.type == "select-one" && fld.type == "select-one"){
			elem.options.length = 1;
			for(i=1;i<fld.options.length;i++){
				if(fld.options[i].value == fld.value ) continue;
				elem.options[newitem] = new Option(fld.options[i].text,fld.options[i].value);
				if(fld.options[i].value ==elemValue)
					elem.options[newitem].selected = true;
				newitem++;
			}
		}
		
	}
}
	

safHandler.prototype.validateMultiple = function(fld){
	var num= fld.id.substr(fld.id.length-1,1);
	var error = false, blank=0;
	for (var j = 0; j < n; j++) {
		var elem = document.getElementById(fld.id.replace(/\d/g,'') + j)
		if(elem.value==""){
			blank++;
			if(j>num && !beforeSubmit) continue;
			else {
				error = true;
			}
		}
		
		var validationRules = elem.className.split(' ');
		for (var i = validationRules.length; i != 0; i--) {
			
			var vRule = validationRules[i-1];
			if (vRule.indexOf("MASK") != -1 && elem.value!="") {
				var rule = vRule.replace("MASK","");
				
				if(!SAFRULE._MASK[rule].test(elem.value)) {
					error = true;
					break;
				}
			}
			if (vRule.indexOf("NUMLIMIT") != -1) {
				limitn = vRule.replace('NUMLIMIT','');
				if (elem.length != limitn) {
					error = true;
					break;
				}
			}
		}
	}
	
	var isRequired = (fld.className.indexOf("REQUIRED") != -1 && fld.className.indexOf('IF-') == -1) ? 1 : 0;
	if(blank == n)  error=false;
	return error;
}

safHandler.prototype.validateCompare = function(op,compareFld){
	var error;
	switch(op){
		case 'EQ' : error = (this.fld.value==this.fld.form[compareFld].value) ? 0 : 1;
					break;
		case 'NEQ' : error = (this.fld.value!=this.fld.form[compareFld].value) ? 0 : 1;
					break;
		case 'GT' : error = (this.fld.value>this.fld.form[compareFld].value) ? 0 : 1;
					break;
		case 'GET' : error = (this.fld.value>=this.fld.form[compareFld].value) ? 0 : 1;
					break;
		case 'LT' : error = (this.fld.value<this.fld.form[compareFld].value) ? 0 : 1;
					break;
		case 'LET' : error = (this.fld.value<=this.fld.form[compareFld].value) ? 0 : 1;
					break;
		default: error = 1;
	}
	return error;
}

safHandler.prototype.validateRequiredIf = function(dependencies) {
	var fld = this.fld;
	var depends = dependencies.split('-');
	var dependantField = document.getElementById(depends[0]);
	var dependantValue = depends[1];
	var actualValue = "";
	
	if(dependantField.type=="radio"){
		var radioFld = dependantField.form[dependantField.name];
		for(var i=0; i<radioFld.length; i++)
			if (radioFld[i].checked )
				actualValue = radioFld[i].value;
	} else if(dependantField.className.indexOf('HAS') != -1){
		var num=dependantField.className.substr(dependantField.className.indexOf('HAS')+3,1);
		for(i=0; i<num; i++)
			actualValue +=  document.getElementById(dependantField.id.replace(/\d/g,'') + i).value;
	}else actualValue = dependantField.value;
	
	if (actualValue == dependantValue || (dependantValue == "NOTNULL" && actualValue.length != 0) || (dependantValue == "NULL" && actualValue.length == 0)) {
		if (fld.value == "") return 0;
		return 1;
	}
	return 1;
}

safHandler.prototype.validateMask = function(maskId) {
	if (SAFRULE._MASK[maskId].test(this.fld.value)) { 
		return 1;
	}
	return 0;
}

safHandler.prototype.validateCharLimit = function(maxlength) {
	var fldValue = this.fld.value.replace(/^\s+/, '');
	fldValue = fldValue.replace(/\s+$/, '')
//	alert(this.fld.name+"="+fldValue.length);
	if (fldValue.length <= maxlength) return 1;
	return 0;
}

safHandler.prototype.validateChecked = function(obj) {
	for (var i = obj.length; i != 0; i--) if (obj[i-1].checked) return 1; 
	return 0;
}

/* SAF Message Handle, used for display information to the site visitor after a
 * a call the validate() method 
 */
safHandler.prototype.messageHandler = function(isMultiple,str){
	var fld = this.fld;
	
	var fldId = (isMultiple || fld.type == "radio") ? fld.id.replace(SAFRULE._MASK["DIGITS"],'') : fld.id;
	var elemMsg;
	var parentDL = getAncestorByTagName(fld,'dl');
	if (parentDL == null){
		parentDL= getAncestorByTagName(fld,'tr')
		if (parentDL != null)
			parentDL=parentDL.getElementsByTagName('th')[0];
		}
	if(parentDL){
		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(parentDL && parentDL.tagName.toLowerCase() != "th")
				parentDL.appendChild(elemMsg);
		}
		if (this.isError) {
			if (parentDL.className.indexOf('error') == -1) {
				parentDL.className += " error";
			}
		} else {
			parentDL.className = parentDL.className.replace("error","");
		}
		
		elemMsg.firstChild.nodeValue = str;
		
	}
}

/* SAF Event Handler Methods */
safHandler.prototype.setFocus = function(obj) {
	var fld = obj.target ? obj.target : obj.srcElement? obj.srcElement : obj;
	beforeSubmit = false;
	if (!fld.className) fld.className = "";
	var fldId = (fld.id)? fld.id : "";
	
	if( safObj.checkMultiple != "" && fldId.indexOf(safObj.checkMultiple.replace(SAFRULE._MASK["DIGITS"],'')) == -1 ){
		setTimeout("safObj.validate('"+safObj.checkMultiple+"')",300);
		}
	if (fld.className.indexOf('HAS') != -1){
		var num = fld.className.substr(fld.className.indexOf('HAS')+3,1);
		safObj.checkMultiple = fld.id.replace(SAFRULE._MASK["DIGITS"],num-1);
	} else safObj.checkMultiple = "";
	
	var waitToValidate = (fld.type == "radio" || fld.type == "checkbox" || (fld.className.indexOf('HAS') != -1)) ? 1 : 0;
//	if (waitToValidate && fld.id.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);
}

safHandler.prototype.setChange = function(obj) {
	safObj.fld = obj.target ? obj.target : obj.srcElement? obj.srcElement : obj;

	if (safObj.fld.type == "select-one") {
		if (safObj.fld.className.indexOf('POPULATE') != -1) {
			safObj.setOptions(fld);
		}
	}
}

safHandler.prototype.setClick = function(obj) {
	var fld = obj.target ? obj.target : obj.srcElement? obj.srcElement : obj;

	if (fld.type == "radio" || fld.type == "checkbox") {
		if (fld.className.indexOf('RELATEDFIELDSET') != -1) {
			safObj.setRelatedFieldset(fld);
		}
		if (fld.className.indexOf('POPULATE') != -1) {
			safObj.setOptions(fld);
		}
		if (fld.className.indexOf('TOGGLEOPTIONS') != -1) {
			safObj.selectedType(fld);
		}
		if (fld.className.indexOf('SETHIDDENFIELDS') != -1) {
			safObj.setDealerTypeHiddenFields(fld);
		}
	}
}

safHandler.prototype.setLoad = function(obj) {
	var fld = obj;
	if (fld.className.indexOf('RELATEDFIELDSET') != -1) {
		this.setRelatedFieldset(fld);
	}
}

safHandler.prototype.setRelatedFieldset = function(obj) {
	var fld = obj;
	var relatedFieldset = document.getElementById(fld.id + "-fieldset");

	if (fld.form[fld.name].length > 0) {
		for (var i = fld.form[fld.name].length; i != 0; i--) {
			relatedFieldset = document.getElementById(fld.form[fld.name][i-1].id + "-fieldset");
			if (relatedFieldset != null) {
			/** Matt to look at it **/
				relatedFieldset.className = (fld.form[fld.name][i-1].checked) ? "db" : "dn"; 
			}
		}
	} else {
		if (relatedFieldset != null) {
			relatedFieldset.className = (fld.checked) ? "db" : "dn"; 
		}
	}
}

var safObj;
var initSAF = new domFunction(function() {
		if (typeof safHandler == "function") {
			safObj = new safHandler();
			safObj.setSAF();
		}
	}, { 'int_content' : 'id' } );