//
// Validator Rule classes
//
function ValidatorRule (name, errorMessage, validationMethod){ this.validationMethod = validationMethod; this.errorMessage = errorMessage ? errorMessage : 'Validation failed.'; this.name = name;};
ValidatorRule.prototype = { doValidation : function(fieldValue, fieldObj) {return this.validationMethod(fieldValue, fieldObj);} };

//
// Validator Rule Collection class
//
function ValidatorRuleCollection(){ this.items = {}; };
ValidatorRuleCollection.prototype = { add : function(name, errorMessage, testFunction) { this.items[name] = new ValidatorRule(name, errorMessage, testFunction); } };

jQuery.blurvalidation = {
	getDefaultValidationRules : function(){
		var rules = new ValidatorRuleCollection();		
		rules.add('validator-required', 'Value required', function(fieldValue, fieldObj) { if (fieldValue == "") return false; return true; });
		rules.add('validator-email', 'Invalid email address', function(fieldValue, fieldObj) { if (fieldValue == "") return true; return /\w{1,}[@][\w\-]{1,}([.]([\w\-]{1,})){1,3}$/.test(fieldValue); });
		rules.add('validator-number', 'Invalid number', function(fieldValue, fieldObj) { if (fieldValue == "")	return true; return (!isNaN(fieldValue) && !/^\s+$/.test(fieldValue)); });
		rules.add('validator-digits', 'Only digits allowed', function(fieldValue, fieldObj) { if (fieldValue == "")	return true; return !/[^\d]/.test(fieldValue); });
		rules.add('validator-alphanum', 'Only letters (a-z) or numbers (0-9) allowed', function(fieldValue, fieldObj) { if (fieldValue == "")	return true; return !/\W/.test(fieldValue); });
		rules.add('validator-date-ddmmyyyy', 'Invalid date, must be dd/mm/yyyy', function(fieldValue, fieldObj) { if (fieldValue == "")	return true;var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;if(!regex.test(fieldValue)) return false;var d = new Date(v.replace(regex, '$2/$1/$3'));return ( parseInt(RegExp.$2, 10) == (1+d.getMonth()) ) && (parseInt(RegExp.$1, 10) == d.getDate()) && (parseInt(RegExp.$3, 10) == d.getFullYear() ); });
		rules.add('validator-date-mmddyyyy', 'Invalid date, must be mm/dd/yyyy', function(fieldValue, fieldObj) { if (fieldValue == "")	return true;var regex = /^(\d{2})\/(\d{2})\/(\d{4})$/;if(!regex.test(fieldValue)) return false;var d = new Date(fieldValue.replace(regex, '$2/$1/$3'));return ( parseInt(RegExp.$1, 10) == (1+d.getMonth()) ) && (parseInt(RegExp.$2, 10) == d.getDate()) && (parseInt(RegExp.$3, 10) == d.getFullYear() ); });
		rules.add('validator-url', 'Invalid URL.', function(fieldValue, fieldObj) { if (fieldValue == "") return true; return /^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i.test(fieldValue); });

		return rules;
	},
	
	validate : function(obj, errClassName)
	{
		var validatedOK = true;
		var validationRules = jQuery.blurvalidation.getDefaultValidationRules();
	  
	  	var elmId = obj;
		var jQueryElm = $("#" + elmId);
		
		var cssClassesStr = new String(jQueryElm.attr("class")); 

		
		cssClassesStr = jQuery.trim(cssClassesStr);
		
		if (cssClassesStr.length > 0)
		{
			var cssClasses = cssClassesStr.split(" ");
									
			for (var i=0; i<cssClasses.length; i++){				
				var validationRule = validationRules.items[cssClasses[i]];					

				if (validationRule){						
					// Get value of the field as a string
					var fieldValue = jQueryElm.fieldStringVal();							
					var retval = validationRule.doValidation(fieldValue, this);
							
					if (!retval){	
						validatedOK = false;
								
						// Set the error css class
						jQueryElm.addClass(errClassName);
						jQueryElm[0].focus();
						break;
					}						
				}
			}
			
			if (validatedOK)
				jQueryElm.removeClass(errClassName);
				
			return validatedOK;
		}
	}
};

jQuery.keydownvalidation = {
	getDefaultValidationRules : function(){
		var rules = new ValidatorRuleCollection();		
		rules.add('validator-digits', 'Invalid number', function(evt, fieldValue, fieldObj)
		{
             var charCode = (evt.which) ? evt.which : event.keyCode
             if (charCode > 31 && (charCode < 48 || charCode > 57)) { return false; } else { return true; }
        });
		return rules;
	},
	
	validate : function(obj, errClassName, evt)
	{
		var validatedOK = true;
		var validationRules = jQuery.keydownvalidation.getDefaultValidationRules();
	  
	  	var elmId = obj;
		var jQueryElm = $("#" + elmId);
		
		var cssClassesStr = new String(jQueryElm.attr("class")); 

		
		cssClassesStr = jQuery.trim(cssClassesStr);
		
		if (cssClassesStr.length > 0)
		{
			var cssClasses = cssClassesStr.split(" ");
									
			for (var i=0; i<cssClasses.length; i++){				
				var validationRule = validationRules.items[cssClasses[i]];					

				if (validationRule){						
					// Get value of the field as a string
					var fieldValue = jQueryElm.fieldStringVal();							
					var retval = validationRule.doValidation(evt, fieldValue, this);
							
					if (!retval){	
						validatedOK = false;
								
						// Set the error css class
						jQueryElm.addClass(errClassName);
						jQueryElm[0].focus();
						break;
					}						
				}
			}
			
			if (validatedOK)
				jQueryElm.removeClass(errClassName);
				
			return validatedOK;
		}
	}
};

jQuery.fn.extend(
{
    addBlurValidation: function(errClassName)
    {
        var id = this[0].id;
    	jQuery("#" + this[0].id).bind("blur", function() { jQuery.blurvalidation.validate(id, errClassName); });
    },
    
    addKeydownValidation: function(errClassName)
    {
        var id = this[0].id;
    	jQuery("#" + this[0].id).bind("keydown", function(event) { return jQuery.keydownvalidation.validate(id, errClassName, event); });
    }
});
