	/*
validator.js
@author: Jordan CM Wambaugh jordan.wambaugh@forrent.com
@since: 01/12/07


usage:

define a rule for each element that must be validated with the addValidator() function:
addValidator(id,type,required,length)
where:
id - the id of the element
type - the type of data that goes in the field. valid values are text, number, email, day, month and year.
required - set to true if the field is required, or false if not required.
length - set to 0 if there is no required length, or set to the exact required length.


Once all the rules have been defined, run installValidationRules(); to activate the validator.

use validateSubmit(); to validate the entire form when the user hits submit.

example usage:

<form onsubmit="return validateSubmit();">
<input type="text" id="test"><br />
</form>
<script type="text/javascript">
addValidator('test','email',true,0);
installValidationRules();
</script>



*/

//this is our global array of validationElement objects.
var _elements;


//our elementRule class
function elementRule(id,type,required,length){
	this.id=id;
	this.type=type;
	this.required=required;
	this.length=length;
	this.flagged=0;
}





//this function adds a new validation rule.
function addValidator(id,type,required,length){

	if(!$(id)){return;}
	if(_elements){
		_elements=_elements.concat(new elementRule(id,type,required,length));
	}else{
		_elements=new Array(new elementRule(id,type,required,length));
	}

}
function clearValidator(){
	_elements=null;
}


//this function installs the onchange handlers to each element
function installValidationRules(){
	var x;
	var len=_elements.length;
	for(x=0;x<len;x++){

		$(_elements[x].id).onblur=function(){validate(this)};
	}
}

//this function performs the actual validation on an element
function validate(element){
	//alert(element.id);

	var x;
	var len=_elements.length;
	//find the rule for this element
	for(x=0;x<len;x++){
		if(_elements[x].id==element.id){
			element.value=trim(element.value);
			//if its a required field, but we have nothing
			if(_elements[x].required==true && isEmpty(element.value)){
				highlightElement(_elements[x].id);
				if(_elements[x].flagged!='required'){alert("This is a required field. Please enter a value");}
				_elements[x].flagged='required';
			}
			//if there is a required length, but it doesn't match
			else if(_elements[x].length!=0 && _elements[x].length!=element.value.length && element.value.length>0){
				highlightElement(_elements[x].id);
				if(_elements[x].flagged!='length'){alert("This field must be exactly "+_elements[x].length+" characters long. Please enter a valid value.");}
				_elements[x].flagged='length';
			}

			//if it has to be a number, then check for that
			else if(_elements[x].type=='number' && !isNumeric(element.value) && element.value.length>0){
				highlightElement(_elements[x].id);
				if(_elements[x].flagged!='number'){alert("This field must contain only numbers. Please enter only a number here.");}
				_elements[x].flagged='number';
			}

			//if it is an email, then check for that.
			else if(_elements[x].type=='email' && !isValidEmail(element.value) && element.value.length>0){
				highlightElement(_elements[x].id);
				if(_elements[x].flagged!='number'){alert("This field must contain only valid email addresses. \nPlease enter a valid email address.");}
				_elements[x].flagged='number';
			}
			//if it is a day, then check for that.
			else if(_elements[x].type=='day'){
				// we have to trim leading zeros in element.value
				// parseInt('08') and parseInt('09') will give us 0 it we won't trim				
				var dateval = parseInt(element.value * 1);								
				if (dateval > 31 || dateval < 1){
					highlightElement(_elements[x].id);
					if(_elements[x].flagged!='day'){alert("This field must contain only valid day of the month. \nPlease enter a valid day.");}
					_elements[x].flagged='day';
				}else{
					resetHighlight(_elements[x].id);
					_elements[x].flagged=0;
				}
			}
			//if it is a month, then check for that.
			else if(_elements[x].type=='month'){
								
				var monthval = parseInt(element.value * 1);								

				if (monthval > 12 || monthval < 1){
					highlightElement(_elements[x].id);
					if(_elements[x].flagged!='month'){alert("This field must contain only valid month. \nPlease enter a valid month.");}
					_elements[x].flagged='month';
				}else{
					resetHighlight(_elements[x].id);
					_elements[x].flagged=0;
				}
			}
			//if it is a year, then check for that.
			else if(_elements[x].type=='year'){
				var yearval = parseInt(element.value);				
				var dateObj = new Date();
				var curyear = dateObj.getFullYear();				
				if (yearval < curyear || yearval > (curyear + 100)){
					highlightElement(_elements[x].id);
					if(_elements[x].flagged!='year'){alert("This field must contain only valid year. \nPlease enter a valid year.");}
					_elements[x].flagged='year';
				}else{
					resetHighlight(_elements[x].id);
					_elements[x].flagged=0;
				}
			}
			//if it is a phone number, then check for that.
			else if(_elements[x].type=='phone' && element.value.length>0){
				var objRegExp  = /^\(?[1-9]\d{2}\)?\s?\-?\d{3}\-?\s?\d{4}$/;
				if (!objRegExp.test(element.value)){
					highlightElement(_elements[x].id);
					if(_elements[x].flagged!='phone'){alert("This field must contain only valid phone number. Please enter only a valid phone number here.");}
					_elements[x].flagged='phone';
				}else{
					resetHighlight(_elements[x].id);
					_elements[x].flagged=0;
				}	
			}
			//if it is a phone vanity url, then check for that.
			else if(_elements[x].type=='vanity' && element.value.length>0){
				var objRegExp  = /^[a-zA-Z0-9\$\.\+\!\*\'()]*$/;
				if (!objRegExp.test(element.value)){
					highlightElement(_elements[x].id);
					if(_elements[x].flagged!='vanity'){alert("This field must contain only valid vanity url.Please enter a valid vanity url. Allowed characters: A-z 0..9 $ _ - . + ! * ' ( )");}
					_elements[x].flagged='vanity';
				}else{
					resetHighlight(_elements[x].id);
					_elements[x].flagged=0;
				}	
			}
			else {
				resetHighlight(_elements[x].id);
				_elements[x].flagged=0;
			}
		}
	}
}


//runs through each field and
function validateSubmit(){
	var x;
	var flagged=0;
	var len=_elements.length;
	//find the rule for this element
	for(x=0;x<len;x++){
		validate($(_elements[x].id));
		if(_elements[x].flagged!=0){
			flagged++;
		}
	}
	if(flagged){
		alert("There are " + flagged + " fields that contain errors on this page. \nPlease fix them before you submit.");
		return(false);
	}
	else{
		enableAllFields();
		return(true);
	}
}

function highlightElement(id){
	new Effect.Highlight(id, {startcolor:'#FF0000'});
	$(id).style.background='#FF9999';
}

function resetHighlight(id){
	$(id).style.background='#FFFFFF';
}

//this is ahandy debug function to display all our
function showValidators(){
	var x;
	var len=_elements.length;
	for(x=0;x<len;x++){
		alert("id: '"+_elements[x].id+"' Type: '"+_elements[x].type+"' Required: "+_elements[x].required);
	}
}


function isNumeric(sText)

{
	var ValidChars = "0123456789.";
	var IsNumber=true;
	var Char;


	for (i = 0; i < sText.length && IsNumber == true; i++)
	{
		Char = sText.charAt(i);
		if (ValidChars.indexOf(Char) == -1)
		{
			IsNumber = false;
		}
	}
	return IsNumber;

}

function isEmpty(string) {
	if ((string.length==0) ||  (string==null)) {
		return true;
	}
	else { return false; }
}

function isValidEmail(str) {

	return (str.indexOf(".") > 0) && (str.indexOf("@") > 0);

}

// Removes leading whitespaces
function LTrim( value ) {

	var re = /\s*((\S+\s*)*)/;
	return value.replace(re, "$1");

}

// Removes ending whitespaces
function RTrim( value ) {

	var re = /((\s*\S+)*)\s*/;
	return value.replace(re, "$1");

}

// Removes leading and ending whitespaces
function trim( value ) {

	return LTrim(RTrim(value));

}



function enableAllFields(){
	var x;
	for(x=0;x<document.forms[0].elements.length;x++){
		if(document.forms[0].elements[x].disabled==true){
			document.forms[0].elements[x].disabled=false;
			
		}
	}
}

/***********************************************
* Textarea Maxlength script- ? Dynamic Drive (www.dynamicdrive.com)
* This notice must stay intact for legal use.
* Visit http://www.dynamicdrive.com/ for full source code
***********************************************/

function ismaxlength(obj){
	var mlength=obj.getAttribute? parseInt(obj.getAttribute("maxlength")) : ""
    if (obj.getAttribute && obj.value.length>mlength)
    obj.value=obj.value.substring(0,mlength)
}
