/**
 * This class produces as-you-type validation as well as on-submit validation for forms
 * Fields with words like 'validateEmail' in their class names will be 
 * validated according to certain predefined formats.
 * Fields with the word 'required' in their class names must be filled.
 * Inputs without valid data will be given the CSS class 'field_error'.
 * If 'useErrorElement is passed as true, 
 * divs named after the IDs of the inputs, followed by 'RequiredError' or
 * 'FormatError', will be made visible when problems arise.
 *  To match the value of one field against another, add the class "match" and the name of the other field you are matching against.
 *
 *  To have a message appear if there are any errors,add a div id="anyError" class="error"
 *
 * if the useKeyUp parameter is set to true, form validation will happen as the user types, otherwise validation happens on submit
 * if useErrorElement is set to true, a text error message will appear. Use the css class "error" for this text 9will display as bold red and be hidden at first)
 *
 **/
function KeyupValidator(formId, useKeyup, useErrorElement){
	this.form = document.getElementById(formId);
	this.inputs = new Array();
	for (i = 0; i < this.form.elements.length; i++)
	{
		//this.attachInputKeyEvents(this.form.elements[i]);
		if(this.form.elements[i].tagName != 'FIELDSET'){
			this.inputs.push(new KeyupValidatorInput(this.form, this.form.elements[i], useKeyup, useErrorElement));
		}
	}
	YAHOO.util.Event.addListener(this.form, 'submit', this.validateForm, this, true);
}

KeyupValidator.prototype.validateForm = function()
{
	var thisElement;
	this.isValid = true;
	//loop through the elements of the form
	for (i = 0; i < this.inputs.length; i++)
	{
		if(!this.inputs[i].validate()){
			this.isValid = false;
		}
	}
	return this.isValid;
}

function KeyupValidatorInput(form, element, useKeyup, useErrorElement){
	//document.title += 'i';
	this.parentForm = form;
	this.element = element;
	this.useKeyup = useKeyup;
	this.useErrorElement = useErrorElement;
	this.timeoutDuration = 2000;
	if(this.useKeyup){
		this.attachKeyEvents();
	}
	//alert(this.element.tagName);
}
KeyupValidatorInput.prototype =
{
	attachKeyEvents: function(element){
		//document.title += 'a';
		YAHOO.util.Event.addListener(this.element, 'keyup', this.keyup, this, true);
	},
	keyup: function(element){
		clearTimeout(this.validateTimeout);
		var timeoutObject = this;
		this.validateTimeout = setTimeout(function(){
				timeoutObject.validate();
				}, this.timeoutDuration);
	},
	/**
	 * If we show the error state, we ought to start checking for 
	 * correctness with no perceivable delay, so the user is 
	 * gratified when they get it right
	 **/
	showError: function(){
		this.timeoutDuration = 100;
		YAHOO.util.Dom.addClass(this.element, 'field_error');
	},
	/**
	 * If we hide the error state, we ought to give the user
	 * some time to type before showing an error again
	 **/
	hideError: function(){
		this.timeoutDuration = 2000;
		YAHOO.util.Dom.removeClass(this.element, 'field_error');
	},
	
	
	validate: function(){

				
 		if (this.element.type == "checkbox") {
			if (this.element.className.indexOf('required') > -1 && !this.element.checked) {
				this.showError();
				try
				{
					if(this.useErrorElement){
						document.getElementById(this.element.name + 'RequiredError').style.display = 'block';
						if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
					}
				}
				catch (e)
				{
					//they don't have an error div for this
				}
				return false;
			}
			
			this.hideError();
			return true;
		}
				

		if (!(this.element.value.replace(/\s/g, '').length > 0))
		{
			if (this.element.className.indexOf('required') > -1)
			{
				this.showError();
				try
				{
					if(this.useErrorElement){
						document.getElementById(this.element.name + 'RequiredError').style.display = 'block';
						if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
					}
				}
				catch (e)
				{
					//they don't have an error div for this
				}
				return false;
			}
			//don't validate the format of empty fields
			this.hideError();
			return true;
		}
		
		if (this.element.className.indexOf('validate') > -1)
		{
			//matches the value of 2 fields
			if (this.element.className.indexOf('validateMatch') > -1)
			{
				var classes = this.element.className;
				var classArray = classes.split(" ");
				for (var i = 0; i < classArray.length; i++) {
					var aClass = classArray[i];
					for (n = 0; n < this.parentForm.elements.length; n++) {
						if (this.parentForm.elements[n].name == aClass) {
							if (this.parentForm.elements[n].value != this.element.value) {
								this.showError();
								
								try
								{
									if(this.useErrorElement){
										document.getElementById(this.element.name + 'MatchError').style.display = 'block';
										if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
									}
								}
								catch (e)
								{
									//they don't have an error div for this
								}
								return false;
							}
							document.getElementById(this.element.name + 'MatchError').style.display = 'none';
						}
					}
				}
			}

			if (this.element.className.indexOf('validateEmail') > -1)
			{
				if(!this.element.value.replace(/^\s+|\s+$/g,'')  != ''){
					if (!this.element.value.match(/^[_a-zA-Z0-9-]+(\.[_a-zA-Z0-9-]+)*@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.(([0-9]{1,3})|([a-zA-Z]{2,3})|(aero|coop|info|museum|name))$/))
					{
						this.showError();
						try
						{
							if(this.useErrorElement){
								document.getElementById(this.element.name + 'FormatError').style.display = 'block';
								if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
							}
							
						}
						catch (e)
						{
							//they don't have an error div for this
						}
						return false;
					}
				}
			}
			else if (this.element.className.indexOf('validateUsername') > -1)
			{
				if (!this.element.value.match(/^[a-zA-Z0-9\-\_]{4,20}$/))
				{
					this.showError();
					try
					{
						if(this.useErrorElement){
							document.getElementById(this.element.name + 'FormatError').style.display = 'block';
							if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
						}
					}
					catch (e)
					{
						//they don't have an error div for this
					}
					return false;
				}
			}
			else if (this.element.className.indexOf('validateName') > -1)
			{
				if (!this.element.value.match(/^[a-zA-Z\-\s\']{1,40}$/))
				{
					this.showError();
					try
					{
						if(this.useErrorElement){
							document.getElementById(this.element.name + 'FormatError').style.display = 'block';
							if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
						}
					}
					catch (e)
					{
						//they don't have an error div for this
					}
					return false;
				}
			}
			else if (this.element.className.indexOf('validatePassword') > -1)
			{
				if (!this.element.value.match(/^[a-zA-Z0-9\-\_]{4,20}$/))
				{
					this.showError();
					try
					{
						if(this.useErrorElement){
							document.getElementById(this.element.name + 'FormatError').style.display = 'block';
							if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
						}
					}
					catch (e)
					{
						//they don't have an error div for this
					}
					return false;
				}
			}
			else if (this.element.className.indexOf('validateZipCode') > -1)
			{
				if (!this.element.value.match(/^[0-9]{5,5}$/))
				{
					this.showError();
					try
					{
						if(this.useErrorElement){
							document.getElementById(this.element.name + 'FormatError').style.display = 'block';
							if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
						}
					}
					catch (e)
					{
						//they don't have an error div for this
					}
					return false;
				}
			}
			else if (this.element.className.indexOf('validateImageFilename') > -1)
			{
				if (!this.element.value.match(/(jpg|jpeg|png|gif)$/i))
				{
					this.showError();
					try
					{
						if(this.useErrorElement){
							document.getElementById(this.element.name + 'FormatError').style.display = 'block';
							if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
						}
					}
					catch (e)
					{
						//they don't have an error div for this
					}
					return false;
				}
			}
			else if (this.element.className.indexOf('validateLength300') > -1)
			{
				if (this.element.value.length > 300)
				{
					this.showError();
					try
					{
						if(this.useErrorElement){
							document.getElementById(this.element.name + 'FormatError').style.display = 'block';
							if(document.getElementById('anyError') && this.useKeyup == false){document.getElementById('anyError').style.display = 'block';};
						}
					}
					catch (e)
					{
						//they don't have an error div for this
					}
					return false;
				}
			}
		}
		this.hideError();
		return true;
	}
}
