$(document).ready(function(){
	var validated = function(){
		var valType = $(this).parents('[validationType]').attr('validationType')+'';
		if (
			(valType.match(/Email/) && !this.value.match(/[a-z_0-9\-\.]{1,}@[a-z_0-9\-\.]{1,}\.[a-z_0-9\-\.]{2,}/i)) /* Email Validation */
			|| (valType.match(/Min=([0-9]{1,})/) && this.value.length < valType.match(/Min=([0-9]{1,})/)[1]) /* Required Minimum Length */
			|| (valType.match(/Number/) && !this.value.match(/^[0-9_\.\- ]*$/)) /* Required to be a Number */
			|| (this.value == '')
		)
			return false;
		else
			return true;
	}
	var highlight = function(trueOrFalse){
		if(typeof(trueOrFalse)=='undefined')
			var trueOrFalse = true;
		if(trueOrFalse){
			$(this).addClass('formInvalid');
			if(!$(this).next().hasClass('formInvalidText'))
				$(this).after('<div style="position:absolute;" class="formInvalidText">'
					+$(this).parents('[validationErrorMessage]').attr('validationErrorMessage')+'</div>');
			$(this).next('.formInvalidText').hide().fadeIn(300).css('left',
				$(this).offset().left+$(this).width()+20).css('top',
				$(this).offset().top).css('cursor','pointer').click(function(){
					highlight.call($(this).prev()[0],false);
				});
			$(this).focus(function(){
				highlight.call($(this)[0],false);
			});
		}else{
			$(this).removeClass('formInvalid');
			$(this).next('.formInvalidText').fadeOut(300,function(){$(this).remove();});
		}
	}
	/* Validate and Highlight */
	var validate = function(){
		if (validated.call(this)){
			highlight.call(this,false);
		}else{
			highlight.call(this);
		}
	}
	
	/*
	 * On initial load, attach events for validating form fields
	 *
	 * Blur do a validation of himself, highlighting as needed
	 * KeyPress or change, only remove existing highlights
	 * Focus on a lower element, check and hilight everyone above him
	 */
	$.attachValidations = {
		init: function(){
			$('[validateMe=true] [validationType][validationType!=] input,[validateMe=true] [validationType][validationType!=] select'
			).unbind().blur(validate
			).bind('keyup change',function(){
				if (validated.call(this)){
					highlight.call(this,false);
				}
			})
			$('.formInput').unbind('focus').focus(function(){
				var el = this;
				var contin = true;
				$('.formInput').each(function(){
					if (el != this && contin){
						if($(this).parents('[validateMe=true]').length > 0 && $(this).parents('[validationType][validationType!=]').attr('validationType'))
							validate.call(this);
					}else
						contin = false;
				});
			});
		}
	};
	$.attachValidations.init();
	
	$('[validateMe=true]').unbind().submit(function(){
		var errorMsg = '';
		$('[validateMe=true] [validationType][validationType!=] input,[validateMe=true] [validationType][validationType!=] select').each(function(){	
			if (validated.call(this)){}else{
				errorMsg += $(this).parent().attr('validationErrorMessage')+'\n';
				validate.call(this);
			}
		});
		if(errorMsg =='')
			return true;
		return false;
	});
});
