/**
 * Validation.js - Javascript form validation
 * 
 * @author  Webstores <info at webstores dot nl>
 *           Copyright (c) Webstores internet totaalbureau <http://www.webstores.nl/>
 */

WS.Validation = function(form) {
	
	var form = $(form),
	    formElements = [],
		errorClass = 'wsv-error';
	
	var validations = {
		required: {
			errorMessage: 'Dit veld is verplicht',
			regex: /\S+/
		},
		email: {
			errorMessage: 'U dient een geldig e-mailadres in te vullen',
			regex: /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/
		},
		zip: {
			errorMessage: 'U dient een geldige postcode in te vullen (1234AB)',
			regex: /^[0-9]{4}[\ ]?[a-zA-Z]{2}$/
		},
		numeric: {
			errorMessage: 'Dit veld mag alleen numerieke tekens bevatten',
			regex: /^[0-9]*$/
		},
		phone: {
			errorMessage: 'U dient een geldig telefoonnummer in te vullen',
			regex: /^[0-9 +-]{10,16}$/
		}
	};
	
	return {
		/**
		 * Validation initialization
		 */
		initialize: function() {
			if(!form) { return false; }
			
			for(var i = 0; i < form.elements.length; i++) {
				if(WS.hasClass(form.elements[i], 'wsv-', true)) {
					formElements.push(form.elements[i]);
				}
			}
			
			// Webkit doesn't include fieldsets in form.elements
			// so we have to add them manually:
			if(WS.browser.Webkit) {
				var fieldsets = form.getElementsByTagName('fieldset');
				for(var i = 0; i < fieldsets.length; i++) {
					if(WS.hasClass(fieldsets[i], 'wsv-', true)) {
						formElements.push(fieldsets[i]);
					}
				}
			}
			this.initEvents();
		},
		
		/**
		 * Initializes all event handlers
		 */
		initEvents: function() {
			var self = this;
			form.onsubmit = function() {
				return self.validateForm();
			};
		},
		
		/**
		 * Enable the form element so it will be validated
		 * 
		 * @param {Mixed} el The ID of or reference to an element
		 */
		enableElement: function(el) {
			el = $(el);
			el.disabled = false;
		},
		
		/**
		 * Disable the form element so it does not get validated
		 * 
		 * @param {Mixed} el The ID of or reference to an element
		 */
		disableElement: function(el) {
			el = $(el);
			el.disabled = true;
		},
		
		/**
		 * Add a custom validation to the validations object
		 * 
		 * @param {String} name The name of the validation being added
		 * @param {JSON} properties JSON object containing the errorMessage and regex
		 */
		addValidation: function(name, properties) {
			if(!validations[name]) {
				validations[name] = properties;
			}
		},
		
		/**
		 * Validates a single form element
		 * 
		 * @param {Object} el The form element to validate
		 * @return {Boolean} True is the form element validates, false otherwise
		 */
		validateElement: function(el) {
			var valid = true;
			var vArr = el.className.match(/wsv-\w+/g);
			
			for(var i = 0; i < vArr.length; i++) {
				if(vArr[i] != errorClass) {
					if(el.nodeName == 'INPUT') {
						if(el.type == 'text' || el.type == 'password') {
							if(vArr[i] == 'wsv-required' || el.value !== '') {
								valid = validations[vArr[i].split('wsv-')[1]].regex.test(el.value);
							}
						}
						else if(el.type == 'checkbox') {
							valid = el.checked;
						}
						else if(el.type == 'radio') {
							var nextElement = formElements[formElements.indexOf(el) + 1];
							do {
								if(!el.checked) {
									valid = false;
								}
								nextElement = formElements[formElements.indexOf(nextElement) + 1];
							}
							while(nextElement.type == 'radio' && nextElement.name == el.name);
						}
					}
					else if(el.nodeName == 'SELECT') {
						valid = el.value != -1;
					}
					else if(el.nodeName == 'TEXTAREA') {
						valid = el.value;
					}
					else if(el.nodeName == 'FIELDSET') {
						valid = 0;
						var inputs = el.getElementsByTagName('input');
						for(var i = 0; i < inputs.length; i++) {
							valid += inputs[i].checked;
						}
					}
				}
				if(!valid) {
					WS.addClass(el, errorClass);
				}
				else if(valid && WS.hasClass(el, errorClass)) {
					WS.removeClass(el, errorClass);
				}
			}
			
			return valid;
		},
		
		/**
		 * Event handler for the form.onsubmit event
		 * 
		 * @return {Boolean} True if all form elements validate, false otherwise
		 */
		validateForm: function() {
			var submit = true;
			
			for(var i = 0; i < formElements.length; i++) {
				if(!this.validateElement(formElements[i])) {
					submit = false;
				}
			}
			
			if(!submit) {
				alert('Er is een fout opgetreden. Controleer of u alle velden juist hebt ingevuld.');
			}
			
			return submit;
		}
	};
};
