// Misc Functions
includeOnce("/javascript/cookies.js");
includeOnce("/javascript/validators.js");  // should automatically include textformat.js
includeOnce("/javascript/events.js");
includeOnce("/javascript/css.js");
includeOnce("/javascript/formvalidator.css");
includeOnce("/javascript/clock.js");


var firstInvalidElement=null;

function attachValidators() {
	forms = document.forms;
	
	for(var i=0;i<forms.length;i++) {
		attachValidators_Form(forms[i]);
	}
}

function attachValidators_Field(fieldObj) {
	f = getAttributes(fieldObj);	
		
	// quit function if there is nothing to do;
	if(!f.required && !f.validate) return;
	
	if(!isAffirmative(fieldObj.getAttribute("delayValidation")) && (f.type=='text' || f.type=='checkbox' || f.type=='textarea' || f.type.indexOf('select')>=0 )) {
		eventFunc = function (e) { validateField(getElementFromEvent(e)); };
		addEvent(fieldObj, 'change',eventFunc);
		addEvent(fieldObj, 'blur',eventFunc);
	}
	
	if(f.type!='text') return;
	
	if(f.validate=='date'||f.validate=='birthday') {
		fieldObj.setAttribute('autocomplete','off');
		includeOnce("/javascript/calendar.js");
		includeOnce("/javascript/calendar-blue.css");
	}
	
	if(f.validate=='time') {
		fieldObj.setAttribute('autocomplete','off');
		appendClockEvent(fieldObj);
	}
	
	if((f.validate=='date' || f.validate=='birthday') && isFunction("Calendar.setup")) {
		dateFunction = "dateFunc = function(date) { ";
		dateFunction += " try { ";
		dateFunction += "var minDate, maxDate; "
		if(f.minDate) {
			minDate = new Date(FormatDate(f.minDate));
			if(minDate!="Invalid Date")	{
				dateFunction += "minDate=new Date('" + minDate + "'); ";	
				dateFunction += "if(minDate > date) return true; ";
			}
		}
		if(f.maxDate) {
			maxDate = new Date(FormatDate(f.maxDate));
			if(maxDate!="Invalid Date")	{
				dateFunction += "maxDate=new Date('" + maxDate + "'); ";	
				dateFunction += "if(maxDate < date) return true; ";
			}
		}
		if(f.invalidWeekdays) {
			dateFunction += "if('"+f.invalidWeekdays+"'.indexOf(date.getDay())>-1) return true; ";
		}
		dateFunction += " } catch(e) {} ";
		dateFunction += " return false;}";
		eval(dateFunction);
		try{
		Calendar.setup({
			elem    	   :    fieldObj,     // the input field
			ifFormat       :    "%Y-%m-%d",     // format of the input field (even if hidden, this format will be honored)
			cache          :    true,
			weekNumbers	   :    false,
			singleClick    :    true,	
			dateStatusFunc :    dateFunc
		}); } catch(e) {}
	}	

}

function attachValidators_Form(formObj) {
	// if the validate attribute isn't true then don't continue with this form.
	if(!isAffirmative(formObj.getAttribute("validate"))) return;
	//console.log(formObj);
	
	// attach onSubmit stuff
	eventFunc = function (e) { 
		if(typeof e=='undefined') return false;
		if(!validateForm(getElementFromEvent(e))) {
			e.returnValue=false; 
			if(typeof e.preventDefault!='undefined') {e.preventDefault();} 
		}
	}

	addEvent(formObj, 'submit',eventFunc);
	
	// attach validators to individual fields
	for(var i=0;i<formObj.length;i++) {
		if(formObj[i].tagName=="FIELDSET") {
			for(var j=0;j<formObj[i].length;j++) {
				attachValidators_Field(formObj[i][j]);
			}
		} else {
			attachValidators_Field(formObj[i]);
		}
	}
}

function changeFieldStyle(fieldObj,fIsValid) {
	var tempIDname, warning;
	f = getAttributes(fieldObj);
	tempIDname=fieldObj.form.getAttribute("name") + "19" + f.type + "84" + f.name;	
	if(!fIsValid) {
		CSS.addClass(fieldObj,f.boxClass);
		if(fieldObj.disabled==false) CSS.addClass(fieldObj,f.boxClass+"BG");
		
		if(f.message!=null && f.message.length>1) {
			if(!document.getElementById(tempIDname)) {
				warning=document.createElement("span");
				warning.id=tempIDname;				
				CSS.addClass(warning,f.messageClass);
				fieldObj.parentNode.insertBefore(warning,fieldObj);
			} else { warning=document.getElementById(tempIDname); }
			warning.style.display="inline";
			CSS.addClass(fieldObj,"MSMTopMargin");
			warning.innerHTML=f.message;
		}
	} else {
		CSS.removeClass(fieldObj,f.boxClass);
		CSS.removeClass(fieldObj,f.boxClass+"BG");
		CSS.removeClass(fieldObj,"MSMTopMargin");
		if(document.getElementById(tempIDname)) {
			warning=document.getElementById(tempIDname);
			warning.style.display="none";
			warning.innerHTML="";				
		}
	}
}

function formatFieldValue(formField) {
	var fFormat, fType, fValidate, tempVal=null;
	fFormat=formField.getAttribute("format");
	if(fFormat==null) fFormat="true";
	fType=formField.getAttribute("type");
	fValidate=formField.getAttribute("validate");
	if((fFormat=='yes' || fFormat=='true') && (fType==null || fType=='text') && fValidate!=null && isFunction("to" + fValidate)) {
		tempVal=window["to"+fValidate](formField.value);
		if(tempVal!=null && tempVal.length>0) formField.value=tempVal;
	}
}

function getAttributes(fieldObj) {
	// create a new object with the field attributes
	f = new Object();
	
	// get the initial data
	f.autosuggest=			fieldObj.getAttribute("autosuggest");
	f.boxClass=				fieldObj.getAttribute("boxClass");
	f.callback=				fieldObj.getAttribute("callback");
	f.invalidWeekdays=		fieldObj.getAttribute("invalidWeekdays");
	f.format = 				isAffirmative(fieldObj.getAttribute("format"));						
	f.mask=					fieldObj.getAttribute("mask");	
	f.maxDate=				fieldObj.getAttribute("maxdate");
	f.maxLength=			fieldObj.getAttribute("maxlength");	
	f.maxTime=				fieldObj.getAttribute("maxtime");
	f.maxWords=				fieldObj.getAttribute("maxwords");
	f.minDate=				fieldObj.getAttribute("mindate");
	f.minLength=			fieldObj.getAttribute("minlength");
	f.minTime=				fieldObj.getAttribute("mintime");
	f.minWords=				fieldObj.getAttribute("minwords");
	f.message=				fieldObj.getAttribute("message");
	f.messageClass=			fieldObj.getAttribute("messageClass");
	f.name = 				fieldObj.getAttribute("name");
	f.pattern=				fieldObj.getAttribute("pattern");
	f.range=				fieldObj.getAttribute("range");
	f.required=				isAffirmative(fieldObj.getAttribute("required"));
	f.toolTip=				fieldObj.getAttribute("tooltip");	
	f.type=					fieldObj.getAttribute("type");								
	f.validate=				fieldObj.getAttribute("validate");
	f.valid=				isAffirmative(fieldObj.getAttribute("valid"));
	f.value=				fieldObj.value.replace(/^\s*|\s*$/g, "");
	

	// correct the attributes
	if(f.autosuggest==null) f.autosuggest=false;
	if(!f.boxClass || !(f.boxClass.length>0)) f.boxClass="MSMErrorInputBox";
	if(f.callback==null) f.callback=false;
	if(f.invalidWeekdays==null) f.invalidWeekdays=false;
	if(f.format==null) f.format=true;
	if(f.mask==null) f.mask=false;
	if(f.maxDate==null) f.maxDate=false;
	if(f.maxLength==null) f.maxLength=false;
	if(f.maxTime==null) f.maxTime=false;
	if(f.maxWords==null) f.maxWords=false;
	if(!f.messageClass || !(f.messageClass.length>0)) f.messageClass="MSMFormWarning";
	if(f.minDate==null) f.minDate=false;
	if(f.minLength==null) f.minLength=false;
	if(f.minTime==null) f.minTime=false;
	if(f.minWords==null) f.minWords=false;
	if(f.name==null)	f.name=false;
	if(f.range==null) f.range=false;
	if(f.range) { 
		f.range=f.range.split(",");
		if(f.range[0]!=null) f.min=f.range[0];
		if(f.range[1]!=null) f.max=f.range[1];
		if(f.min.length==0) f.min=false;
		if(f.max.length==0) f.max=false;
	}
	if(f.type==null || f.type.length==0 || f.type=="textarea" || f.type=="file") f.type="text";
	if(f.validate==null && f.pattern!=null) f.validate="regex";
	if(f.validate==null) f.validate=false;
	f.value=f.value.replace("'","\\'");
	if(!f.value.length>0) f.value=false;
	return f;
}

function insertAfter(insert,refNode){
	try {
		if(refNode.nextSibling)
			refNode.parentNode.insertBefore(insert, refNode.nextSibling);
		else
			refNode.parentNode.appendChild(insert);
	} catch(e) {
		refNode.parentNode.appendChild(insert);
	}
}

function isAffirmative(obj) {
	if(obj==null) return null;	
	if(obj=="false" || obj=="no" || obj<=0) return false;
	if(obj=="true" || obj=="yes" || obj==1 || obj==true || obj=="True" || obj=="Yes" ) return true;
	return null;
}

function isValidForm(formObj) {
	if(typeof formObj === 'string')	formObj = document[formObj];
	var formPasses = true;
	firstInvalidElement=null;
	
	if(formObj==null || formObj.length==0) return false;
	
	// Cycle through all form fields checking and correcting as we go
	for(var i=0;i<formObj.length;i++) {
		if(formObj[i].tagName=="FIELDSET") {
			for(var j=0;j<formObj[i].length;j++) {
				if(!isValidField(formObj[i][j])) {
					if(firstInvalidElement==null) firstInvalidElement=formObj[i][j];
					formPasses=false; 
				}
			}
		} else {
			if(!isValidField(formObj[i])) {
				if(firstInvalidElement==null) firstInvalidElement=formObj[i];
				formPasses=false; 
			}
		}
	}
	
	return formPasses;
}

function isValidField(fieldObj) {
	var f = getAttributes(fieldObj);
	if(f.type=="submit" || f.type=="button" || f.type=="reset" || f.type=="hidden") return true;
	if(f.valid==false) return false;
	if(f.type=="text") {
		if(!f.value) { if(f.required) return false; return true; }

		if(f.pattern && !isRegex(f.value,f.pattern)) return false; 
		if(f.validate && f.validate!="regex" && isFunction("is" + f.validate) && !window["is" + f.validate](f.value)) return false;
		
		if(f.min && f.min>parseFloat(f.value)) return false;
		if(f.max && f.max<parseFloat(f.value)) return false;

		if(f.minLength && f.minLength>f.value.length) return false;
		if(f.maxLength && f.maxLength<f.value.length) return false;
		if(f.minWords && parseInt(f.minWords)>wordCount(f.value)) return false;
		if(f.maxWords && parseInt(f.maxWords)<wordCount(f.value)) return false;

		// Minimum Date Check
		if((f.validate=='date'||f.validate=='birthday') && f.minDate) {
			minDate = new Date(FormatDate(f.minDate,"F d, Y"));
			f.value = new Date(FormatDate(f.value,"F d, Y"));
			if(f.value!="Invalid Date" && minDate!="Invalid Date" && f.value < minDate) return false;
		}
		
		if((f.validate=='date'||f.validate=='birthday') && f.maxDate) {
			maxDate = new Date(FormatDate(f.maxDate,"F d, Y"));
			f.value = new Date(FormatDate(f.value,"F d, Y"));
			if(f.value!="Invalid Date" && maxDate!="Invalid Date" && f.value > maxDate) return false;
		}

		if((f.validate=='date'||f.validate=='birthday') && f.invalidWeekdays) {
			f.value = new Date(FormatDate(f.value,"F d, Y"));
			if(f.invalidWeekdays.indexOf(f.value.getDay())>-1) return false;
		}
	} else if(f.type=='checkbox') {
		if(!f.required) return true;
		tempElement=fieldObj.form[f.name];
		if(tempElement.length && tempElement.length>1) {
			if(!optionIsSelected(tempElement)) return false;			
		} else {
			if(!fieldObj.checked) return false;
		}
	} else if(f.type=='radio') {
		if(!f.required) return true;
		tempElement=fieldObj.form[f.name];
		if(!optionIsSelected(tempElement))  return false;
	} else {
		if(!f.required) return true;
		if(!f.value || f.value.length==0)  return false;
	}
	return true;
}

function validateField(fieldObj) {
	var fieldPasses = true;
	// See if there is a validation function for the given type and use it if found
	fIsValid = isValidField(fieldObj);

	// See if there is a formatting function for the given type and use it if found	
	if(fIsValid) {
		var t = isAffirmative(fieldObj.getAttribute("format"));
		if(t==null || t) formatFieldValue(fieldObj); 
	} else {

		if(firstInvalidElement==null) firstInvalidElement=fieldObj;
		fieldPasses=false; 
	}

	// Format the styles based on whether it passed validation
	changeFieldStyle(fieldObj,fIsValid);	
	return fieldPasses;
}

function validateForm(formObj) {
	if(typeof formObj === 'string')	formObj = document[formObj];
	var fIsValid,fType,fValue,fFormat;
	var formPasses = true;
	firstInvalidElement=null;
	
	if(formObj==null || formObj.length==0) return false;
	
	// Cycle through all form fields checking and correcting as we go
	for(var i=0;i<formObj.length;i++) {
		if(formObj[i].tagName=="FIELDSET") {
			for(var j=0;j<formObj[i].length;j++) {
				if(!validateField(formObj[i][j])) {formPasses=false; }
			}
		} else {
			if(!validateField(formObj[i])) {formPasses=false; }
		}
	}	
	
	if(firstInvalidElement!=null) try{firstInvalidElement.focus();}catch(err){}
	return formPasses;
}

formIsValid=validateForm;

addEvent(window, 'load', attachValidators);
addEvent(window, 'unload', EventCache.flush);
