function FormValidator(o){
	this.obj=o;
	this.formFields=new Array();
	this.msg="There were problems with the following fields:\n\n"
	this.firstField=null;
}
FormValidator.prototype.addFormField=function(oField, sDisplayName, bRequired, sFormat, iMaxLength){
	this.formFields[this.formFields.length]=new FormField(this, oField, sDisplayName, bRequired, sFormat, iMaxLength);
}
FormValidator.prototype.validate=function(bShowMsg){
	if(bShowMsg==null) bShowMsg=true;
	for(var i=0;i<this.obj.elements.length;i++){
		var o=this.obj.elements[i];
		if(o.type=="text"||o.type=="textarea") o.value=new String(o.value).trim();
	}
	var iTest=Number(this.msg.length);
	for(var i=0;i<this.formFields.length;i++){
		var s=this.formFields[i].validate();
		if(s!=""){
			if(this.firstField==null) this.firstField=this.formFields[i].obj;
			this.msg+=s;
		}
	}
	if(this.msg.length>iTest){
		if(bShowMsg) alert(this.msg);
		try{
			if(this.firstField.tagName==null){
				this.firstField[0].focus();
			}else{
				this.firstField.focus();
			}
		}catch(e){
		}
		return(false);
	}else{
		return(true);
	}
}

function FormField(oForm, oField, sDisplayName, bRequired, sFormat, iMaxLength){
	this.form=oForm;
	this.obj=(typeof(oField)=="object")?oField:this.form.obj[oField];
	if(this.obj==null){
		this.validate=function(){return("FormValidator Error: No object found for '"+sDisplayName+"' ("+oField+")")};
	}else{
		this.name=this.obj.name;
		this.displayName=sDisplayName;
		this.required=bRequired;
		// (sFormat instanceof RegExp) doesn't work on mac
		this.format=(typeof(sFormat)=="object")?sFormat:new String(sFormat).toLowerCase();
		this.maxLength=(isNaN(parseInt(iMaxLength)))?0:iMaxLength;
	}
}
FormField.prototype.validate=function(){
	this.value=this.obj.value;
	if(this.format=="select") return((this.required&&this.obj.selectedIndex<=((this.obj.multiple)?-1:0))?"'"+this.displayName+"' is a required field\n":"");
	if(this.format=="checkbox"||this.format=="radio"){
		if(!this.required) return("");
		if(this.obj.length==null) return((this.obj.checked)?"":"'"+this.displayName+"' is a required field\n");
		for(var i=0;i<this.obj.length;i++){
			if(this.obj[i].checked) return("");
		}
		return("'"+this.displayName+"' is a required field\n");
	}
	if(this.format=="file"){
		if(!this.required) return("");
		if(this.value==""&&this.form.obj["old_"+this.name].value=="") return("'"+this.displayName+"' is a required field\n");
		return("");
	}
	if(this.value==""&&!this.required) return("");
	if(this.value==""&&this.required) return("'"+this.displayName+"' is a required field\n");
	if(this.maxLength>0&&(this.value.length>this.maxLength)) return("'"+this.displayName+"' is too long. (max "+this.maxLength+" chars.)\n");
	switch(this.format){
		case "word":
			var re=/^\w+$/;
			break;
		case "text":
			// var re=/^[\w\'\-\/\\:.,\?!=%&$ ]+$/;
			var re=/^[^<>\f\r\n\v]+$/;
			break;
		case "longtext":
			// var re=/^[\w\s\'\-\/\\:.,\?!=%&$\"()]+$/;
			var re=/^[^<>]+$/;
			break;
		case "numeral":
			var re=/^\d+$/;
			break;
		case "number":
			var re=/^[\-+]?[\d,]+$/;
			break;
		case "float":
			var re=/^[\-+]?[\d,]+\.?\d*$/;
			break;
		case "phonenumber":
			var re=/^(\+|\(\d+\)|\d)[\d \-]+$/;
			break;
		case "date":
			// var re=/^[0-3]?[0-9]\/[0-1]?[0-9]\/(?:\d{2})|(?:\d{4})$/
			var re=/^[0-3]?[0-9]\/[0-1]?[0-9]\/\d{4}$/
			break;
		case "email":
			var re1 = /(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)/;															// not valid
			var re2 = /^.+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}|[0-9]{1,4})(\]?)$/;	// valid
			return((!re1.test(this.value)&&re2.test(this.value))?"":"'"+this.displayName+"' is not valid\n");
		default:
			// (this.format instanceof RegExp) doesn't work on mac
			if(typeof(this.format)=="object"){
				return((this.format.test(this.value))?"":"'"+this.displayName+"' is not valid\n");
			}else{
				return("");
			}
	}
	return((re.test(this.value))?"":"'"+this.displayName+"' is not valid\n");
}
String.prototype.trim=function(){return this.replace(/^\s*|\s*$/g, "");}
String.prototype.truncate=function(iLength){
	if (this.length>iLength){
		var s=this.substr(0,iLength);
		if(s.indexOf(" ")==-1){
			return s+"...";
		}else{
			return(s.substr(0,s.lastIndexOf(" "))+" ...");
		}
	}else{
		return(this);
	}
}
function restrictLength(oField, iMaxChars){
	return(oField.value.length<=iMaxChars);
}
