/*jslint browser: true, regexp: true, unparam: true, nomen: true, maxerr: 50, indent: 4 */
/*global $:false, getStxt:false, window:false */

var onSubmitHandler;

(function () {
	'use strict';

	var animationFields = [], checkEmail = function (Email) {
		var at = Email.indexOf('@'), c = Email.charAt(at + 1).toLowerCase(), pos = 0,
			countryCodes = '|ad|ae|af|ag|ai|al|am|an|ao|aq|ar|as|at|au|aw|az|ba|bb|bd|be|bf|bg|bh|bi|bj|bm|bn|bo|br|bs|bt|bv|bw|by|bz|ca|cc|cf|cg|ch|ci|ck|cl|cm|cn|co|cr|cs|cu|cv|cx|cy|cz|de|dj|dk|dm|do|dz|ec|ee|eg|eh|er|es|et|eu|fi|fj|fk|fm|fo|fr|fx|ga|gb|gd|ge|gf|gh|gi|gl|gm|gn|gp|gq|gr|gs|gt|gu|gw|gy|hk|hm|hn|hr|ht|hu|id|ie|il|in|io|iq|ir|is|it|jm|jo|jp|ke|kg|kh|ki|km|kn|kp|kr|kw|ky|kz|la|lb|lc|li|lk|lr|ls|lt|lu|lv|ly|ma|mc|md|mg|mh|mk|ml|mm|mn|mo|mp|mq|mr|ms|mt|mu|mv|mw|mx|my|mz|na|nc|ne|nf|ng|ni|nl|no|np|nr|nt|nu|nz|om|pa|pe|pf|pg|ph|pk|pl|pm|pn|pr|pt|pw|py|qa|re|ro|ru|rw|sa|sb|sc|sd|se|sg|sh|si|sj|sk|sl|sm|sn|so|sr|st|su|sv|sy|sz|tc|td|tf|tg|th|tj|tk|tm|tn|to|tp|tr|tt|tv|tw|tz|ua|ug|uk|um|us|uy|uz|va|vc|ve|vg|vi|vn|vu|wf|ws|ye|yt|yu|za|zm|zr|zw|com|edu|gov|int|mil|net|org|arpa|nato|info|biz|sex|xxx|rs|';

		if (Email.indexOf(',') !== -1) {
			if (Email.toLowerCase().indexOf('compuserve.com') !== -1) {
				return getStxt('inACompuserveAddressYouShouldReplaceCommas');
			} else {
				return getStxt('anEmailAddressShouldNotContainCommas');
			}
		}

		if (at === 0) {
			return getStxt('nothingInFrontOfAtSign');
		} else {
			if (at === -1) {
				return getStxt('anEmailAddressShouldContainAtSign');
			}
		}

		if ((c < 'a' || c > 'z') && (c < '0' || c > '9')) {
			return getStxt('behindAtSignShouldBeLetterOrDigit');
		}

		if (Email.indexOf('..', at) !== -1) {
			return getStxt('thereAreTwoDotsAfterTheAtSign');
		}

		for (pos = 0; pos < Email.length; pos += 1) {
			c = Email.charAt(pos).toLowerCase();
			if (c === ' ') {
				return getStxt('thisEmailAddressContainsSpaces');
			}
		}

		for (pos = at + 1; pos < Email.length; pos += 1) {
			c = Email.charAt(pos).toLowerCase();
			if ((c < 'a' || c > 'z') && (c < '0' || c > '9') && c !== '.' && c !== '-') {
				return getStxt('theEmailAddressContainsInvalidChar') + ' "' + c + '"';
			}
		}
		pos = Email.lastIndexOf('.');
		if (pos === -1) {
			return getStxt('theDomainnameDoesntHaveDot');
		}
		c = Email.substring(pos + 1, Email.length).toLowerCase();
		if (countryCodes.indexOf('|' + c + '|') === -1) {
			return getStxt('thereAreNoDomainsEndingWith') + ': ' + c;
		}
		return null;
	}, isValidDutchBankAccount = function (accNum) {
		var i, re_acc_postbank = /^[pP]\d{1,7}$/i, re_acc_bank = /^(\d{9,10}|\d{2,3}.\d{2}.\d{2}.\d{3})$/, productSum = 0;
		if ((accNum.length <= 9 && (accNum.indexOf('p') === 0 || accNum.indexOf('P') === 0)) || accNum.length <= 8) {
			accNum = accNum.replace(/\./g, '');
			if (re_acc_postbank.test(accNum)) {
				return null;
			} else {
				return getStxt('thisIsAnInvalidPostbankNumber');
			}
		}
		if (!re_acc_bank.test(accNum)) {
			return getStxt('thisBankaccountnumberIsInvalid');
		}
		accNum = accNum.replace(/\./g, '');
		accNum = '0' + accNum;
		accNum = accNum.substring(accNum.length - 10);
		for (i = 0; i < accNum.length; i += 1) {
			productSum += (accNum.length - i) * parseInt(accNum.charAt(i), 10);
		}
		if (productSum % 11 !== 0) {
			return getStxt('thisBankaccountnumberIsInvalid');
		}
		return null;
	}, revertToNormal = function () {
		this.style.borderColor = this.style.oldBorderColor;
		this.onkeypress = null;
	}, trim = function (s) {
		while (s.substring(0, 1) === ' ') {
			s = s.substring(1, s.length);
		}
		while (s.substring(s.length - 1, s.length) === ' ') {
			s = s.substring(0, s.length - 1);
		}
		return s;
	}, inputFieldAnimation = function (input) {
		var el = animationFields.length, field = 'animationFields[' + el + ']';
		if (typeof (input.tmpValue) !== 'undefined' && input.tmpValue !== false) {
			return;
		}
		input.tmpValue = input.value;
		animationFields[el] = input;

		if (input.type.substring(0, 6) === 'select') {
			input.focus();
			setTimeout(field + ".blur();", 100);
			setTimeout(field + ".focus();", 200);
			setTimeout(field + ".blur();", 300);
			setTimeout(field + ".value = " + field + ".tmpValue; " + field + ".focus(); " + field + ".tmpValue=false; ", 400);
		} else {
			input.value = '   <  <  <';
			setTimeout(function () {
				input.value = '  <  <  <';
			}, 200);
			setTimeout(function () {
				input.value = ' <  <  <';
			}, 400);
			setTimeout(function () {
				input.value = '<  <  <';
			}, 600);
			setTimeout(function () {
				input.value = '';
				input.value = input.tmpValue;
				input.focus();
				input.tmpValue = false;
			}, 800);
		}
	};

	// The form validator
	onSubmitHandler = function (form) {
		var valType, c, i, element, validationFields, fields, field, title, elName, lastFieldName, val,
			missingElements = [], failedElements = [], melding = [], fieldnames = [], okSoFar = true, sel = false,
			alreadyExists = false, failedMessage = null, reUnderscore = /_/g, numericRegex = /^\d*$/, alphanumericRegex = /\w/;

		if ((typeof $ !== 'undefined') && (typeof $.validator !== 'undefined') && $(form).find('.required').length > 0) {
			return $(form).validate().form();
		} else {
			for (c = 0; c < form.elements.length; c += 1) {
				element = form.elements[c];

				// add [] to mutiple selects if it isn't there (for php form handling)
				if (element.type === 'select-multiple' && element.name.substr(element.name.length - 2, 2) !== '[]') {
					element.name = element.name + '[]';
				}

				if ((element.getAttribute('required') === '1') || (element.getAttribute('required') === 'required')) {
					switch (element.type) {
					case 'select-one':
					case 'select-multiple':
						if (element.selectedIndex === -1 || trim(element.options[element.selectedIndex].value) === '') {
							okSoFar = false;
							missingElements[missingElements.length] = element;
						}
						break;

					case 'checkbox':
						if (!element.checked) {
							okSoFar = false;
							missingElements[missingElements.length] = element;
						}
						break;

					case 'radio':
						for (i = 0; i < form.elements[element.name].length; i += 1) {
							if (form.elements[element.name][i].checked) {
								sel = true;
							}
						}
						if (sel === false) {
							okSoFar = false;
							missingElements[missingElements.length] = element;
						}
						break;
					case 'password':
					case 'text':
					case 'file':
					case 'textarea':
						if (trim(element.value) === '') {
							okSoFar = false;
							missingElements[missingElements.length] = element;
						}
						break;
					}
				}
				valType = element.getAttribute('validation');
				if (valType) {
					validationFields = {};

					// parse the validation string, for possible multiple strings and options in the validation attribute
					if (valType.indexOf(',') > 0) {
						fields = valType.split(',');
						for (i = 0; i < fields.length; i += 1) {
							if (fields[i].indexOf('=') > 0) {
								field = fields[i].split('=');
								validationFields[field[0]] = field[1];
							} else {
								validationFields[fields[i]] = '';
							}
						}
					} else {
						if (valType.indexOf('=') > 0) {
							field = valType.split('=');
							validationFields[field[0]] = field[1];
						} else {
							validationFields[valType] = '';
						}
					}

					if (trim(element.value) !== '' || element.getAttribute('required') === '1') {
						for (i in validationFields) {
							if (typeof validationFields[i] !== 'undefined') {
								title = element.title || element.name;
								val = element.value;
								switch (i.toLowerCase()) {
								case 'email':
									failedMessage = checkEmail(element.value);
									break;

								case 'dutchbankaccount':
									failedMessage = isValidDutchBankAccount(element.value);
									break;

								case 'numeric':
									if (!numericRegex.test(element.value)) {
										failedMessage = title.replace(reUnderscore, ' ') + ' ' + getStxt('canOnlyContainDigits');
									}
									break;

								case 'alphanumeric':
									if (!alphanumericRegex.test(element.value)) {
										failedMessage = title.replace(reUnderscore, ' ') + ' ' + getStxt('canOnlyContainLettersAndDigits');
									}
									break;

								case 'maxlength':
									if (val.length > validationFields[i]) {
										failedMessage = title.replace(reUnderscore, ' ') + ' ' + getStxt('containsToMuchCharsMax') + ' ' + validationFields[i] + '.';
									}
									break;

								case 'minlength':
									if (val.length < validationFields[i]) {
										failedMessage = title.replace(reUnderscore, ' ') + ' ' + getStxt('notEnoughCharsMin') + ' ' + validationFields[i] + '.';
									}
									break;
								}
							}
						}
					}
					if (failedMessage !== null) {
						okSoFar = false;
						element.message = failedMessage;
						failedElements[failedElements.length] = element;
					}
				}
			}
		}

		// check for other things here and set okSoFar to false if something is wrong!
		if (okSoFar) {
			return true;
		}
		if (missingElements.length > 0) {
			for (c = 0; c < missingElements.length; c += 1) {
				if (!missingElements[c].title) {
					missingElements[c].title = missingElements[c].name;
				}
				alreadyExists = false;
				for (i = 0; i < fieldnames.length; i += 1) {
					if (fieldnames[i] === missingElements[c].title) {
						alreadyExists = true;
						break;
					}
				}
				if (!alreadyExists) {
					elName = missingElements[c].title.replace(reUnderscore, ' ');
					fieldnames[fieldnames.length] = elName.replace('[]', '');
				}
			}


			if (fieldnames.length === 1) {
				melding[melding.length] = getStxt('theField') + ' ' + fieldnames[0] + ' ' + getStxt('hasntBeenFilledYet');
			} else {
				lastFieldName = fieldnames.pop();
				melding[melding.length] = getStxt('theFields') + ' ' + fieldnames.join(', ') + ' ' + getStxt('and') + ' ' + lastFieldName + ' ' + getStxt('haventBeenFilledYet');
			}
		}

		for (c = 0; c < failedElements.length; c += 1) {
			melding[melding.length] = failedElements[c].message;
		}
		window.alert(melding.join("\n"));
		for (c = missingElements.length - 1; c >= 0; c -= 1) {
			missingElements[c].style.oldBorderColor = missingElements[c].style.borderColor;
			missingElements[c].style.borderColor = 'red';
			missingElements[c].onkeypress = revertToNormal;
			inputFieldAnimation(missingElements[c]);
		}
		for (c = failedElements.length - 1; c >= 0; c -= 1) {
			failedElements[c].style.oldBorderColor = failedElements[c].style.borderColor;
			failedElements[c].style.borderColor = 'red';
			failedElements[c].onkeypress = revertToNormal;
			inputFieldAnimation(failedElements[c]);
		}
		return false;
	};
}());

