﻿// $cmignore

jQuery.fn.validate = function (options, customErrors) {
	jQuery.fn.fieldsWithErrors = function () {
		return this.find('.field').filter(function () {return !!$(this).data('error')});
	}
	jQuery.fn.labelForField = function () {
		// Assuming here that if there's a label without a single dedicated 
		// field i.e. no *for* attribute set, then it represents the main label 
		// for the field, which implicitly contains multiple fields.
		var label = this.closest('.field').find('label[for=""]');
		if (label.length == 0) label = this.closest('.field').find('label');
		return label.text();
	}
	
	var configuration = {
		validationFinished : function (validationWasSuccessful) {}
	}
	
	$.extend(configuration, options);
	
	var validityErrors = {
		'password-confirm' : {'customBlank' : 'Please confirm your password.', 'customConfirm': 'Your passwords must match. Please try again.'},
		'new-email-confirm' : {'customConfirm' : 'Your email addresses must match. Please try again.'},
		'security-answer' : {'customBlank' : 'Please enter your security answer to continue.'},
		'security-question' : {'customBlank' : 'Please choose a security question from the drop-down above.'},
		'screen-name' : {'customBlank' : 'In order to submit ratings and reviews, you’ll need to create a screen name.'},
		'terms-and-conditions' : {'customBlank' : 'You must accept the Terms & Conditions to continue.'},
		'country' : {'customBlank' : 'Please select a country from the drop-down list.'},
		'company-country' : {'customBlank' : 'Please select a country from the drop-down list.'},
		'recaptcha_challenge_field' : {'customBlank' : 'Please enter the words in the box above to continue.'},
		'home-phone' : {'customBlank' : 'Please enter a valid home phone number.'},
		'cell-phone' : {'customBlank' : 'Please enter a valid cell phone number.'},
		'company-address' : {'customBlank' : 'Please enter a valid company address.'},
		'old-email' : {'customBlank' : 'Please enter your old email address to continue.'},
		'new-email' : {'customBlank' : 'Please enter a new email address.'},
		'new-email-confirm' : {'customBlank' : 'Please confirm your new email address.'},
		'old-password' : {'customBlank' : 'Please enter your old password to continue.'},
		'new-password' : {'customBlank' : 'Please enter a new password to continue.'},
		'new-password-confirm' : {'customBlank' : 'Please confirm your new password.'},
		'security-answer-confirm' : {'customConfirm' : 'Please confirm your security answer.'},
		'postal-code' : {'customBlank' : 'Please enter a valid Postal Code'},
		'confirmationCode' : {'customBlank' : 'Please enter your confirmation code.'},
		'account-number' : {
			'customErrors' : [
				{
					'errorMessage' : 'Please enter a valid account number. Your account number must contain 9 numbers.',
					'validate' : function (input) {
						return (input == '' || input.match(/^\d{9}$/));
					}
				}
			]
		},
		'password' : {
			'customErrors' : [
				{
					'errorMessage': 'Your password must contain 6 - 100 characters including at least one letter and number. No special characters.',
					'validate': function (input) {
						var sp_regex = /[^\w\s]/gi;
						return (input.length >= 6 && input.length <= 100 && input.match(/[a-zA-Z]/) && input.match(/[\d]/) && !sp_regex.test(input));
					}
				}
			]
		},
		'new-password' : {
			'customErrors' : [
				{
					'errorMessage': 'Your password must contain 6 - 100 characters including at least one letter and number. No special characters.',
					'validate': function (input) {
						var sp_regex = /[^\w\s]/gi;
						return (input.length >= 6 && input.length <= 100 && input.match(/[a-zA-Z]/) && input.match(/[\d]/) && !sp_regex.test(input));
					}
				}
			]
		},
		'email' : {
			'customBlank' : 'Please enter your email address.',
			'customErrors' : [
				{
					'errorMessage': 'Please use a valid email format. Ex: yourname@address.com.',
					'validate': function (input) {
						var emailRegex = '^\\w+([+\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*\\.(\\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi|travel|tel|pro))$';
						return input.match(emailRegex);
					}
				},
				{
					'errorMessage': 'Your email address exceeds our 100 character limit.',
					'validate': function (input) {
						return (input.length <= 100);
					}
				},
				{
					'errorMessage': 'Please use a valid email format with no spaces. Ex: yourname@address.com.',
					'validate': function (input) {
						return !input.match(/[ ]/);
					}
				}
			]
		},
		'email-feedback' : {
			'customBlank' : 'Test.',
			'customErrors' : [
				{
					'errorMessage': 'Please use a valid email format. Ex: yourname@address.com.',
					'validate': function (input) {
						var emailRegex = '^\\w+([+\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*\\.(\\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi|travel|tel|pro))$';
						return input.match(emailRegex);
					}
				},
				{
					'errorMessage': 'Your email address exceeds our 100 character limit.',
					'validate': function (input) {
						return (input.length <= 100);
					}
				},
				{
					'errorMessage': 'Please use a valid email format with no spaces. Ex: yourname@address.com.',
					'validate': function (input) {
						return !input.match(/[ ]/);
					}
				}
			]
		},
		'new-email' : {
			'customErrors' : [
				{
					'errorMessage': 'Please use a valid email format. Ex: yourname@address.com.',
					'validate': function (input) {
						var emailRegex = '^\\w+([+\\.-]?\\w+)*@\\w+([\\.-]?\\w+)*\\.(\\w{2}|(com|net|org|edu|int|mil|gov|arpa|biz|aero|name|coop|info|pro|museum|mobi|travel|tel|pro))$';
						return input.match(emailRegex);
					}
				},
				{
					'errorMessage': 'Your new email address exceeds our 100 character limit.',
					'validate': function (input) {
						return (input.length <= 100);
					}
				},
				{
					'errorMessage': 'Please use a valid email format with no spaces. Ex: yourname@address.com.',
					'validate': function (input) {
						return !input.match(/[ ]/);
					}
				}
			]
		}
	};
	
	$.extend(validityErrors, customErrors);
	
	var blankRegex = /^\s*$/;
	
	$(this)
		.find('.field')
			.each(function () {
				var field = $(this);
				var inputs = field.find(':input').filter(':visible');
				
				// There would be a more functional way of accomplishing this if
				// JavaScript/jQuery provided proper mapping and injection methods.
				var areInputsBlank = false;
				inputs.each(function () {
					 areInputsBlank = areInputsBlank || (!!$(this).val().match(blankRegex) || $(this).hasClass('default'));
				});
				
				field
					.removeData('error')
					.removeClass('error')
					.find('.error-description').remove().end();
				
				if (inputs.length > 0 && field.is(':visible')) {
					// Unfortunately, blank, required radio buttons and checkboxes require special logic
					if (field.hasClass('required') && inputs.attr('type').match(/^(checkbox|radio)$/) && field.find(':checked').length == 0 && !field.hasClass('simple-error')) {
						var error = (validityErrors[inputs.attr('id')] != null && validityErrors[inputs.attr('id')]['customBlank'] != null) ? 
							validityErrors[inputs.attr('id')]['customBlank'] : 
							((field.find('label[for=""]').text() || field.find('label').text())  + ' is blank.');

						field.data('error', error).addClass('error');
					}
					// Set ONE Error For Radio Buttons.  Add 'simple-error' class to field element
					else if (field.hasClass('required') && field.hasClass('simple-error') && inputs.attr('type').match(/^(checkbox|radio)$/) && field.find(':checked').length == 0) {
						field.data('error', 'Please choose one of the above options').addClass('error');
					}
					// Blank required fields
					else if (field.hasClass('required') && !inputs.attr('type').match(/^(checkbox|radio)$/) && areInputsBlank) {
						var error = (validityErrors[inputs.attr('id')] != null && validityErrors[inputs.attr('id')]['customBlank'] != null) ? 
							validityErrors[inputs.attr('id')]['customBlank'] : 
							('Please enter your ' + $(this).labelForField().toLowerCase() + '.');
						
						field.data('error', error).addClass('error');
					}
					// Custom errors
					else if (validityErrors[inputs.attr('id')] != null && validityErrors[inputs.attr('id')]['customErrors'] != null) {
						var errorTypes = validityErrors[inputs.attr('id')]['customErrors'];
						var input = inputs.val();
						$.each(errorTypes, function () {
							var errorType = this;
							if (!errorType.validate(input)) 
								field.data('error', errorType.errorMessage).addClass('error');
						});
					}
					// Confirmation fields that do not match their associated field
					else if (inputs.attr('id').match(/\-confirm$/)) {
						var original = field.closest('form').find('[id=' + inputs.attr('id').replace('-confirm', '') + ']');
						// Only render this error if the associated field has no errors,
						// e.g. if the Email field is left blank, than there is little
						// reason to point out that the Email Confirmation field doesn't match
						var error = (validityErrors[inputs.attr('id')] != null && validityErrors[inputs.attr('id')]['customConfirm'] != null) ? 
							validityErrors[inputs.attr('id')]['customConfirm'] : 
							(inputs.labelForField() + ' does not match.');
						
						if (!original.closest('.field').data('error') && original.val() != inputs.val())
							field.data('error', error).addClass('error');
					}
				
					if (!!field.data('error') && !field.closest('form').hasClass('simple')) {
						if (field.find('.field-help').length > 0) field.find('.field-help').before('<p class="error-description">' + field.data('error') + '</p>');
						else field.append('<p class="error-description">' + field.data('error') + '</p>');
					} 
				}
				
			});
	
	var validationWasSuccessful = !($(this).fieldsWithErrors().length > 0);
	configuration.validationFinished(validationWasSuccessful);
	
	return validationWasSuccessful;
}
// $/cmignore



