(function($)
{
	$.validate = {version: '0.4',instances:0,validator: {
		PATTERN_CC : "^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11})$",
	PATTERN_CC_MSC : "^5[1-5][0-9]{14}$",
	PATTERN_CC_VSA : "^4[0-9]{12}(?:[0-9]{3})?$",
	PATTERN_CC_AME : "^3[47][0-9]{13}$",
	PATTERN_CC_DISC : "^6(?:011|5[0-9]{2})[0-9]{12}$",
	PATTERN_EMAIL : "^[a-zA-Z_0-9-'\+~]+(\.[a-zA-Z_0-9-'\+~]+)*@([a-zA-Z_0-9-\.]+)+[\.][a-zA-Z]{2,7}$",
				getValue: function(obj) {
					var temp=obj;
					if(obj.value!==undefined) {
						temp = obj.value;
					}
					return temp;
				},
				lenBetween : function(obj,gt,lt) {
					var string = this.getValue(obj);
					string = string.toString().replace(/^\s+|\s+$/g,"");;
					if (!(string.length >= gt && string.length <= lt)) {
						return false;
					}
					return true;
				},
				matchPattern : function(obj,pattern) {
					var string = this.getValue(obj);
					var regExp = new RegExp(pattern);
					return regExp.test(string);
				},
				isTheSame : function(obj,string2) {
					var string = this.getValue(obj);
					if (string!==string2) {
						return false;
					}
					return true;
				},
				isDifferent : function(obj,string2) {
					var string = this.getValue(obj);
					if (string==string2) {
						return false;
					}
					return true;
				},
				isOneOf : function(obj,array) {
					var string = this.getValue(obj);
					for (var i=0;i>array.length;i++) {
						if (string==array[i]) {
							return true;
						}
					}
					return false;
				},
				isChecked : function(obj) {
					if (obj.length==undefined) {
						if (obj.checked) {
							return true;
						}
					} else {
						for (var i=0;i<obj.length;i++) {
							if (obj[i].checked) {
								return true;
							}
						}
					}
				},
				isCreditCard : function(obj,cardtype) {
					var string = this.getValue(obj);
					var pattern=this.PATTERN_CC;
					switch(cardtype) {
						case "Visa":
							pattern=this.PATTERN_CC_VSA;
							break;
						case "MasterCard":
							pattern=this.PATTERN_CC_MSC;
							break;
						case "Discovery":
							pattern=this.PATTERN_CC_DISC;
							break;
						case "AMEX":
							pattern=this.PATTERN_CC_AME;
							break;
					}
	
				if (this.matchPattern(obj,pattern)) {
					if (!this.luhn(string)) {
						return false;
					}
						return true;
				}
				return false;
			},
			luhn: function(num) {
				num = (num + '').replace(/\D+/g, '').split('').reverse();
				if (!num.length)
				return false;
				var total = 0, i;
				for (i = 0; i < num.length; i++) {
					num[i] = parseInt(num[i])
					total += i % 2 ? 2 * num[i] - (num[i] > 4 ? 9 : 0) : num[i];
				}
				return (total % 10) == 0;
			},
			isDate : function(obj,m,d,y) {
				m = m - 1; // javascript month range : 0- 11
				var tempDate = new Date(y,m,d);
				var tempYear = (tempDate.getYear() < 1000) ? tempDate.getYear() + 1900 : tempDate.getYear();
		
				if ( !((tempYear == y) && (m == tempDate.getMonth()) && (d == tempDate.getDate())) ) {	
					return false;
				}
				return true;
			}
			}};
	
    $.fn.validate = function(settings)
    {
		return this.each(function()
        {
			var thisform = this;
			var elements = $(this).find("input[type!=submit],select,textarea");
			var submitted = false;
			var form = (settings.form!=undefined) ? settings.form : {};
			var messages = (settings.messages!=undefined) ? settings.messages : {};
			settings=jQuery.extend({cssError:"error",onChange:true,showAlert:false,showErrors:true,addMaxLength:false,checkAll:false,debug:false},settings.options);
			var errors = {
				errors:[],
				hasErrors:0,
				addError: function(error_returned) {
					this.errors[this.errors.length]=error_returned;
					this.hasErrors += 1;
				},
				showErrorsAlert: function() {
					var msg="";
					for (var i=0;i<this.errors.length;i++) {
						msg+=this.errors[i] +"\n";
					}
					if (msg.length>0) {
						alert(msg);
					}
				}	
			}
		
			elements.each(function() {
				
				$(this).bind("validate",function(event) {
					cssError(errorCheck(event.target),event.target);
				});
			});
			
			if(settings.onChange) {
					$(this).find('input[type="text"],input[type="password"],textarea').keyup(update).blur(update);
					$(this).find('select,input[type="checkbox"],input[type="radio"]').change(update);
			}
			
			if (settings.addMaxLength) {

				elements.filter("input[type=text]").each(function() {
					var element = getElement($(this));
					if (element.len!=undefined && element.len.max!=undefined)  {
						$(this).attr("maxlength",element.len.max);
					}
				});		
			}
					
			
			function errorCheck(input,ignore,dep) {
				
				var ignore = (ignore!=undefined) ? ignore : false;
				var element = getElement(input);
				var value = ($(input).attr("value")!=undefined) ? $(input).attr("value") : "";
				var ErrorMsg = (element.message!=undefined) ? element.message : "";
				var addError = (element.addError!=undefined) ? element.addError : true;
				var validate =  (element.validate!=undefined) ? element.validate : 0;
				var disable = (element.disabled!=undefined) ? element.disabled : false;
				var dependent = (element.dependent!=undefined) ? element.dependent : [];
				var validated = 0; 
				var temperrors = [];
				
				ignore = (ignore==true) ? true : (element.ignore!=undefined) ? element.ignore : false;
				disable = (disable==true) ? disable : ($(input).attr("disabled")!=undefined) ? $(input).attr("disabled") : false ;
				
				if (dep==undefined) {
					$(dependent).each(function(i) {
						if (dependent[i].field!=input) {
							var otherinput = getInput(dependent[i].field);
							var isValid = true;
							var isError = (errorCheck(otherinput,true,true).length>0) ? true : false
							var disableOnError  = dependent[i].disableOnError;
							if (isError==disableOnError || disable==true) {
								disable = true;
							}
						}
					});
				}
				
				
				if (disable!=true && disable!=false) {
				//	disable = (eval(disable)!=undefined && eval(disable)==true) ? true : false;
				}
				
				
				
			if (element!="" && element.check!=undefined && element.check.length > 0 && disable==false) {
				
						
					
					$(element.check).each(function(i) {
						
						ErrorMsg = (element.check[i].message=="" || element.check[i].message==undefined) ? element.message : element.check[i].message ;
						
						var check = element.check[i];
						var isValid = true;
												
						if(check.test!=undefined) {
							test = eval(check.test);
							test = (test==true) ? true : false;
							isValid = (isValid==false) ? isValid : test;
						}
						
						if(check.date!=undefined && check.date==true) {
							var date = value.split("/");
							var isDate = false;
							var isPattern = $.validate.validator.matchPattern(value,"^[0-9]{2}\/[0-9]{2}\/[0-9]{4}$");
							if (date.length==3 && isPattern){
								// MM/DD/YYYY
								isDate = $.validate.validator.isDate(input,date[0],date[1],date[2]);
							}
							isValid = (isValid==false) ? isValid :  isDate;
	
						}
						if (check.pattern!=undefined) {
							var pattern = check.pattern;
							var isPattern = $.validate.validator.matchPattern(value,pattern);
							isValid = (isValid==false) ? isValid :  isPattern;
						}
						if (check.email!=undefined && check.email==true) {
							var isEmail =  $.validate.validator.matchPattern(value,$.validate.validator.PATTERN_EMAIL);
							isValid = (isValid==false) ? isValid :  isEmail;
						}
						if(check.isnot!=undefined) {
							var defaultvalue = check.isnot;
							var isSelected = $.validate.validator.isDifferent(value,defaultvalue);
							isValid = (isValid==false) ? isValid :  isSelected;
						}
						if(check.len!==undefined) {
							var minLen = (check.len.min!=undefined) ? check.len.min : 0;
							var maxLen = check.len.max;
							var isLen = $.validate.validator.lenBetween(value,minLen,maxLen);

							isValid = (isValid==false) ? isValid : isLen;
						}
						if(check.checked!=undefined) {
							isValid = (isValid==false) ? isValid : $(input).is(":checked");
						}
						if(check.creditCard!=undefined) {
	
							var isCC = $.validate.validator.isCreditCard(value);
							isValid = (isValid==false) ? isValid : isCC;
						}
						
						if(check.isTheSame!=undefined) {
							var item1 = elements.filter("input[name=" + check.isTheSame.item1 + "]").attr("value");
							var item2 = elements.filter("input[name=" + check.isTheSame.item2 + "]").attr("value");	
							var isSame = $.validate.validator.isTheSame(item1,item2);
							isValid = (isValid==false) ? isValid : isSame;
						}
						if(check.radiogroup!=undefined) {
							var checked = false;
							var radioname = $(input).attr("name");
							var allradios = $(thisform).find('input[name="' + radioname + '"]:radio');
							
							$(thisform).find('input[name="' + radioname + '"]:radio').each(function(index) {
								checked=(checked) ? checked : $(this).is(":checked");
							});

	
							isValid = (isValid==false) ? isValid : checked;
							
							if (allradios.index($(input))!=allradios.length-1) {
								ignore = true;
							}
							
							
						}
						if(isValid==false && (ErrorMsg!=undefined && ErrorMsg!="") ) {
							temperrors.push(ErrorMsg);
						} else {
							validated+=1;
						}
						
					});
					
					if ((validated==validate && validate!=0) || (validate==0 && validated==element.check.length)) {
						addError = false;
					} else {
						addError = true;
					}
										
				}
				
				if (addError && temperrors.length > 0) {

					for (var x=0;x<temperrors.length;x++) {
						if(ignore==false) {
							errors.addError(temperrors[x]);
						}
					}
				}
				
				
				return (addError) ? temperrors : [];
				
			}
			
		
				
			function update(event) {
				if (submitted) {
					if (settings.checkAll) {
						elements.each(function() {
							cssError(errorCheck(this),this);		
						});
					} else {
					cssError(errorCheck(event.target),event.target);
					}
				}
			}
			
			function getElement(input) {
				var formobj = "form." + $(input).attr("name");
				var element = "";
				if ($(input).attr("name")!="" && eval(formobj)!=undefined) {
					element = eval(formobj);
				}
				return element;
			}
			function getInput(element) {
				var input = false;
				elements.each(function(i) {
					if ($(elements[i]).attr("name") == element) {
						input = elements[i];
					}
				});
				return input;
			}
			
			function cssError(errormsgs,input) {
				var element = getElement(input);
				var Errorbox = element.errorID;
				var ignoreCSS = (element.ignoreCSS!=undefined) ? element.ignoreCSS : false;
				var ErrorMsg = (element.message!=undefined) ? element.message : "";

				$("#" + Errorbox).html("");
				
				if (errormsgs.length==0) {
						if(Errorbox!=undefined && Errorbox.length>0 && settings.showErrors ) {
							$("#" + Errorbox).html("");
						}
						$(input).removeClass(settings.cssError);
						
						$(element.check).each(function() {
							if(this.radiogroup!=undefined) {
								var radioname = $(input).attr("name");
								$(thisform).find('input[name="' + radioname + '"]:radio').each(function(index) {
									$(this).removeClass(settings.cssError);
								});
							}			
							
						});
						
				} else {
					if (ignoreCSS==false) {
						$(input).addClass(settings.cssError);
					}
					$(errormsgs).each(function(i) {
						ErrorMsg = (errormsgs[i]=="" || errormsgs[i]==undefined) ? element.message : errormsgs[i];
						if(Errorbox!=undefined && Errorbox.length>0 && settings.showErrors) {
							var newErrorMsg = $("#" + Errorbox).html() + "<br/>" + ErrorMsg;
							$("#" + Errorbox).html(newErrorMsg);
						}
					});			
				}
				
			}
			
			$(this).submit(function() {
				submitted = true;
				errors.errors = new Array();
				errors.hasErrors = 0;
				elements.trigger('validate',true);
				var error = (errors.hasErrors > 0) ? true : false;
				if (settings.showAlert) {
					errors.showErrorsAlert();
				}
				if($("." + settings.cssError).length) {
					$("." + settings.cssError)[0].focus();
				}
				
				return (settings.debug==false) ? !error : false;

			});
			
        });
    };
	})(jQuery);
