document.write('<scr' + 'ipt type="text/javascript" src="/common/js/locale/' + SPConfig.locale.toUpperCase() + '/validation_copy.js"></scr' + 'ipt>');

function FormValidator()
{
	this.errorMsgBoxID = "";
	this.errorBoxDisplay = "";
	this.labelErrorClass = "";
	this.displayErrorSummary = true;
	
	this.validatees = new Array();
	
	this.valid = false;
	this.validIsUpToDate = false;
	this.setErrorMsgBoxID = function(errorMsgBoxID)
	{
		this.errorMsgBoxID = errorMsgBoxID;
	}
	
	this.setErrorBoxDisplay = function(errorBoxDisplay)
	{
		this.errorBoxDisplay = errorBoxDisplay;
	}
	
	this.setErrorClass = function(labelErrorClass)
	{
		this.labelErrorClass = labelErrorClass;
	}
	
	/**
	 *@todo this setLabelErrorClass alias maintains backwards compatibility, but shuold be phased out 
	 *@depricated
	 */
	this.setLabelErrorClass = this.setErrorClass;
	
	this.setDisplayErrorSummary = function(bool)
	{
		this.displayErrorSummary = bool;
	}

	/*	
	Adds a FieldValidatee which will be validated when 'validate()' is run. 
	
	@param id (string) The HTML ID of the form input control
	@param prettyName (string) Label of this field in the form
	@param type (string) The type of validation to be done. See FieldValidatee class for possible values
	@param required (boolean) Whether this is a required field, or optional
	@param labelID (string) The HTML ID of the label for this form field (optional)
	
	@return (boolean) Whether this field was added successfully
	*/
	this.addField = function(id, prettyName, type, required, labelID, customErrMsg)
	{
		// IS type A VALID TYPE?
		if(!Validatee.isValidType(type))
			return false;
		
		this.validatees[this.validatees.length++] = new FieldValidatee(id, prettyName, type, required, labelID, customErrMsg);
		
		this.validIsUpToDate = false;
		return true;
	}

	/*	
	Adds a ValueValidatee which will be validated when 'validate()' is run. 
	
	@param value (string) The value of the form input control
	@param prettyName (string) Label of this field in the form
	@param type (string) The type of validation to be done. See FieldValidatee class for possible values
	@param required (boolean) Whether this is a required field, or optional
	@param labelID (string) The HTML ID of the label for this form field (optional)
	
	@return (boolean) Whether this value was added successfully
	*/
	this.addValue = function(value, prettyName, type, required, labelID, customErrMsg)
	{
		// IS type A VALID TYPE?
		if(!Validatee.isValidType(type))
			return false;
		
		this.validatees[this.validatees.length++] = new ValueValidatee(value, prettyName, type, required, labelID, customErrMsg);
		
		this.validIsUpToDate = false;
		return true;
	}
	
	/*
	Adds an ErrorValidatee which always returns an error. The error message posted to the error box will 
	  be in the format "prettyName: errMsg", so you don't have to put the prettyName in your errMsg when passing it
	  in to this function. 
	
	@param valid (boolean) Whether this field is valid or invalid (needed for when we have to uncolor the label of
		                    this field after an error has been fixed
	@param errMsg (string) The error message to show the user (not including the prettyName, or field name)
	@param prettyName (string) Label of this field in the form
	@param labelID (string) The HTML ID of the label for this form field (optional)
	
	@return (boolean) Whether this item was added successfully
	*/
	this.addError = function(valid, errMsg, prettyName, labelID)
	{
		this.validatees[this.validatees.length++] = new ErrorValidatee(valid, errMsg, prettyName, labelID);
		
		this.validIsUpToDate = false;
		return true;
	}
	
	/*	
	Validates the Validatees and updates this.valid. 
	Displays error messages to user through error message box and label highlighting (if given).
	
	@param none
	@return (boolean) Whether the Validatees are all valid 
	*/
	this.validate = function()
	{
		if(this.validatees.length == 0)
			return false;
		
		if(this.validIsUpToDate)
			return this.valid;

		var errMsg = "";
		var errMsgLineBreak = (this.errorMsgBoxID !== "") ? "<br />" : "\n";

		// Validate each validatee
		var localValid = true;
		var i;
		for(i = 0 ; i < this.validatees.length ; i++)
		{
			if(!this.validatees[i].validate())
			{
				localValid = false;
				errMsg += this.validatees[i].getErrorMsg()+errMsgLineBreak;
			}
		}
		this.valid = localValid;

		// Display errors
		this.removeErrorClassFromAllElements();

		if(!this.valid)
		{
			// Show which validatees' labels are erroneous
			if(this.labelErrorClass !== "")
			{
				for(i = 0 ; i < this.validatees.length ; i++)
				{
					if(this.validatees[i].getLabelID() === "") continue;

					labelCtrl = document.getElementById(this.validatees[i].getLabelID());
					if(labelCtrl == null) continue;
					
					if(!this.validatees[i].isValid())
						this.addErrorClassToElement(labelCtrl);
				}
			}
			
			// Write the error messages to the error box
			if(this.displayErrorSummary)
			{
				if(this.errorMsgBoxID !== "")
				{
					if(this.errorBoxDisplay === "")
						this.errorBoxDisplay = "block";
				
					var errorMsgBox = document.getElementById(this.errorMsgBoxID);
					errorMsgBox.innerHTML = errMsg;
					errorMsgBox.style.display = this.errorBoxDisplay;
				}
				else
				{
					alert(errMsg);
				}
			}
		}
		
		// We're done
		this.validIsUpToDate = true;
		return this.valid;
	}
	
	this.addErrorClassToElement = function(element)
	{
		if(this.labelErrorClass == "" || !element)
			return;
		
		// Make sure we only add the error class if it's not already here
		if(element.className.search(new RegExp("\\W*"+this.labelErrorClass+"\\W*")) == -1)
			element.className += " "+this.labelErrorClass;
	}
	
	this.removeErrorClassFromElement = function(element)
	{
		if(this.labelErrorClass == "" || !element)
			return;
		
		// Make sure we don't have the error class set in this validatees's className
		element.className = element.className.replace(new RegExp("\\W*"+this.labelErrorClass+"\\W*"), " ");
	}
	
	this.removeErrorClassFromAllElements = function()
	{
		if(this.labelErrorClass == "")
			return;
		
		for(i = 0 ; i < this.validatees.length ; i++)
		{
			if(this.validatees[i].getLabelID() === "") continue;

			labelCtrl = document.getElementById(this.validatees[i].getLabelID());
			if(labelCtrl == null) continue;
			
			this.removeErrorClassFromElement(labelCtrl);
		}
	}
	
	/*
	Returns whether the Validatees' data are valid. Performs validation if it hasn't been performed yet.
	
	@param none
	@return (boolean) Whether the Validatees are valid
	*/
	this.isValid = function()
	{
		if(this.validatees.length == 0)
			return false;
		if(!this.validIsUpToDate)
			return this.validate();
		return this.valid;
	}
}

/*
WARNING: THIS IS AN ABSTRACT CLASS!
YOU MUST SUBCLASS THE 'getValueValidatee()' FUNCTION IN ORDER TO USE THIS FUNCTIONALITY
*/
function Validatee(prettyName, type, required, labelID, customErrMsg)
{
	if(!Validatee.isValidType(type))
		return false;
	this.validationCopy = new SPValidationCopy;
	this.prettyName = prettyName; 
	this.type = type;
	this.required = required;
	this.labelID = labelID;
	
	this.valid = false;
	this.validIsUpToDate = false;
	this.errMsg = "";
	this.customErrMsg = customErrMsg; // defined by user upon addition to FormValidator list

	this.getLabelID = function()
	{
		return this.labelID;
	}
	
	/*	
	Validates this Validatee, storing the error message if this validatee is invalid, 
	and updating this.valid. 
	
	@param none
	@return (boolean) Whether this validatee is valid 
	*/
	this.validate = function()
	{
		// Get the value
		var value = this.getValue();
		// Leave early if we can based on if this validatee is required
		if(!this.required && value === "") 
		{
			this.valid = true;
			this.validIsUpToDate = true;
			return this.valid;
		}
		if(this.required && value === "") 
		{
			this.valid = false;
			this.validIsUpToDate = true;
			this.errMsg = this.prettyName+this.validationCopy.isMandatory();
			return this.valid;
		}
		// Validate based on type	
		// NOTE: IF YOU ADD/REMOVE TYPES FROM HERE, 
		//   BE SURE TO UPDATE THE Validatee.validTypes ARRAY
		switch(this.type)
		{
			case "text":
			case "select":
			case "none":
				this.valid = this.validateText(value);
				break;
			case "zip":
				this.valid = this.validateZip(value);
				break;
			case "zip-IT":
				this.valid = this.validateZip_IT(value);
				break;				
			case "email":
				this.valid = this.validateEmail(value);
				break;
			case "number":
				this.valid = this.validateNumber(value);
				break;
			case "whole_number":
				this.valid = this.validateNumber(value, "whole");
				break;
			case "positive_number":
				this.valid = this.validateNumber(value, "positive");
				break;
			case "positive_whole_number":
				this.valid = this.validateNumber(value, "whole positive");
				break;
			case "phone_us":
				this.valid = this.validatePhoneUS(value);
				break;
			case "phone_international":
				this.valid = this.validatePhoneInternational(value);
				break;
			case "phone":
				this.valid = this.validatePhone(value);
				break;
			case "dollars":
				this.valid = this.validateDollars(value);
				break;
			case "date":
				this.valid = this.validateDate(value);
				break;
			case "dob":
				this.valid = this.validateDOB(value);
				break;
			case "password_confirm":
				this.valid = this.validatePasswords(value, document.getElementById("password_confirm").value);
				break;
			case "email_confirm":
				this.valid = this.validateEmails(value, document.getElementById("email_confirm").value);
				break;
			case "nickname":
				this.valid = this.validateNickname(value);
				break;
			case "age":
				this.valid = this.validateAge(); //hack
				break;
			default:
				this.valid = false;
				break;
		}
		
		// We're done
		this.validIsUpToDate = true;
		return this.valid;
	}
	
	/*
	Returns whether this Validatee's data is valid. Performs validation if it hasn't been performed yet.
	
	@param none
	@return (boolean) Whether this Validatee is valid
	*/
	this.isValid = function()
	{
		if(!this.validIsUpToDate)
			this.validate();
		
		return this.valid;
	}
	
	this.getErrorMsg = function()
	{
		return this.errMsg;
	}
	
	/*
	Gets the value of this validatee.
	This is an abstract function. It needs to be defined by a subclass in order to be used.  
	
	@param none
	@return (mixed) The value of the form. 
	*/
	this.getValue = function()
	{
		alert("Error: Illegal use of abstract class function 'getValueValidatee()'!")
		return false;
	}
	
	this.assignErrMsg = function(errMsg)
	{
		if(this.customErrMsg)
			errMsg = this.customErrMsg;
		this.errMsg = this.prettyName+errMsg;
	}
	
	// VALIDATION FUNCTIONS
	
	this.validatePhoneUS = function(value)
	{
		//if(value.search(/^\(?[0-9]{3}\)?[- ]?[\. ]?[0-9]{3}[- ]?[\. ]?[0-9]{4}$/) == -1)
		if(value.search(/^(\+)?[0-9 \-\(\)]+$/) == -1)
		{
			this.assignErrMsg(this.validationCopy.isInvalid());
			return false;
		}
		
		return true;
	}
	
	this.validatePhoneInternational = function(value)
	{
		//if(value.search(/^\+?[0-9]{3}[- ]?[0-9]{3}[- ]?[0-9]{3}[- ]?[0-9]{3}$/) == -1)
		if(value.search(/^(\+)?[0-9 \-\(\)]+$/) == -1)
		{
			this.assignErrMsg(this.validationCopy.isInvalid());
			return false;
		}
		
		return true;
	}
	
	this.validatePhone = function(value)
	{
		//if(value.search(/^\(?[0-9]{3}\)?[- ]?[0-9]{3}[- ]?[0-9]{4}$/) == -1 && 
		//	value.search(/^\+?[0-9]{3}[- ]?[0-9]{3}[- ]?[0-9]{3}[- ]?[0-9]{3}$/) == -1)
		if(value.search(/^(\+)?[0-9 \-\(\)]+$/) == -1)
		{
			this.assignErrMsg(this.validationCopy.isInvalid());
			return false;
		}
		
		return true;
	}
	
	this.validateNickname = function(value)
	{
		if(value.search(/^[a-zA-Z0-9-_\. ]+$/) == -1 || value.length < 3)
		{
			this.assignErrMsg("Nickname must be at least 3 characters.");
			return false;
		}
		
		return true;
	}
	
	/* validates that passwords match each other */
	this.validatePasswords = function(value, confirmation)
	{
		//alert("password? = " + value);
		if(value.length < 3 || confirmation.length < 3) {
			this.assignErrMsg("Password must be at least 3 characters.");
			return false;
		}
		if(value != confirmation)
		{
			this.assignErrMsg("Passwords do not match.");
			return false;
		}
		
		return true;
	}
	
	this.validateAge = function()
	{
		var mm = document.getElementById("age_m").options[document.getElementById("age_m").selectedIndex].value;
		var dd = document.getElementById("age_d").options[document.getElementById("age_d").selectedIndex].value;
		var yyyy = document.getElementById("age_y").options[document.getElementById("age_y").selectedIndex].value;
		
		if(parseInt(mm) < 1 || parseInt(dd) < 1 || parseInt(yyyy) < 1) {
			this.assignErrMsg(this.validationCopy.isInvalid());
			return false;
		}
		
		days = new Date();
		gdate = days.getDate();
		gmonth = days.getMonth();
		gyear = days.getFullYear();
		
		age=gyear-yyyy;
		if((mm==(gmonth+1))&&(dd<=parseInt(gdate))) {
			age=age;
		} else {
		if(mm<=(gmonth)) {
			age=age;
		} else {
			age=age-1; 
		} }
		if(age < 18) {
			this.assignErrMsg(this.validationCopy.under18())
			return false;
		} return true;
		
	}
	
	this.validateEmails = function(value, confirmation)
	{
		
		if(value.length > 50) {
			this.assignErrMsg("Email address must be less than 50 characters.");
			return false;
		}
			if(value.search(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.(\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$/i) == -1)
		{
			this.assignErrMsg("Not a valid email address.");
			return false;
		}
		if(value != confirmation)
		{
			this.assignErrMsg("Email addresses do not match.");
			return false;
		}
		
		return true;
	}
	
	/*
	Validates a 'number' validatee
	Should be called from Validatee.validate()
	
	@param value (mixed) The value of this validatee
	@param restrictions (string/optional) Space-separated string listing restrictions on kind of number.
		Possible values include: positive, whole
	@return (boolean) Whether 'value' is a valid "number"
	*/
	this.validateNumber = function(value, restrictions)
	{
		if(isNaN(value))
		{
			this.assignErrMsg("Not a number.");
			return false;
		}
		
		value = Number(value);
		
		if(restrictions == undefined || restrictions === "" || restrictions == null)
			return true;
		
		rtn = true;
		restrictErrMsgs = "";
		
		if(restrictions.search(/\W*positive\W*/) != -1)
		{
			if(value <= 0)
			{
				restrictErrMsgs += "positive, ";
				rtn = false;
			}
		}
		
		if(restrictions.search(/\W*whole\W*/) != -1)
		{
			if(Math.floor(value) != value)
			{
				restrictErrMsgs += "whole, ";
				rtn = false;
			}
		}
		
		restrictErrMsgs = restrictErrMsgs.replace(/, $/, "");
		
		if(!rtn)
		{
			this.assignErrMsg("Not a "+restrictErrMsgs+" number.");
		}
		
		return rtn;
	}
	
	/*
	Validates a 'text' validatee
	Should be called from Validatee.validate()
	
	@param value (string) The value of this validatee
	@return (boolean) Whether 'value' is a valid "text"
	*/
	this.validateText = function(value)
	{
		return true;
	}
	
	this.validateDollars = function(value)
	{
		if(value.search(/^\$?[0-9]{0,3}(,?[0-9]{3})*(\.[0-9]{2})?$/) == -1)
		{
			this.assignErrMsg("Not a valid dollar amount.");
			return false;
		}
		
		return true;
	}
	
	/*
	Validates a 'zip' validatee
	Should be called from Validatee.validate()
	
	@param value (string) The value of this validatee
	@return (boolean) Whether 'value' is a valid "zip"
	
	checks for US zip forms:##### or #####-####
	checks for Canadian zip form: A#A#A#
	*/
	this.validateZip = function(value)
	{
		//if ((value.search(/^[0-9]{5}(-[0-9]{4})?$/) == -1)&&(value.search(/^[a-zA-Z][0-9][a-zA-Z][0-9][a-zA-Z][0-9]/) == -1))
		if(value.search(/^[a-zA-Z0-9\- ]+$/) == -1)
		{
			this.assignErrMsg(this.validationCopy.isInvalid());
			return false;
		}
		
		return true;
	}
	
	this.validateZip_IT = function(value){
		if(value.search(/^[0-9]{5}$/) == -1){
			this.assignErrMsg(this.validationCopy.isInvalid());
			return false;
		}
		return true;
	}
	/*
	Validates an 'email' validatee
	Should be called from Validatee.validate()
	
	@param value (string) The value of this validatee
	@return (boolean) Whether 'value' is a valid "email"
	*/
	this.validateEmail = function(value)
	{
			
		if(value.length >= 50) {
			this.assignErrMsg(this.validationCopy.lessThanXXCharacters(50));
			return false;
		}
				if(value.search(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*\.(\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum))$/i) == -1)
		{
			this.assignErrMsg(this.validationCopy.isInvalid());
			return false;
		}
	
		return true;
	}
	
	/*
	Validates a 'date' validatee
	Should be called from Validatee.validate()
	
	@param value (string) The value of this validatee
	       the date format must be "yyyy-mm-dd" or "yyyy/mm/dd"
	@return (boolean) Whether 'value' is a valid "date"
	*/	
	this.validateDate = function(value)
	{
		var errMsg = "Not a valid date.";
		
		// Ensure the date is separated correctly
		value = this.homogenizeDateSeparators(value);
		
		// Break the string up into its parts
		var temp = value.split("-");
		if(temp.length != 3)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		var year = temp[0];
		var month = temp[1];
		var day = temp[2];
		
		// See if they're at least numbers
		if(year.search(/\D/) != -1 || month.search(/\D/) != -1 || day.search(/\D/) != -1 || 
			year.length > 4 || month.length > 2 || day.length > 2)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		year = Number(year);
		month = Number(month);
		day = Number(day);
				
		// Check year
		var now = new Date();
		var this_year = now.getFullYear();
		if(year < 1900 || year > this_year + 10)  // no earlier than 1900 and no later than 10 years after this year
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		// Check month
		if(month < 1 || month > 12)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		// Check day
		if(day < 1 || day > 31)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		// Check for 30-day months
		if((month == 4 || month == 6 || month == 9 || month == 11) && day == 31)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		// Check February
		if(month == 2)
		{
			if(day > 29)
			{
				this.assignErrMsg(errMsg);
				return false;
			}
			else if(day == 29 && year % 4 != 0)
			{
				this.assignErrMsg(errMsg);
				return false;
			}
		}
		
		return true;
	}
	
	/*
	Validates a 'date' validatee as being a valid date of birth
	Should be called from Validatee.validate()
	
	@param value (string) The value of this validatee
	       uses validateDate as an initial check for format
	@return (boolean) Whether 'value' is a valid "date"
	*/	
	this.validateDOB = function(value)
	{
		var errMsg = "Not a valid date of birth.";
		
		// Let's make sure it's a date first
		if(!this.validateDate(value))
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		// Ensure the date is separated correctly
		value = this.homogenizeDateSeparators(value);
		
		// Break the string up into its parts
		var temp = value.split("-");
		if(temp.length != 3)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		var year = temp[0];
		var month = temp[1];
		var day = temp[2];
		
		// See if they're at least numbers
		if(year.search(/\D/) != -1 || month.search(/\D/) != -1 || day.search(/\D/) != -1 || 
			year.length > 4 || month.length > 2 || day.length > 2)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		year = Number(year);
		month = Number(month);
		day = Number(day);
		
		var now = new Date();
		var this_year = now.getFullYear();
		
		if(year < 1900)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		var dob = new Date(year, month, day)
		if(dob > now)
		{
			this.assignErrMsg(errMsg);
			return false;
		}
		
		return true;
	}
	
	/*
	Formats date string separators into a homogenized format (yyyy-mm-dd)
	Should be called from Validatee.validate()
	
	@param value (string) The value of this validatee
	       uses validateDate as an initial check for format
	@return (boolean) Whether 'value' is a valid "date"
	*/	
	this.homogenizeDateSeparators = function(value)
	{
		value = value.replace(/\//, "-");
		return value;
	}
}

// NOTE: IF YOU ADD/REMOVE TYPES FROM HERE, 
//   BE SURE TO UPDATE THE Validatee.validate() FUNCTION
Validatee.validTypes = new Array(
	"none", 
	"text", 
	"select",
	"zip", 
	"zip-IT",
	"email", 
	"number", 
	"whole_number", 
	"positive_number", 
	"positive_whole_number", 
	"phone", 
	"phone_us", 
	"phone_international", 
	"dollars", 
	"date",
	"dob",
	"password_confirm",
	"email_confirm",
	"nickname",
	"age"
	);
Validatee.isValidType = function(type)
{
	var i;
	for(i = 0 ; i < Validatee.validTypes.length ; i++)
		if(Validatee.validTypes[i] === type)
			return true;

	return false;
}

/*
Subclass of Validatee
Obtains value from HTML form dynamically via "getElementById()' and "getElementsByName()"
*/
function FieldValidatee(id, prettyName, type, required, labelID, customErrMsg)
{
	this.id = id;
	
	this.inheritFrom = Validatee;
	this.inheritFrom(prettyName, type, required, labelID, customErrMsg);
	
	this.getValue = function()
	{
		var i; 
		var formCtrl = null;
		
		// Get access to the form control via it's 'name' attribute
		elements = document.getElementsByName(this.id);
		if(elements.length != 0)
		{
			// We found an element by name, so let's set its default values
			for(i = 0 ; i < elements.length ; i++)
			{
				// If it's a radio button group or a checkbox, go by 'checked'
				if(elements[i].type == "radio" || elements[i].type == "checkbox")
				{
					if(elements[i].checked == true)
					{
						formCtrl = elements[i];
						break;
					}
				}
				else if(elements[i].value !== "")  // otherwise go by 'value'
				{
					formCtrl = elements[i];
					break;
				}
			}			
		}
		else
		{
			// try by id
			formCtrl = document.getElementById(this.id);
		}
		
		if(formCtrl == null) return "";

		// Get the value based on what type of control it is
		var rtn = "";
		
		switch(formCtrl.type)
		{
			case "hidden":
			case "text":
			case "password":
			case "textarea":
			case "radio":
				rtn = formCtrl.value;
				break;
				
			case "checkbox":
				rtn = (formCtrl.checked) ? formCtrl.value : "";
				break;
				
			case "select":
			case "select-one":
				if(formCtrl.selectedIndex < 1)
					rtn = "";
				else
					rtn = formCtrl.options[formCtrl.selectedIndex].value;
				break;
				
			case "select-multiple":
				for(i = 0 ; i < formCtrl.options.length ; i++)
					if(formCtrl.options[i].selected)
						rtn += formCtrl.options[i].value+",";
				rtn = rtn.replace(/,$/, ""); // drop the last ','
				break;
		}
		
		return rtn.replace(/\s+/, "");
	}
}

/*
Subclass of Validatee
Obtains value from constructor
*/
function ValueValidatee(value, prettyName, type, required, labelID, customErrMsg)
{
	this.value = value;
	this.inheritFrom = Validatee;
	this.inheritFrom(prettyName, type, required, labelID, customErrMsg);
	
	this.getValue = function()
	{
		return this.value.replace(/\s+/, "");
	}
}

/*
Subclass of Validatee
Contains no value. 
Normally, subclass of Validatee is required to implement a getValue() function, 
  but we're also going to override the validate() function, which calls getValue()
Still, we'll override it for consistancy's sake. 
*/
function ErrorValidatee(valid, errMsg, prettyName, labelID)
{
	this.inheritFrom = Validatee;
	this.inheritFrom(prettyName, "none", true, labelID);
	this.valid = valid;
	if(!this.valid)
		this.errMsg = prettyName + ": " + errMsg;
	
	this.getValue = function()
	{
		return null;
	}
	
	this.validate = function()
	{
		this.validIsUpToDate = true;
		
		return this.valid;
	}
}
