if (!jQuery) throw new Error("jQuery required to run Validator");
if (!Array.prototype.contains) {
	Array.prototype.contains = function(o){
		var a = this;
		for (var i=0, j=a.length; i<j; i++)
			if (a[i]==o)
				return true;
		return false;
	}
}
if (!String.prototype.trim) {
	String.prototype.trim=function() {
		var s = this;
		s = s.replace(/^\s+/,"");
		s = s.replace(/\s+$/,"");
		return s;
	}
}
function Validator(){}
Validator.validators = new Object();
Validator.setValidators = function(elements) {
	for (var i=0, j=elements.length; i<j; i++) {
		var o = new ElementValidator(elements[i]);
		
		// Used for "blur" event checks
		Validator.validators[o.id]=o;
		if (o.element) {
			if (o.element.tagName.toUpperCase()=="SELECT") {
				$(o.element).change(Validator.onBlurCheck);
			} else {
				if (/text|password/i.test(o.element.getAttribute("type")))
					$(o.element).blur(Validator.onBlurCheck);
			}
		}
	}
}
Validator.validate = function() {
	var isValid = true;
	
	for (var i in Validator.validators) {
		Validator.validators[i].check();
		isValid = isValid && Validator.validators[i].valid;
	}
	
	return isValid;
}
Validator.onBlurCheck=function(event)
{	
	//ie
	if(document.all)
	{
		id = event.srcElement.getAttribute('id');
	}
	//moz
	else
	{
		id = this.getAttribute('id');
	}
	Validator.validators[id].check();
}
Validator.isEmpty = function(s) {
	var re = /^\s+$/;
	return s==null || s.length == 0 || re.test(s);
}
Validator.isEmail=function(s) {
	s = s.replace(" ","");
	var re = /^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/;
	return s.length==0 || re.test(s);
}
function ElementValidator(item) {
	this.id = item[0];
	this.valid = false;
	this.type = item[1].split("|");
	this.errorMessage = "";
	this.validationFunc = null;
	
	if (item[2])
	    this.errorMessage = item[2];
	if (item[3])
	    this.validationFunc = item[3];
	    
	if (this.type.contains("list")) {
	    this.element = $(":input[name='"+item[0]+"']").get(0);
	} else {
	    this.element = $("#"+item[0]).get(0);
	}
}
ElementValidator.prototype.check = function() {
	var errMsg;
    var typ;
    var required = this.type.contains("required");
    
    if (required) {
        this.valid = !Validator.isEmpty(this.element.value);
        errMsg = "This field is required."; 
        if (this.type.length == 1)
        	this.type[1] == "text";
        if (this.type[0]!="required") {
			typ = this.type[0];
		} else {
			typ = this.type[1];
		}
    } else {
        typ = this.type[0];
    }
	
	if (!required || (required && this.valid)) {
	    switch(typ) {
		    case "email":
		        this.valid = Validator.isEmail(this.element.value);
		        errMsg = "Invalid email address.";
		        break;
		    case "number":
		        this.element.value = this.element.value.replace(/[^.0-9]/g,"").trim();
		        this.valid = this.element.value.length==0 || /^\d+(\.\d\d)?/.test(this.element.value);
		        errMsg = "Invalid amount.";
		        break;
		    case "postcode":
		        this.valid = /^\d\d\d\d$/.test(this.element.value);
		        errMsg = "Invalid postcode.";
		        break;
		    case "list":
		        if (this.element.tagName.toUpperCase()=="SELECT") {
			        this.valid = this.element.selectedIndex>0;
		        } else {
			        var items = $(":radio[name='" + this.id + "'],:checkbox[name='" + this.id + "']").filter(":checked");
			        this.valid = items.length > 0;
		        }
		        errMsg = "Please select an item from this list.";
		        break;
		    default:
		        this.valid = true;
		        break;
	    } 
	}
	if (this.validationFunc!=null) {
	    errMsg = this.validationFunc(this.element);
	    this.valid = Validator.isEmpty(errMsg);
	}
	errMsg = this.errorMessage.length > 0 ? this.errorMessage : errMsg;
	
	if (this.valid) {
	    this.clearError();
	} else {
		this.setError(errMsg);
	}
}
ElementValidator.prototype.clearError=function() {
    $("#"+this.id+"_errmsg").remove();    
}
ElementValidator.prototype.setError = function(errMsg) {
    var	errorNode = $("#"+this.id+"_errmsg");
    if (errorNode.length==1) {
		errorNode.text(errMsg);
	} else {
		$(this.element.parentNode).append("<span class='errorMessage' id='"
		   +this.id+"_errmsg'>"+errMsg+"</span>");
	}
}
