/*
The Creative Department
Doug Heyob
version 1.2

Description:
A validator is created for a specific form, rules are assigned to the validator, and then when the form is submitted the form is validated against the rules.
This cleans up a lot of the code in the page.

Tested On:
IE 5.2 Mac, IE 6 Win, Mozilla 1.5, Safari 1.0
*/
function Validator() {
	this.patternRules = new Object();
	this.selectedRules = new Object();
	this.customRules = new Array();
}
Validator.prototype.setPatternRule = function (id, regexp, message, ignoreCase, invert) {
	var obj = new Object();
	obj.id = id;
	obj.regexp = regexp;
	obj.message = message;
	obj.ignoreCase = ignoreCase || false;
	obj.inverse = invert || false;
	this.patternRules[id] = obj;
};

Validator.prototype.setSelectedRule = function (id, message, ignoreEmptyOptions, min, max) {
	var obj = new Object();
	obj.id = id;
	obj.message = message;
	obj.ignoreEmpty = ignoreEmptyOptions || false;
	obj.min = min || 1;
	obj.max = max;
	this.selectedRules[id] = obj;
};

Validator.prototype.addCustomRule = function (fun) {
	this.customRules[this.customRules.length] = fun;
};

Validator.prototype.validate = function (form) {
	if (form == null) return false;
	var i;
	var finishedSelectedRules = new Object();
	for (i=0;i<form.elements.length;i++) {
		//test select-single, select-multiple, input types=(text, password, file, hidden, checkbox, radio), textarea
		var element = form.elements[i];
		var rule = this.selectedRules[element.name];
		if (rule != null) {
			if (element.tagName  == 'SELECT') {
				if (element.type == 'select-multiple') {
					var count = 0;
					var j;
					for(j=0;j<element.options.length;j++) {
						if (element.options[j].selected && (!rule.ignoreEmpty || element.options[j].value != '')) count++;
					}
					if (rule.min > count || (rule.max != null && rule.max < count)) {
						alert(rule.message);
						return false;
					}
				} else {
					if (element.selectedIndex < 0 || (element.options[element.selectedIndex].value == '' && rule.ignoreEmpty)) {
						alert(rule.message);
						return false;
					}
				}
			} else {
				if (element.tagName == 'INPUT') {
					switch (element.type) {
						case 'text':
						case 'password':
						case 'file':
						case 'hidden':
							break;
						case 'checkbox':
						case 'radio':
							if (!finishedSelectedRules[element.name]) {
								var ar = form.elements[element.name];
								var count = 0;
								if (ar.length) {
									var j;
									for (j=0;j<ar.length;j++) {
										if (ar[j].checked) count++;
									}
								} else {
									if (element.checked) count++;
								}
								if ((rule.min > count) || ((rule.max != null) && (rule.max < count))) {
									alert(rule.message);
									return false;
								}
								finishedSelectedRules[element.name] = true;
							}
							break;
					}
				} else if (element.tagName == 'TEXTAREA') {
				}
			}
		}
		rule = this.patternRules[element.name];
		if (rule != null) {
			var r = rule.regexp;
			if (r.charAt(0) != '^') r = '^'+r;
			if (r.charAt(r.length-1) != '$') r += '$';
			var reg = new RegExp(r, rule.ignoreCase?'i':'');
			if (element.tagName == 'SELECT') {
				if (element.type == 'select-multiple') {
					//todo
				} else {
					if (element.selectedIndex < 0 || (reg.test(element.options[element.selectedIndex].value) == rule.inverse)) {
						alert(rule.message);
						return false;
					}
				}
			} else if (element.tagName == 'INPUT') {
				switch (element.type) {
					case 'text':
					case 'password':
					case 'file':
					case 'hidden':
						if ((reg.test(element.value) == rule.inverse)) {
							alert(rule.message);
							return false;
						}
						break;
					case 'checkbox':
					case 'radio':
				}
			} else if (element.tagName == 'TEXTAREA') {
				if ((reg.test(element.value) == rule.inverse)) {
					alert(rule.message);
					return false;
				}
			}
		}
	}
	{
		//custom rules
		var j;
		for (j=0;j<this.customRules.length;j++) {
			if (this.customRules[j](form) == false) return false;
		}
	}
	return true;
};
