function Validator(items)
{

	this.items = items;
	
	this.errors="";
	this.errorsFields = [];

	//methods
	this.validateEmpty = validateEmpty;
	this.validateUsername = validateUsername;
	this.validatePassword = validatePassword;
	this.validateConfirmField = validateConfirmField;
	this.validateEmail = validateEmail;
	this.validatePhone = validatePhone;
	this.validateNumber = validateNumber;
	this.validatePositiveNumber=validatePositiveNumber
	this.addToErrorsFields = addToErrorsFields;

	this.isValid = validateForm;
	this.clearErrors = clearErrors;
	this.getErrors = getErrors;

	this.Validator = function()
	{
		for(i=0;i<this.items.length;i++)
		{
			this.items[i] = new formItem(this.items[i]);
		}
	}
	
	this.Validator();
	
}
function clearErrors()
{
	this.errors = "";
	
	for(i=0;i<this.errorsFields.length;i++)
	{
		this.errorsFields[i].field.style.background = this.errorsFields[i].bgColor;
		this.errorsFields[i].field.title = this.errorsFields[i].title;
	}
	this.errorsFields = [];
}
function getErrors()
{
	this.isValid();
	return this.errors;
}

function formItem(object)
{
	this.field = (object.id!=null)?document.getElementById(object.id):null;
	this.required = (object.required!=null)?object.required:false;
	this.type = (object.type!=null)?object.type:'text';
	this.label = (object.label!=null)?object.label:'';
	this.originalField = (object.originalFieldId!=null)?document.getElementById(object.originalFieldId):null;
	this.maxChars = (object.maxChars!=null)?object.maxChars:null;
}

function validateForm()
{
	this.clearErrors();
	for(i=0;i<this.items.length;i++)
	{
		var error="";
		switch(this.items[i].type)
		{
			case "text":
				error = this.validateEmpty(this.items[i].field,this.items[i].maxChars);
				break;
			case "username":
				error = this.validateUsername(this.items[i].field,this.items[i].required);
				break;
			case "password":
				error = this.validatePassword(this.items[i].field,this.items[i].required);
				break;
			case "confirm":
				error = this.validateConfirmField(this.items[i].field,this.items[i].originalField.value,this.items[i].required);
				break;
			case "email":
				error = this.validateEmail(this.items[i].field,this.items[i].required);
				break;
			case "phone":
				error = this.validatePhone(this.items[i].field,this.items[i].required);					
				break;
			case "number":
				error = this.validateNumber(this.items[i].field,this.items[i].required);
			case "positive_number":
				error = this.validatePositiveNumber(this.items[i].field,this.items[i].required);
								
				break;
}
		if(error.length!=0) this.errors +="- "+this.items[i].label+": "+error+"\n\n";
	}
	if(this.errors!="")
		return false;
	else
		return true;
}

function addToErrorsFields(fld)
{
	this.errorsFields.push({field:fld,bgColor:fld.style.background,title:fld.title});
}

function validateEmpty(fld,maxChars) {

	var error = "";
  
    if (fld.value.length == 0) {
        this.addToErrorsFields(fld);
		fld.style.background = 'Yellow'; 
        error = "This required field has not been filled in."
		fld.title = error;
    }
    else
    {
    	
    	if(maxChars!=null)
    	{
    		if(fld.value.length>maxChars)
    		{
		        this.addToErrorsFields(fld);
				fld.style.background = 'Yellow'; 
		        error = "No more than 20 characters for this field."
				fld.title = error;
    		}
    	}
    }
    return error;   
}
function validateUsername(fld,required) {
    var error = "";
    var illegalChars = /\W/; // allow letters, numbers, and underscores
 
    if (fld.value == ""  && required) {
        this.addToErrorsFields(fld);
		fld.style.background = 'Yellow'; 
        error = "You didn't enter a username.";
		fld.title = error;
    } else if ((fld.value.length < 5) || (fld.value.length > 15)) {
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow'; 
        error = "This username is the wrong length.";
		fld.title = error;
    } else if (illegalChars.test(fld.value)) {
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow'; 
        error = "This username contains illegal characters.";
		fld.title = error;
    }
    return error;
}
function validateNumber(fld,required)
{
		var error ="";
		if (fld.value == "" && required) {
			this.addToErrorsFields(fld);
			fld.style.background = 'Yellow'; 
			error = "This required field has not been filled in."
			fld.title = error;
		}else if(!Number(fld.value))
		{
			this.addToErrorsFields(fld);
			fld.style.background = 'Yellow';
			error = "This field value is not a number";
			fld.title = error;
		}
		return error;
}

function validatePositiveNumber(fld,required)
{
		var error ="";
		if (fld.value == "" && required) {
			this.addToErrorsFields(fld);
			fld.style.background = 'Yellow'; 
			error = "This required field has not been filled in."
			fld.title = error;
		}else if(!Number(fld.value))
		{
			this.addToErrorsFields(fld);
			fld.style.background = 'Yellow';
			error = "This field value is not a number";
			fld.title = error;
		}
		else if(fld.value<0)
		{
			this.addToErrorsFields(fld);
			fld.style.background = 'Yellow';
			error = "This field value is not a positive number";
			fld.title = error;
		}
		return error;
}
function validateConfirmField(fld,originalValue,required) {
		var error ="";
		
		if (fld.value.length == 0 && required) {
			this.addToErrorsFields(fld);
			fld.style.background = 'Yellow'; 
			error = "This required field has not been filled in."
			fld.title = error;
		}else if(fld.value != originalValue)
		{
			this.addToErrorsFields(fld);
			fld.style.background = 'Yellow';
			error = "Values don't match";
			fld.title = error;
		}
		return error;
}

function validatePassword(fld,required) {
    var error = "";
    var illegalChars = /[\W_]/; // allow only letters and numbers 
 
    if (fld.value == "" && required) {
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
        error = "You didn't enter a password.";
		fld.title = error;
    } else if ((fld.value.length < 7) || (fld.value.length > 15)) {
        error = "This password is the wrong length. ";
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
		fld.title = error;
    } else if (illegalChars.test(fld.value)) {
        error = "This password contains illegal characters.";
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
		fld.title = error;
    } else if (!((fld.value.search(/(a-z)+/)) && (fld.value.search(/(0-9)+/)))) {
        error = "This password must contain at least one numeral.";
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
		fld.title = error;
    }
   return error;
}   

function trim(s)
{
  return s.replace(/^\s+|\s+$/, '');
} 

function validateEmail(fld,required) {
    var error="";
    var tfld = trim(fld.value);                        // value of field with whitespace trimmed off
    var emailFilter = /^[^@]+@[^@.]+\.[^@]*\w\w$/ ;
    var illegalChars= /[\(\)\<\>\,\;\:\\\"\[\]]/ ;
    
    if (fld.value == "" && required) {
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
        error = "You didn't enter an email address.";
		fld.title = error;
    } else if (!emailFilter.test(tfld)) {              //test email for illegal characters
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
        error = "Please enter a valid email address.";
		fld.title = error;
    } else if (fld.value.match(illegalChars)) {
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
        error = "This email address contains illegal characters.";
		fld.title = error;
    }
    return error;
}
function validatePhone(fld,required) {
    var error = "";
    var stripped = fld.value.replace(/[\(\)\.\-\ ]/g, '');     

   if (fld.value == "" && required) {
        error = "You didn't enter a phone number.";
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
		fld.title = error;
    } else if (isNaN(parseInt(stripped))) {
        error = "This phone number contains illegal characters.";
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
		fld.title = error;
    } else if (!(stripped.length == 10)) {
        error = "This phone number is the wrong length. Make sure you included an area code.";
		this.addToErrorsFields(fld);
        fld.style.background = 'Yellow';
		fld.title = error;
    } 
    return error;
}