﻿// JScript File
/// <reference path="util.js" />

String.prototype.trim = function() { return this.replace(/^\s+|\s+$/, ''); };

var fieldTypes = {
	text: {
		name: 'Text field',
		validate: function(mandatory, value) {
			return mandatory ? value != '' : true;
		}
	},
	
	email: {
		name: 'Email Address',
		validate: function(mandatory, value) {
			if(value == '' && !mandatory) return true;
			return (value != '') && /^([\w\-\.']+)@((\[([0-9]{1,3}\.){3}[0-9]{1,3}\])|(([\w\-]+\.)+)([a-zA-Z]{2,4}))$/.test(value);
		}
	},
	
	phone: {
		name: 'Phone',
		validate: function(mandatory, value) {	
			if(value == '' && !mandatory) return true;
			return (value != '') && /^[ ]*((\(\d{2,6}\))|\d*)?[ ]*-?[ ]*(\d| ){2,20}(ext?e?n?t?i?o?n?[\.]{0,1}){0,1}[ ]{0,}(\d| ){0,20}$/.test(value);
		}
	},
	
	postcode: {
		name: 'Postcode',
		validate: function(mandatory, value) {
			value = value.trim().toUpperCase();
			if(value == '' && !mandatory) return true;
			return (value != '') && /(((^[ ]*[BEGLMNS][1-9]\d?)|(^W[2-9])|(^(A[BL]|B[ABDHLNRST]|C[ABFHMORTVW]|D[ADEGHLNTY]|E[HNX]|F[KY]|G[LUY]|H[ADGPRSUX]|I[GMPV]|JE|K[ATWY]|L[ADELNSU]|M[EKL]|N[EGNPRW]|O[LX]|P[AEHLOR]|R[GHM]|S[AEGKL-PRSTWY]|T[ADFNQRSW]|UB|W[ADFNRSV]|YO|ZE)\d\d?)|(^W1[A-HJKSTUW0-9])|(((^WC[1-2])|(^EC[1-4])|(^SW1))[ABEHMNPRVWXY]))(\s*)?([0-9][ABD-HJLNP-UW-Z]{2}))$|(^GIR\s?0AA$)[ ]*/.test(value);
		}
	},
	
	integer: {
		name: 'Integer',
		validate: function(mandatory, value) {
			value = value.trim();
			if(value == '' && !mandatory) return true;
			return (value != '') && /^[0-9]+$/.test(value);
		}
	},
	
	abilityv4serial: {
		name: 'Ability V4 Serial Number',
		validate: function(mandatory, value) {	
			if(value == '' && !mandatory) return true;
			return (value != '') && /^[ ]*(\d{8})[ ]*[\-]?[ ]*(\d{5})[ ]*[\-]?[ ]*(\d{5})[ ]*$/.test(value);
		}
	}
}

validator.prototype = {
	errorClass: '',
	messageContainer: '',
	errorMessage: '',
	fieldList: null,
	highlightTimeout: null,
	signature: null,
	
	addField: function(fieldId, mandatory, type, customFunction) {
		var field = document.getElementById(fieldId);
		field.validate = true;
		field.fieldType = type;
		field.mandatory = mandatory;
		field.customFunction = customFunction;
	},
	
	addCheckbox: function(fieldName, mandatory) {
		this.fieldList.push({type:'checkbox', name: fieldName, mandatory: true});
	},
	
	addDropdown: function(fieldName, customValidatorFunction) {
		this.fieldList.push({type:'dropdown', name: fieldName, mandatory: true, customValidator: customValidatorFunction});
	},
	
	signatureCheckbox: function(fieldName) {
		this.signature = document.getElementById(fieldName);
	},
	
	validateCheckboxes: function(item) {
		var valid = false;
		var d = document.getElementById(item.name);
		if(d) this.removeClass(d, this.errorClass);
		
		if(item.mandatory) {
			var boxes = document.getElementsByName(item.name);
			for(var i=0; i<boxes.length; i++) {
				if(boxes[i].checked) valid = true;
			}
		} else {
			valid = true
		}
		if(!valid) {
			var d = document.getElementById(item.name);
			if(d) this.addClass(d, this.errorClass);
		}
		return valid;
	}
}

function validator(formId) {
	var self = this;
	this.fieldList = new Array();
	if(formId != null) {
		this.form = document.getElementById(formId);
	} else {
		this.form = document.forms[0];
	}

	this.form.onsubmit = function() {
		var valid = true;

		var fields = self.form.getElementsByTagName('input');
		for(var i=0; i<fields.length; i++) valid = self.validateField(fields[i]) && valid;

		var fields = self.form.getElementsByTagName('textarea');
		for(var i=0; i<fields.length; i++) valid = self.validateField(fields[i]) && valid;
		
		for(var i=0; i<self.fieldList.length; i++) {
			if(self.fieldList[i].type == 'checkbox') valid = self.validateCheckboxes(self.fieldList[i]) && valid;
		}
		
		for(var i=0; i<self.fieldList.length; i++) {
			if(self.fieldList[i].type == 'dropdown') valid = self.validateDropdown(self.fieldList[i]) && valid;
		}
		
		if(self.signature != null && valid) {
			if(!self.signature.checked) {
				valid = false;
				self.addClass(self.signature.parentElement, self.errorClass);
			} else {
				self.removeClass(self.signature.parentElement, self.errorClass);
			}
		}
		
		if(!valid) { 
			clearTimeout(self.highlightTimeout);
			self.messageContainer.style.display = 'block';
			self.messageContainer.innerHTML = self.errorMessage;
			self.addClass(self.messageContainer, 'highlight');
			self.highlightCount = 0;
			var hc = function() { 
				if(self.highlightCount++ % 2 == 0) self.removeClass(self.messageContainer, 'highlight'); 
				else self.addClass(self.messageContainer, 'highlight');
				if(self.highlightCount < 5) self.highlightTimeout = setTimeout(hc, 400);
			}
			self.highlightTimeout = setTimeout(hc, 400);
		}
		else self.messageContainer.innerHTML = '';
		
		return valid;
	}
	
	this.clearErrors = function() {
		var fields = self.form.getElementsByTagName('input');
		for(var i=0; i<fields.length; i++) self.removeClass(fields[i], self.errorClass);
		var fields = self.form.getElementsByTagName('textarea');
		for(var i=0; i<fields.length; i++) self.removeClass(fields[i], self.errorClass);
	}
	
	this.addClass = function(el, name) {
		self.removeClass(el, name);
		el.className = (el.className + ' ' + name).trim();
	}
	
	this.removeClass = function(el, name) {
		el.className = el.className.replace(new RegExp(name, "gi"), '').trim();
	}
	
	this.validateField = function(field) {
		var valid = true;
		if(field.validate) {
			if(!field.fieldType.validate(field.mandatory, field.value)) valid = false;
			if(valid && field.customFunction) {
				valid = field.customFunction();
			}
			if(valid) {
				self.removeClass(field, self.errorClass);
				self.setLabelError(field.id, self.errorClass, true);
			} else {
				self.addClass(field, self.errorClass);
				self.setLabelError(field.id, self.errorClass, false);
			}
		}
		return valid;
	}
	
	this.validateDropdown = function(field) {
		element = document.getElementById(field.name);
		var valid = element.selectedIndex > 0;
		
		if(valid && field.customValidator != null) valid = field.customValidator(element);
		
		if(valid) {
			self.removeClass(element, self.errorClass);
			self.setLabelError(element.id, self.errorClass, true);
		} else {
			self.addClass(element, self.errorClass);
			self.setLabelError(element.id, self.errorClass, false);
		}
		return valid;
	}
	
	this.setLabelError = function(id, className, remove) {
		var labels = document.getElementsByTagName('label');
		for(var i=0; i<labels.length; i++) {
			if(labels[i].htmlFor == id) {
				if(remove) {
					self.removeClass(labels[i], className);
					labels[i].title = '';
				} else {
					self.addClass(labels[i], className);
					labels[i].title = 'There is a problem with the value in this field - please enter a valid value';
				}
			}
		}
	}
	
	this.autoValidation = function(fields) {
		for(var i=0; i<fields.length; i++) {
			var field = fields[i];
			if(field.validate) {
				field.onfocus = field.onchange = field.onblur = field.onclick = field.onkeyup = function() {
					self.validateField(this);
				}
			}
		}
	}
	
	this.enableAutoValidation = function() {
		self.autoValidation(self.form.getElementsByTagName('input'));
		self.autoValidation(self.form.getElementsByTagName('textarea'));
		
		for(var i=0; i<self.fieldList.length; i++) {
			if(self.fieldList[i].type == 'checkbox') {
				var fields = document.getElementsByName(self.fieldList[i].name);
				var value = i;
				for(var j=0; j<fields.length; j++) {
					fields[j].onclick = function() {
						self.validateCheckboxes(self.fieldList[value]);
					}
				}
			}
		}
	}
}