/***
*	Validator Script
*	Written By: Matthew Gaddis
*	Date: 2006-07-26
* 	Dependencies:
*		prototype v 1.5.0 >
***/

var Validator = {};
Validator.Base = function() {};

Validator.Base.prototype = 
{
	baseInitialize: function(options)
	{
		this.ELEMENT_NODE = 1;
		this.TEXT_NODE = 3;
		
		if (this.setOptions)
			this.setOptions(options);
		else
			this.options = options || {};
			
		this.options.required 		= this.options.required 		|| { test: /[\S]+/, example: null };
		this.options.phone 			= this.options.phone 			|| { test: /^(\(?[\d]{3}\)?)?[ \-]?[\d]{3}[ \-]?[\d]{4}$/, example: '(555) 555-5555' };
		this.options.wordphone 		= this.options.wordphone 		|| { test: /^(\(?[\d\w]{3}\)?)?[ \-]?[\d\w]{3}[ \-]?[\d\w]{4}$/, example: '(555) 555-5555' };
		this.options.email 			= this.options.email 			|| { test: /^[-!#$%&'*+\.\\\/0-9=?A-Z^_`a-z{|}~]+@[-!#$%&'*+\\\/0-9=?A-Z^_`a-z{|}~]+\.[-!#$%&'*+\.\\\/0-9=?A-Z^_`a-z{|}~]+$/  /* ' little hacky hack for IDEs */, example: 'johnsmith@sampledomain.com' };
		this.options.uszipcode 		= this.options.uszipcode 		|| { test: /^\d{5}(\-\d{4})?$/, example: '55555' };
		this.options.creditcard		= this.options.creditcard		|| { test: /^\d{4}[ \-]?\d{4}[ \-]?\d{4}[ \-]?\d{4}$/, example: '0000-0000-0000-0000' };
		this.options.url			= this.options.url				|| { test: /^(f|ht)tps?:\/\/[\w\-]+\.[\w\-]+/, example: 'http://www.yourdomain.com' };
		this.options.password		= this.options.password			|| { test: /^[^ \r\n\t]{5,12}$/, example: '5 to 12 characters long with no spaces' };
		this.options.middleinitial	= this.options.middleinitial	|| { test: /^[a-zA-Z][\.]?$/, example: 'W.' };
		this.options.integer		= this.options.integer			|| { test: /^\-?\d+$/, example: 'Integer' };
		this.options.money			= this.options.money			|| { test: /^\d+(\.\d{2})?$/, example: '1000.00' };
		this.options.date			= this.options.date				|| { test: /^[01]?[0-9]\/[0-3]?[0-9]\/(19|20)?[0-9]{2}$/, example: 'mm/dd/yyyy' };
		this.options.yeardate 		= this.options.yeardate			|| { test: /^(19|20)?[0-9]{4}$/, example: 'yyyy' };		
	}
}

Validator.Form = Class.create();
Validator.Form.prototype = Object.extend
(
 	new Validator.Base(), 
	{
		init: function(options)
		{
			this.baseInitialize(options);
			this.FORM_NODE_NAME = 'FORM';
			this.LABEL_NODE_NAME = 'LABEL';

			this.options.onclick = this.options.onclick || function(event)
			{
				if (! this.check ( Event.element ( event ) ) )
				{
					///
					/// This may not work for safari...
					///
					Event.stop(event);
				}
			}
		},
		initialize: function(options)
		{
			this.init(options);
		},
		check: function(_submit)
		{
			var _form = _submit.parentNode;
			while(_form.tagName != 'FORM' && _form.parentNode) { _form = _form.parentNode; }
			if(_form)
			{
				var _label = _form.getElementsByTagName('label');
				for(var i = 0; i < _label.length; i++)
				{
					var _labelClass = null;
					var _labelFor = null;
					var _alertMessage = _label[i].firstChild.nodeValue;
					//label tags come in two variations
					//1. They have a 'for' attribute that ties them with the corresponding form element
					_labelClass = (_label[i].className != '') ? _label[i].className : null;
					
					_labelFor = _label[i].getAttribute('for');
					if(_labelFor == null && document.all)
						_labelFor = (_label[i].attributes['for'].value != '') ? _label[i].attributes['for'].value : null;
	
					//2. They do not have a 'for' attribute but instead
					//   the form element is a child of the label tag
					if(_labelFor == null)
					{
						for(var k = 0; k < _label[i].childNodes.length; k++)
						{
							if(_label[i].childNodes[k].nodeType == this.ELEMENT_NODE && (_labelFor == null || _labelFor == ''))
							{
								var _element = _label[i].childNodes[k];
								
								if( 
									(_element.tagName == 'INPUT') || 
									(_element.tagName == 'TEXTAREA') ||
									(_element.tagName == 'SELECT'))
								{
									_labelFor = _element.getAttribute('id');
								}
							}
							else if(_label[i].childNodes[k].nodeType == this.TEXT_NODE && _alertMessage == null)
							{
								_alertMessage = _label[i].childNodes[k].nodeValue;
							}
						}
					}
					
					if(_labelClass != null && _labelFor != null)
					{
						var _labelClassArray = _labelClass.split(' ');
						var _input = document.getElementById(_labelFor);
						if(
							(_input.tagName == 'INPUT' && 
							(_input.getAttribute('type') == "text" || _input.getAttribute('type') == "password" || _input.getAttribute('type') == "hidden" || _input.getAttribute('type') == null)) || 
							(_input.tagName == 'TEXTAREA') ||
							(_input.tagName == 'SELECT'))
						{
							for(var j = 0; j <  _labelClassArray.length; j++)
							{
								if(typeof this.options[_labelClassArray[j]] != 'undefined')
								{
									var valid = true;
									var validator = this.options[_labelClassArray[j]].test;
									var required = ( $A(_labelClassArray).indexOf('required') > -1 );
									
									if ( typeof validator.test != 'undefined' )
									{
										valid = validator.test(_input.value);
									}
									else if ( typeof validator == 'function' )
									{
										valid = validator(_input.value);
									}
									
									if
									(
										 valid != true &&
										(required || _input.value != '')
									)
									{
										if(required)
											_alertMessage += ' is required';
										if(this.options[_labelClassArray[j]]['example'] != null)
										{
											_alertMessage += (required) ? '\nand ' : ' ';
											_alertMessage += 'should be formatted as ' + this.options[_labelClassArray[j]].example;
										}
										_alertMessage += '.';
										alert(_alertMessage);
										if(_input.getAttribute('type') != 'hidden')
										{
											_input.focus();
											if(_input.tagName != 'SELECT')
												_input.select();
										}
										return false;
									}
								}
							}
						}
						else if((_input.getElementsByTagName('input')).length > 0)
						{
							var inputList = _input.getElementsByTagName('input');
							var required = ( $A(_labelClassArray).indexOf('required') > -1 );
							if(required)
							{
								if(_label[i].getAttribute('title') != '' && _label[i].getAttribute('title') != null)
								{
									_alertMessage  = _label[i].getAttribute('title');
								}
								else
								{
									_alertMessage += ' is required';
								}
								
								var isSet = false;
								for(var j = 0; j < inputList.length; j++)
								{
									if(inputList[j].getAttribute("type") == "checkbox" || inputList[j].getAttribute("type") == "radio")
									{
										if(inputList[j].checked)
										{
											isSet = true;
										}
									}
								}
								if(! isSet)
								{
									_alertMessage += '.';
									alert(_alertMessage);
									return false;
								}
							}
						}
					}
				}
			}
			return true;
		}
	}
);

Validator.ESMForm = Class.create();
Validator.ESMForm.prototype = Object.extend
(
 	new Validator.Form(), 
	{
		initialize: function(element, options)
		{
			this.init(element, options);
			
			var i, inputSubmitElements = $$('form.userform input[type=submit]');
			for(i = 0; i < inputSubmitElements.length; i++)
			{
				Event.observe(inputSubmitElements[i], 'click', this.options.onclick.bindAsEventListener(this));
			}
		}
	}
);
