var VAL_REQUIRED = 0;
var VAL_CELLPHONE = 1;
var VAL_EMAIL = 2;

var validationFields = new Array();
var pageValidators = new Array();
var errorList;
var pageErrorList;
var errorsOnTop = true;
var ajaxValidationCount;
var hasError;

var formSubmitting = false;

function doValidate(form){
	if(formSubmitting) return false;
	startProcessing();
	if(!form)
		form = document.forms[0];

	if(!form.id)
		form.id="validationForm";
	hasError = false;
	ajaxValidationCount = 0;
	errorList = new Array();
	pageErrorList = new Array();
	var hasAjax = false;
	for(var i=0;i<pageValidators.length;i++){
		pageValidators[i]();
	}
	for(var i=0;i<validationFields.length;i++){
		validationFields[i].message=null;
		validationFields[i].ajaxValidators=0;
		validationFields[i].validate();
		if(validationFields[i].ajaxValidators>0){
			ajaxValidationCount += validationFields[i].ajaxValidators;
			hasAjax = true;
		}
	}
	if(hasError && !hasAjax) {
		showAllErrors();
	} else
		$("#errors").hide();
	if(!hasAjax){
		return !hasError;
	}else{
		checkError(form);
		return false;
	}
}

function startProcessing(){
	formSubmitting = true;
	disableAllButtons();
}

function endProcessing(){
	formSubmitting = false;
	enableAllButtons();
}

function disableAllButtons(){
	var input = document.getElementsByTagName("input");
	if(input.length){
		for(var i=0;i<input.length;i++){
			if(input[i].type=="button" || input[i].type=="submit"){
				input[i].style.color = "gray";
			}
		}
	}
}

function enableAllButtons(){
	var input = document.getElementsByTagName("input");
	if(input.length){
		for(var i=0;i<input.length;i++){
			if(input[i].type=="button" || input[i].type=="submit"){
				input[i].style.color = "white";
			}
		}
	}
}

function checkError(form){
	if(!form)
		form = document.forms[0];
	if(ajaxValidationCount==0){
		if(!hasError)
			ajaxValidationSuccess(form);
		else
			showAllErrors();
	}else{
		setTimeout("checkError(document.getElementById('"+ form.id +"'));",100);
	}
}

function ajaxValidationSuccess(form){
	form.submit();
}

function showAllErrors(){
	if(ajaxValidationCount==0 && (pageErrorList.length>0 || errorList.length>0)){
		var errorText = "Errors encountered below. Please correct before proceeding.<br>";
		if(errorsOnTop){
			for(var i=0;i<pageErrorList.length;i++){
				errorText = errorText + "<br><span class='errorMessage'>"+pageErrorList[i]+"</span>";
			}
			for(var i=0;i<errorList.length;i++){
				var field = errorList[i];
				errorText = errorText + "<br><a class='errorMessage' href='javascript:document.getElementById(\""+field.id+"\").focus();'>"+field.message+"</a>";
			}
		}
		$("#errors").html(errorText);
		
		$("#errors").show();
		window.scrollTo(0,0);
		endProcessing();
	}
}

function addValidationField(id){
	var field = document.getElementById(id);
	validationFields[validationFields.length] = field; 
	field.label = field.getAttribute("label");
	if(field.label=="")
		getLabel(field);
	field.validate = field_validate;
	field.errorField = $("#v_"+id);
	field.showError = showFieldError;
	field.hideError = hideFieldError;
	field.message = "";
	field.error = false;
	field.validators = new Array();
	field.addValidator = field_addValidator;
	field.addAjaxValidator = field_addAjaxValidator;
	field.addValidatorByType = field_addValidatorByType;
	if(field.getAttribute("required")=="true"){
		field.addValidatorByType(VAL_REQUIRED);
	}
	field.setError = field_setError;
	field.setAjaxError = field_setAjaxError;
	field.ajaxValidators = 0;
}

function getLabel(field){
	return;
	try{
	field.label = field.parentNode.parentNode.getElementsByTagName("label")[0].innerHTML.replace(":","");
	}catch(e){
		field.label = "";
	}
}

function addPageValidator(validatorFunction){
	pageValidators[pageValidators.length] = validatorFunction;
}

function addValidator(id,validatorFunction){
	document.getElementById(id).addValidator(validatorFunction);
}

function addAjaxValidator(id,validatorFunction){
	document.getElementById(id).addAjaxValidator(validatorFunction);
}

function addValidatorByType(id,type){
	document.getElementById(id).addValidatorByType(type);
}

function field_addValidatorByType(type){
	var validatorFunction;
	switch(type){
		case VAL_REQUIRED:
			validatorFunction = doValidateRequired;
			break;
		case VAL_CELLPHONE:
			validatorFunction = doValidateCellphone;
			break;
		case VAL_EMAIL:
			validatorFunction = doValidateEmail;
			break;
		default: break;
	}

	this.addValidator(validatorFunction);
}

function field_addValidator(validatorFunction){
	this.validators[this.validators.length] = validatorFunction;
}

function field_addAjaxValidator(validatorFunction){
	this.validators[this.validators.length] = validatorFunction;
}

function field_setAjaxError(message){
	if(message!="")
		this.setError(message);
	ajaxValidationCount--;
	showAllErrors();
}

function field_setError(message){
	if(!this.message || this.message==""){
		this.message = message;
		this.error = true;
		hasError = true;
		this.showError();
	}
}

function setPageError(message){
	pageErrorList[pageErrorList.length] = message;
	hasError = true;
}


function showFieldError(){
	if(this.className.indexOf("error")<0)
		this.className=this.className + " error";
	if(errorsOnTop){
		var fieldIncluded=false;
		for(var i=0;i<errorList.length;i++){
			if(errorList[i].id==this.id)
				fieldIncluded = true;
		}
		if(!fieldIncluded)
			errorList[errorList.length]=this;
	}else{
		this.errorField.text(this.message);
		this.errorField.show();
	}
}

function hideFieldError(){
	this.className=this.className.replace("error","");
	if(!errorsOnTop){
		this.errorField.text("");
		this.errorField.hide();
	}
}

function field_validate(){
	this.error = false;
	for(var i=0;i<this.validators.length;i++){
		// call the validator
		this.validators[i](this);
	}
	if(!this.error){
		this.hideError();
	}
}

function ajaxValidate(validationFunction,field, params){
	field.ajaxValidators++;
	$.ajax({
        url: validationFunction,
        dataType: "text",
        data: params,
        cache: false,
        success:function(text){field.setAjaxError(text);}
        });
}



/***
Validators
***/

function doValidateRequired(field){
	if(field.value == ""){
		var msg = "This is a required field.";
		if(field.label && field.label!="")
			msg = field.label +" is a required field.";
		field.setError(msg);
	}
}

function doValidateCellphone(field){
	var strippedValue = field.value;
	strippedValue = strippedValue.replace(/\(/g,"")
	strippedValue = strippedValue.replace(/\)/g,"")
	strippedValue = strippedValue.replace(/\-/g,"")

	if(field.value=="") {
	}else if(!/^[\d(,\d),\d-]*$/.test(field.value)){
		field.setError("Value should only contain numeric characters, '(', ')', and '-'");
	}else if(strippedValue.length != 10){
		field.setError("Number must be 10 digits");
	}
}

function doValidateEmail(field){
	var filter = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;
	if(field.value==""){
	}else if (!filter.test(field.value.trim())) {
		field.setError("Invalid e-mail address");
	}
}

function doValidateRadioRequired(field){
	if(!field.checked){
		var msg = "This is a required field.";
		if(field.label && field.label!="")
			msg = field.label +" is a required field.";
		field.setError(msg);
	}
}
