/**
 * Javascript Validation Class
 *
 * @author Kevin Gwynn
 * @since 2008-07-17
 */

/**
 * Examples:
 */

/*

Validation.AddValidators('int_form',
	{fname: ['not null', 'Please provide your first name'],
	 lname: ['not null', 'Please provide your last name'],
	 email: ['email', 'Please provide a valid e-mail address'],
	 zip: ['int minlength5 maxlength5', 'Please provide your 5-digit zip code']
	}
);

// OR:

Validation.AddValidators('int_form',
	{fname: {type: 'not null', description: 'Please provide your first name'},
	 lname: {type: 'not null', description: 'Please provide your last name'},
	 email: {type: 'email', description: 'Please provide a valid e-mail address'},
	 zip: {type: 'int minlength5 maxlength5', description: 'Please provide your 5-digit zip code'}
	}
);

// OR:

Validation.AddValidator('int_form', 'fname', 'not null', 'Please provide your first name');
Validation.AddValidator('int_form', 'lname', 'minlength 5 maxlength 7 not null', 'Please provide your last name');
Validation.AddValidator('int_form', 'email', 'email', 'Please a valid e-mail address');
Validation.AddValidator('int_form', 'zip', 'int minlength5 maxlength5', 'Please provide your 5-digit zip code');
*/


var Validation = {

	_forms: {},

	AddValidator: function(formId, fieldId, type, description, condition) {
		var form = document.getElementById(formId);
		var field = document.getElementById(fieldId);

		if ('undefined' == typeof form.onsubmit && 'undefined' == typeof form.onSubmit
			|| ('object' == typeof form.onsubmit && null == form.onsubmit)) {
			form.onsubmit = function() {
				return Validation.ValidateForm(formId);
			}
		}

		if ('undefined' == typeof this._forms[formId]) {
			this._forms[formId] = {};
		}

		this._forms[formId][fieldId] = {type: type, description: description, condition: condition};
	},

	AddValidators: function(formId, validators) {
		for (var fieldId in validators) {
			var validator = validators[fieldId];

			if ('undefined' == typeof validator.type) {
				this.AddValidator(formId, fieldId, validator[0], validator[1], validator[2]);
			} else {
				this.AddValidator(formId, fieldId, validator.type, validator.description, validator.condition);
			}
		}
	},

	RemoveValidator: function(formId, fieldId) {
		if ('undefined' != typeof this._forms[formId][fieldId]) {
			delete this._forms[formId][fieldId];
		}
	},

	ValidateForm: function(formId) {
		var isValid = true;

		this._forms[formId].message = '';

		for (var fieldId in this._forms[formId]) {
			var validator = this._forms[formId][fieldId];
			isValid = isValid && Validation.ValidateField(formId, fieldId, validator.type, validator.description, validator.condition);
		}

		if (!isValid) {
			alert (this._forms[formId].message);
		}

		return isValid;
	},

	ValidateField: function(formId, fieldId, type, description, condition) {
		var field = document.getElementById(fieldId);
		
		// If we don't have a field, see if the passed in value was a name
		if (!field) {
			field = document.getElementsByName(fieldId)[0];
		}
		
		var form = this._forms[formId];

		if ('undefined' == typeof field || null == field) {
			return true;
		}

		if ('undefined' != field.type && ('radio' == field.type || 'checkbox' == field.type)) {
			type += ' checkbox';
		}

		if ('undefined' == typeof type) {
			//alert ('ValidateField error: field [' + fieldId + '] has no specified validation type.');
			return true;
		}

		if ('undefined' != condition && condition && !eval(condition)) {
			return true;
		}

		return     this.ValidateNotNull(form, field, type, description)
				&& this.ValidateInteger(form, field, type, description)
				&& this.ValidateMinimumLength(form, field, type, description)
				&& this.ValidateMaximumLength(form, field, type, description)
				&& this.ValidateMinimumValue(form, field, type, description)
				&& this.ValidateMaximumValue(form, field, type, description)
				&& this.ValidateEmail(form, field, type, description)
			;
	},

	ValidateNotNull: function(form, field, type, description) {
		if (type.match(/checkbox/i)) {
			var checkboxes = document.getElementsByName(field.name);

			for (var i = 0; i < checkboxes.length; i++) {
				if (checkboxes[i].checked) {
					return true;
				}
			}

			form.message += description + '\n';
			field.focus();
			return false;
		}

		if (type.match(/not null/i)) {
			if (!field.value) {
				form.message += description + '\n';
				field.focus();
				return false;
			}
		}

		return true;
	},

	ValidateInteger: function(form, field, type, description) {
		if (type.match(/int/)) {
			if (field.value.match(/[^0-9]/)) {
				form.message += description + '\n';
				field.focus();
				return false;
			}
		}
		return true;
	},

	ValidateMinimumLength: function(form, field, type, description) {
		var matches = type.match(/minlength *([0-9]+)/i);
		if (matches) {
			var minLength = matches[1];
			if (field.value.length < minLength) {
				form.message += description + '\n';
				field.focus();
				return false;
			}
		}
		return true;
	},

	ValidateMaximumLength: function(form, field, type, description) {
		var matches = type.match(/maxlength *([0-9]+)/i);
		if (matches) {
			var maxLength = matches[1];
			if (field.value.length > maxLength) {
				form.message += description + '\n';
				field.focus();
				return false;
			}
		}
		return true;
	},

	ValidateMinimumValue: function(form, field, type, description) {
		var matches = type.match(/min *([0-9]+)/i);
		if (matches) {
			var min = matches[1];
			if (field.value < min) {
				form.message += description + '\n';
				field.focus();
				return false;
			}
		}
		return true;
	},

	ValidateMaximumValue: function(form, field, type, description) {
		var matches = type.match(/max *([0-9]+)/i);
		if (matches) {
			var min = matches[1];
			if (field.value > max) {
				form.message += description + '\n';
				field.focus();
				return false;
			}
		}
		return true;
	},

	ValidateEmail: function(form, field, type, description) {
		if (type.match(/email/)) {
			var re = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,6}|[0-9]{1,3})(\]?)$/;
			if (!re.test(field.value)) {
				form.message += description + '\n';
				field.focus();
				return false;
			}
		}
		return true;
	}
}
