/*
	Script: default.js
		Revised script to accompany revamped Change of Address Form (COAF) website.
		This script utilizes <Validator> and <DatePicker>.
	
	Author:
		Eric Clemmons
		
	License:
		Reserved for use of Whitefence.com, Change of Address Form, and all related sites.
	
*/

window.addEvent('domready', init);

/*
	Function: init
		Instantiates a new <Validator> class that validates the following.
			o E-Mail Address
			o Old Address
			o New Address
	
		It also creates two (2) <DatePicker>s with a range of 90 days.
	
*/

var QueryObject = new Class({
	initialize: function(s){
		var o = {};
		$A(s.replace(/(^.*\?)|(#.*$)/g,'').split('&')).each(function(p){
			p = p.split("=");
			o[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
		});
		return o;
	}
});

function init() {
	$('form').setStyle('display', '');
	$('submit_button').removeProperty('disabled');
	
	var query = new QueryObject(location.search);
	if($defined(query.mrc))
		$('form').adopt(new Element('input', {
			'type': 'hidden',
			'name': 'MRC',
			'value': query.mrc
		}));
	
	$$('#form a[target="_blank"]').addEvent('click', function(e) {
		e.stop();
		window.open(this.href, null, 'width=400,height=300,scrollbars=yes');
		return false;
	});
	
	if($('movedate')) $('movedate').setStyle('display', 'none');
	if($('offers_phone')) $('offers_phone').setStyle('display', 'none').removeClass('required');
	
	var checkboxes = $$('fieldset.step.four input[type="checkbox"]');
	checkboxes.addEvent('click', function() {
		var checked = checkboxes.some(function(item, index) {
			return item.checked;
		});
		(checked) ?
			$('offers_phone').setStyle('display', 'block').addClass('required')
		:
			$('offers_phone').setStyle('display', 'none').removeClass('required').removeClass('address-validation');
	});
	
	if($('offer2')) $('offer2').addEvent('click', function() {
		(this.checked) ? $('movedate').setStyle('display', '') : $('movedate').setStyle('display', 'none');
	});
	if($('home_security_label')) $('home_security_label').setStyle('display', 'none');
	if($('home_security_checkbox')) $('home_security_checkbox').addEvent('click', function() {
		(this.checked) ? $('home_security_label').setStyle('display', '') : $('home_security_label').setStyle('display', 'none');
	});
	
	if($('new_state')) $('new_state').addEvent('change', verifyService);	// New State
	if($('TruGreen')) $('TruGreen').addEvent('change', verifyService);	// TruGreen
	if($('CORT')) $('CORT').addEvent('change', verifyService);		// CORT
	if($('new_apartment') && $('TruGreen')) $('new_apartment').addEvent('change', verifyApartment);
	if($('CDI_NAME_T28')) $('CDI_NAME_T28').setStyle('display', 'none');
	if($('home_improvement')) $('home_improvement').addEvent('click', function() {
		(this.checked) ? $('CDI_NAME_T28').setStyle('display', '') : $('CDI_NAME_T28').setStyle('display', 'none');
	});
	if($('CDI_NAME_T22')) $('CDI_NAME_T22').addEvent('click', function() {
		(this.checked) ? $('simple-save').setStyle('display', '') : $('simple-save').setStyle('display', 'none');
	});
	if($('simple-save')) $('simple-save').setStyle('display', 'none');
	
	$('form').addEvent('submit', function(event) {
		if(!$('offers_phone').hasClass('required')) return true;		
		$('offers_phone').removeClass('error').addClass('address-validation');
		if($('phone_local_number2').value == ($('phone_local_number').value)) {
			$('phone_local_number2').removeClass('error');
			$('offers_phone').addClass('success');
		} else {
			event = new Event(event); event.preventDefault();
			$('phone_local_number2').addClass('error');
			$('offers_phone').addClass('error');
			return false;
		}
	});
			
	var validator = new Validator({phone: '##########'});
	validator.addEmail('CDI_NAME_T23');
	validator.addPhone('phone_local_number');
	validator.addPhone('phone_local_number2');
	validator.addAddress('SDI_ADDY_OLDADDRESS', 'SDI_ADDY_OLDAPT', 'SDI_ADDY_OLDCITY', 'SDI_ADDY_OLDSTATE', 'SDI_ADDY_OLDZIP');
	validator.addAddress('SDI_ADDY_NEWADDRESS', 'SDI_ADDY_NEWAPT', 'SDI_ADDY_NEWCITY', 'SDI_ADDY_NEWSTATE', 'SDI_ADDY_NEWZIP');

	new Calendar('forwarding_date', {
		additionalShowLinks: $('forwarding_date_image'),
		rangeInDays: [5, 90],
		onPick: function() {
			$('move_date').value = $('forwarding_date').value;
		}
	});
	new Calendar('move_date', {
		additionalShowLinks: $('move_date_image'),
		rangeInDays: [5, 90]
	});
	
	hints = $$('label.field-phone').getElement('span.help');
	$$('label.field-phone').getElement('input').each(function(item, index) {
		var hint = hints[index];
		hint.oHTML = hint.innerHTML;

		item.addEvent('keyup', function() {
			var mask = '(###) ###-####';	
			var num = item.value.replace(/\D/gi, '');

			if(num.length == 0) return hint.innerHTML = hint.oHTML;
			
			var i = 0;
			do {
				mask = mask.replace(/\#/i, num.charAt(i));
			} while(num.charAt(++i));
			mask = mask.replace(/\#/g, '');
			var dash = mask.search('-');
			if(num.length < 6) mask = mask.substring(0, dash);
			hint.innerHTML = mask;
		});
	});
}

function verifyApartment() {
	if($('new_apartment').value.length != 0) {
		$('home_security_checkbox').setProperty('disabled', 'disabled').setStyle('display', 'none');
		$('home_security').setStyle('display', 'none');
		$('TruGreen').setProperty('disabled', 'disabled').setStyle('display', 'none');
		$('TruGreen_label').setStyle('display', 'none');
		$('home_improvement').setProperty('disabled', 'disabled').setStyle('display', 'none');
		$('home_improvement_label').setStyle('display', 'none');
		$('CDI_NAME_T28').setStyle('display', 'none');
		$('CDI_NAME_T26').setStyle('disabled', 'disabled').setStyle('display', 'none').getNext().setStyle('display', 'none');
	} else {
		$('home_security_checkbox').removeProperty("disabled").setStyle('display', '');
		$('home_security').setStyle('display', '');
		$('TruGreen').setProperty('disabled', '').setStyle('display', '');
		$('TruGreen_label').setStyle('display', '');
		$('home_improvement').setProperty('disabled', '').setStyle('display', '');
		$('home_improvement_label').setStyle('display', '');
		$('CDI_NAME_T28').setStyle('display', '');
		$('CDI_NAME_T26').setStyle('disabled', '').setStyle('display', '').getNext().setStyle('display', '');
	}
}

function verifyService() {
	/*
		The states that are Not Serviceable for TruGreen are: HI, LA, MT, NV, ND, WY

		The states that are Not Serviceable for CORT are: AK, AL, AR, HI, IA, ID, ME, MS, MT, ND, NE, NH, OR, SC, SD, UT, VT, WV, WY.
	*/
	var state = $('new_state').value;
	var TruGreen = ['HI', 'LA', 'MT', 'NV', 'ND', 'WY'];
	var CORT = ['AK', 'AL', 'AR', 'HI', 'IA', 'ID', 'ME', 'MS', 'MT', 'ND', 'NE', 'NH', 'OR', 'SC', 'SD', 'UT', 'VT', 'WV', 'WY'];
	var Brinks = ['AR','AZ','CA','CO','DC','DE','FL','GA','IL','IN','KS','KY','LA','LA','MA','MD','ME','MI','MN','MO','MS','NC','NH','NJ','OH','OR','PA','RI','SC','TN','TX','VA','WA','WI','WV'];
	var USI = ['AZ','CA','CO','DE','FL','IL','MD','MN','NC','NJ','NV','PA','SC','VA','WV'];

	if($('auto_insurance_checkbox')) {
		$('auto_insurance_checkbox').setProperty('checked', '').setStyle('display', 'none').getNext().setStyle('display', 'none');
		for(i = 0; i < USI.length; i++)
			if(state == USI[i])
				$('auto_insurance_checkbox').setStyle('display', '').getNext().setStyle('display', '');
	}

	if($('home_security_checkbox')) {
		$('home_security_checkbox').setProperty('checked', '').setStyle('display', 'none').getNext().setStyle('display', 'none');
		for(i = 0; i < Brinks.length; i++)
			if(state == Brinks[i] && $('home_security_checkbox').getProperty('disabled') !== 'disabled')
				$('home_security_checkbox').setStyle('display', '')
					.getNext().setStyle('display', '');
	}
	
	if($('TruGreen') && !$('TruGreen').getProperty('disabled')) {
		$('TruGreen').setStyle('display', '');
		$('TruGreen').getNext().setStyle('display', '');
		for(i = 0; i < TruGreen.length; i++)
			if(state == TruGreen[i]) {
				$('TruGreen').checked = ""; 
				$('TruGreen').setStyle('display', 'none');
				$('TruGreen').getNext().setStyle('display', 'none');
			}
	}
	if($('CORT')) {
		$('CORT').setStyle('display', '');
		$('CORT').getNext().setStyle('display', '');
		for(i = 0; i < CORT.length; i++)
			if(state == CORT[i]) {
				$('CORT').checked = ""; 
				$('CORT').setStyle('display', 'none');
				$('CORT').getNext().setStyle('display', 'none');
			}
	}	
}


/*
	Class: Validator
		A class that validates phone numbers, e-mail addresses, and physical/mailing addresses.
		Any input that is required must have the class *required*.
	
	Options:
		phone		-	A template for validating a number.  Default is "(###) ###-####".
		phoneClass	-	Class assigned to each phone that is validated.  Default is "validator_phone".
		form		-	Name of the form (id) to be validated.  Default is "form".
		submit		-	Name of the submit button (id) to begin validation when clicked. Default is "submit".
		onStart		-	Function to call when validation starts.  Useful for indicating that validation is occurring.
		onComplete	-	Function to call when validation ends.
		
	Example:
		(start code)
			<html>
				<body>
					<form id="form">
						<input type="text" id="phone" class="required" value="987 456 1234"/>
						
						<input type="text" id="email" />
						
						<input type="text" id="street" />
						<input type="text" id="apt" />
						<input type="text" id="city" />
						<input type="text" id="state" />
						<input type="text" id="zipcode" />
						
						<input type="submit" id="submit" />
					</form>
				</body>
			</html>
			
			<script>
				var validator = new Validator();
				validator.addEmail('email');
				validator.addPhone('phone');
				validator.addAddress('street', 'apt', 'city', 'state', 'zipcode');			
			</script>
		(end code)

	Notes:
		E-Mail & Address validation are done by an AJAX call to "validate.php".  The name
		of the form fields don't matter, only their presence and order when calling <addAddress>.

*/

var Validator = new Class({
	options: {
		phone: '(###) ###-####',
		phoneClass: 'validator_phone',
		form: 'form',
		submit: 'submit',
		onStart: Class.empty,
		onComplete: Class.empty
	},
	
	/*
		Function: initialize
			Called when <Validator> is first insantiated.
			
		Parameters:
			options	-	Object of options for phone, phoneClass, form, and submit.
	*/
	initialize: function(options) {
		this.setOptions(options);
		var form = $(this.options.form) || document.getElementsByName(this.options.form)[0];
		form.addEvent('submit', (function(event) {
			event = new Event(event); event.preventDefault();
			this._validateForm();
		}).bind(this));
		var submit = $(this.options.submit) || document.getElementsByName(this.options.submit)[0];
		if(submit)
			submit.addEvent('click', form.fireEvent.pass('submit'));
	},
	
	/*
		Function: addPhone
			External function used to add a single element, or multiple elements in the form of an array.
		
		Parameters:
			element(s)	-	ID name of a single or multiple elements to validate.
	
		See Also:
			<_validatePhone>
	*/
	addPhone: function(elements) {
		if($type(elements) != "array")
			elements = [elements];
		$each(elements, function(e) {
			el = $(e) || document.getElementsByName(e)[0];
			el.addEvent('blur', (function() {
				this._validatePhone($(e) || document.getElementsByName(e)[0]);	
			}).bind(this));
		}, this);
	},
	
	/*
		Function: addEmail
			Add an E-Mail for validation.
		
		Parameters:
			element	-	A single ID for the element.  You must call <addEmail> again to add a second element.
		
		See Also:
			<_validateEmail>
	*/
	addEmail: function(element) {
		var input = $(element) || document.getElementsByName(element)[0];
		input.addEvent('blur', this._validateEmail.pass(input));
	},
	
	/*
		Function: addAddress
			Adds an address for validation.  You can pass in fields by NAME or ID.
			
		Parameters:
			street		-	Name or ID for the street address (required).
			apartment	-	Name or ID for the apartment/suite.
			city		-	Name or ID for the city.
			state		-	Name or ID for the state.
			zipcode		-	Name or ID for the zipcode (required).
		
		See Also:
			<_validateAddress>
		
	*/
	addAddress: function(street, apartment, city, state, zipcode) {
		var address = {
			'json': 			'true',
			'streetAddress': 	$(street) || document.getElementsByName(street)[0],
			'city': 			$(city) || document.getElementsByName(city)[0],
			'state': 			$(state) || document.getElementsByName(state)[0],
			'zipcode': 			$(zipcode) || document.getElementsByName(zipcode)[0],
			'apartmentNumber': 	$(apartment) || document.getElementsByName(apartment)[0]
		};
		address.streetAddress.addEvent('blur', this._validateAddress.pass(address, this));
		address.apartmentNumber.addEvent('blur', this._validateAddress.pass(address, this));
		address.city.addEvent('blur', this._validateAddress.pass(address, this));
		address.state.addEvent('change', this._validateAddress.pass(address, this));
		address.zipcode.addEvent('keyup', this._validateAddress.pass(address, this));
		
		if(tmp = $('address-validation-' + address.streetAddress.name))
			tmp.remove();

		var label = new Element('label');
		label.setAttribute('id', 'address-validation-' + address.streetAddress.name);
		label.setStyle('opacity', 0);
		label.addClass('address-validation');
		label.addClass('error');
		label.setHTML("Address Must Be Validated");
		label.injectAfter((address.zipcode).getParent());
		var fade = new Fx.Style(label, 'opacity', {	duration: 500 }).set(0).start(1);
	},
	/*
		Function: _removeAddress
			Internal function that is not being used.  Potentially for when you want to
			remove validation.
	*/
	_removeAddress: function(address) {	},
	/*
		Function: _validatePhone
			Uses regular expressions to strip out non-digits from phone number, then
			replace the pound (#) signs in template with each number.  Extra digits aren't inserted.
			The template is defined in <initailize>'s options by "phone".
	*/
	_validatePhone: function(e) {
		//var field = e.getNext();
		var value = e.value;
		var clean = e.value = value.replace(/\D/gi, ""); // Removes NOT DIGITS
		var string = this.options.phone;
		
		(function() {$(e.id+'-validation').remove();}).attempt();
		
		if(clean == "") return e.removeClass('error').value = "";

		if(clean.length != 10) {
			var label = new Element('label');
			label.setAttribute('id', e.id+'-validation');
			label.setStyle('opacity', 0);
			label.addClass('address-validation');
			e.addClass('error');
			label.addClass('error');
			label.setHTML('Number Must Be 10 Digits.');
			label.setStyles({
				'width': '95%',
				'overflow': 'hidden',
				'clear': 'both'
			});
			label.injectAfter(e.getParent());
			fade = new Fx.Style(label, 'opacity', { duration: 500 }).start(1);
		}
		e.value = clean;
	},
	/*
		Function: _validateEmail
			Internal function that calls "validate.php" to verify the E-Mail address
			using MXRecords.  A "label" tag appears under the input with the validation
			status.  This label tag one of two classes, depending on the status.
				o label #email-validation.error
				o label #email-validation.success
		
		Parameters:
			input	-	The input element (the actual object) to be validated.
	*/
	_validateEmail: function(input) {
		(function() {$('email-validation').remove();}).attempt();
		var label = new Element('label');
		label.setAttribute('id', 'email-validation');
		label.setStyle('opacity', 0);
		label.addClass('address-validation');
		label.addClass('error');
		label.setHTML('Validating E-Mail...');
		label.setStyles({
			'width': '95%',
			'overflow': 'hidden'
		});
		label.injectAfter(input.getParent());
		fade = new Fx.Style(label, 'opacity', { duration: 500 }).start(1);
		
		new Ajax('validate.php', {
			method: 'post',
			data: 'email_address='+encodeURI(input.value),
			autoCancel: true,
			onComplete: function(response) {
				eval(response);

				(function() {$('email-validation').remove();}).attempt();
				var label = new Element('label');
				label.setAttribute('id', 'email-validation');
				label.setStyle('opacity', 0);
				label.addClass('address-validation');
				(validator.num_errors == 0) ? label.addClass('success') : label.addClass('error');
				(validator.num_errors == 0) ? label.setHTML('E-Mail Validated.') : label.setHTML(validator.email_address);
				label.setStyles({
					'width': '95%',
					'overflow': 'hidden'
				});
				label.injectAfter(input.getParent());
				fade = new Fx.Style(label, 'opacity', { duration: 500 }).start(1);
				/*if(validator.num_errors == 0) {
					(function() {
						fade.setOptions({
							duration: 500,
							onComplete: function() { this.element.remove(); }
						});
						fade.start(0);
					}).delay(3000);
				}*/
			}
		}).request();
	},
	
	_revalidateAddress: function(address) {
		address['zipcode'].oValue = null;
		this._validateAddress(address);
	},
	/*
		Function: _validateAddress
			Internal function call validation when the zipcode is 5 digits in length and
			the street address has been altered.  Like <_validateEmail>, this uses
			"validate.php" and inserts a label beneath the address with the current status.
				o label #address-validation-[the street address input's NAME] .address-validation .success
				o label #address-validation-[the street address input's NAME] .address-validation .error
	*/
	_validateAddress: function(address) {
		if ((address.zipcode.value).length < 5 && $('address-validation-'+address.streetAddress.name).hasClass('success'))
			$('address-validation-'+address.streetAddress.name).removeClass('success').addClass('error').setHTML('Address Must Be Validated').oValue = null;
		if ((address.zipcode.value).length < 5 || address.streetAddress.value == "") return;
		
		var addressChanged = function(address) {
			var changed = false;
			for(field in address)
				if(address[field].oValue != address[field].value) changed = true;
			
			if(	address['streetAddress'].oValue != address['streetAddress'].value &&
				address['zipcode'].oValue == address['zipcode'].value) changed = false;
			return changed;
		};
		var saveAddress = function(address) {
			for(field in address) address[field].oValue = address[field].value;
			return true;
		};
		
		if(!addressChanged(address)) return;
		saveAddress(address);
		
		(function(){ $('address-validation-'+address.streetAddress.name).remove(); }).attempt();
		
		var label = new Element('label');
		label.setAttribute('id', 'address-validation-' + address.streetAddress.name);
		label.setStyle('opacity', 0);
		label.addClass('address-validation');
		label.addClass('error');
		label.setHTML("Verifying Address...");
		label.injectAfter((address.zipcode).getParent());
		var fade = new Fx.Style(label, 'opacity', {	duration: 500 }).set(0).start(1);
		
		var query = "";
 		for(field in address)
			query += field + "=" + 	(address[field].value || 
									(($type(address[field]) == 'string') 
										? address[field]
										: ''
									)) + "&";
		query = query.replace(/#/g, '');
		
		new Ajax('validate.php', {
			method: 'get',
			autoCancel: true,
			data: query,
			onFailure: function() {
				$('address-validation-' + address.streetAddress.name)
				.removeClass('error')
				.addClass('success')
				.setHTML('Address assumed correct because of an internal error.');
			},
			onComplete: function(txt) {
				this._updateAddress(txt, address);
			}.bind(this)
		}).request();
	},
	
	_updateAddress: function(txt, address) {
		var addressChanged = function(address) {
			var changed = false;
			for(field in address)
				if(address[field].oValue != address[field].value) changed = true;
			
			if(	address['streetAddress'].oValue != address['streetAddress'].value &&
				address['zipcode'].oValue == address['zipcode'].value) changed = false;
			return changed;
		};
		var saveAddress = function(address) {
			for(field in address) address[field].oValue = address[field].value;
			return true;
		};
		
		try {
			eval(txt);  // Sets "addy" object
		} catch(e) {
			$('address-validation-' + address.streetAddress.name)
			.removeClass('error')
			.addClass('success')
			.setHTML('Address assumed correct because of an internal error.');
			return;
		}
	
		address.streetAddress.value = addy.fields.streetAddress.value;
		address.apartmentNumber.value = addy.fields.aptNumber.value;
		address.city.value = addy.fields.city.value;
		address.state.value = addy.fields.state.value;
		address.zipcode.value = addy.fields.zipcode.value;

		// fix state SELECT element bug (in Win32+FF?)
		if(address.state.type.toLowerCase() == 'select')
			for(st_index = 0; st_index < address.state.length; st_index++)
				if(address.state[st_index].value == addy.fields.state.value)
					address.state.selectedIndex = st_index;

		if(!addressChanged(address)) saveAddress(address);

		// Fix doubled-apartment bug
		if((space = address.apartmentNumber.value.indexOf(" ")) > -1)
			address.apartmentNumber.value = address.apartmentNumber.value.substr(0, space);
			
		var sameStreets = $$('input[type="text"]').filter(function(input, index) {
			return (input.value == addy.fields.streetAddress.value);
		});
		var sameZips = $$('input[type="text"]').filter(function(input, index) {
			return (input.value == addy.fields.zipcode.value);
		});
		
		if((sameStreets.length > 1) && (sameZips.length > 1)) {
			addy.fields.errorcode.value = -1;
			addy.fields.errordesc.value = "Old &amp; New address cannot be the same.";
		}
	

		// Flash them to show they're correct or wrong
		(function() {
			$('address-validation-' + address.streetAddress.name).remove();
		}).attempt();
		var label = new Element('label');
		label.setAttribute('id', 'address-validation-' + address.streetAddress.name);
		label.setStyle('opacity', 0);
		(addy.fields.errorcode.value == 0) ? label.addClass('success') : label.addClass('error');
		label.addClass('address-validation');
		label.setHTML(addy.fields.errordesc.value || "Address Verified");
		
		var klass = this;
		var link = new Element('span', {
			'events': {
				'click': klass._revalidateAddress.pass(address, klass)
			}
		}).setHTML('<br />(<a href="javascript:void(0);">Validate Again</a>)');
		label.adopt(link);
		if(addy.fields.errordesc.prompt == "true") {
			check = new Element('input');
			check.setAttribute('type', 'checkbox');
			check.setStyle('float', 'left');
			//check.addClass('field-checkbox');
			check.injectTop(label);
			check.addEvent('click', function() {
				this.getParent().removeClass('error').addClass('success');
				this.remove();
			});
		}
		label.injectAfter((address.zipcode).getParent());

		/*if(label.hasClass('success')) {
			$each(address, function(o) {
				if($type(o) != 'element') return;
				o.removeEvents();
			});
		}*/

		var fade = new Fx.Style(label, 'opacity', {	duration: 500 }).set(0);
		fade.start(0,1);
		verifyService();
	},
	
	/*
		Function: _validateForm
			Internal function called when "submit" is fired.  This function simply checks each
			input for the class "required" and colors the background yellow if it is empty.
			
	*/
	_validateForm: function(inputs) {
		var form = $(this.options.form) || document.getElementsByName(this.options.form)[0];
		var profanity = {'a1rborne':1,'a1rexpress':1,'adutlsonly':1,'airb0rne':1,'airborne':1,'airexpress':1,'alr0borne':1,'anus':1,'arse':1,'ass':1,'assess':1,'asshole':1,'b00b':1,'b01nk':1,'b0ink':1,'b0ob':1,'b10wj0b':1,'b10wjob':1,'blowj0b':1,'blowjob':1,'b1sexual':1,'b1tch':1,'bastard':1,'baxglobal':1,'bisexual':1,'bitch':1,'b10wjob':1,'bl0wjob':1,'blowjob':1,'bo0b':1,'bo1nk':1,'boink':1,'boob':1,'boobs':1,'breast':1,'breast':1,'bur1ingtonair':1,'burl1ngt0na1r':1,'burl1ngtonair':1,'burlingt0nair':1,'burlingtona1r':1,'burlingtonair':1,'businessexpress':1,'butthead':1,'butthole':1,'c0ca1ne':1,'c0caine':1,'c0ck':1,'cannab1s':1,'cannabis':1,'carnal':1,'cathouse':1,'chink':1,'choot':1,'cl1t':1,'cl1t0r1s':1,'cl1toris':1,'clit':1,'clit0r1s':1,'clit0ris':1,'clitor1s':1,'clitoris':1,'coca1ne':1,'cocaine':1,'cock':1,'cocksucker':1,'crack':1,'crap':1,'crapper':1,'cunn1l1ngus':1,'cunni1ingus':1,'cunnilingus':1,'cunt':1,'d1ck':1,'d1ldo':1,'d1pshit':1,'d1pshit':1,'dago':1,'damn':1,'darky':1,'defecate':1,'deltaairlines':1,'dhl':1,'diarrhea':1,'dickhead':1,'dild0':1,'dildo':1,'dipsh1p':1,'dipshit':1,'dumbass':1,'ejaculate':1,'erotic':1,'erotica':1,'eroticism':1,'fag':1,'fart':1,'fdx':1,'fellati0':1,'fe11atio':1,'fe1lati0':1,'feces':1,'federalexpress':1,'fel1ati0':1,'fellat10':1,'fellat1o':1,'fellatio':1,'foreskin':1,'freebase':1,'fuck':1,'fucker':1,'fuckface':1,'fuckhead':1,'fuckin':1,'fucking':1,'fucks':1,'g0n0rrhea':1,'g0norrhea':1,'g0p0stal':1,'g0postal':1,'gon0rrhea':1,'gonorrhea':1,'gopostal':1,'greyhoundbus':1,'gyne':1,'hardon':1,'hash1sh':1,'he11':1,'he1l':1,'hel1':1,'hell':1,'her0in':1,'heroin':1,'homosexual':1,'ibm':1,'incest':1,'jackoff':1,'jerkoff':1,'k1ke':1,'kiddieporn':1,'kike':1,'kmart':1,'kn0ckers':1,'kn0ckup':1,'knockers':1,'knockup':1,'lsd':1,'m0rph1ne':1,'m0rphine':1,'mailboxesetc':1,'mar1juana':1,'marijuana':1,'masterbate':1,'masturbation':1,'masturbate':1,'masturbation':1,'menstral':1,'menstruation':1,'menstruating':1,'microsoft':1,'morph1ne':1,'morphine':1,'motherfucker':1,'mutherfacker':1,'mutherfucker':1,'n1gger':1,'naked':1,'necrophilia':1,'nigga':1,'nigger':1,'northwest':1,'nude':1,'op1ate':1,'opiate':1,'p0st0ff1ce':1,'p0st0ffice':1,'p0stal':1,'p0stoff1ce':1,'p0stoffice':1,'p1l0talrfre1ght':1,'p1lotalrfreight':1,'p1ss':1,'pakmail':1,'panties':1,'pecker':1,'pedophile':1,'pedophilia':1,'pee':1,'pen1s':1,'penis':1,'pil0tairfreight':1,'pilotairfreight':1,'piss':1,'pissed':1,'pissedoff':1,'porn':1,'pornography':1,'post0ff1ce':1,'post0ffice':1,'postal':1,'postalservice':1,'postoff1ce':1,'postoffice':1,'pussy':1,'queers':1,'rps':1,'sadomasochism':1,'satan':1,'screw':1,'sdhsdsdf':1,'semen':1,'sex':1,'sexual':1,'sexy':1,'sh1t':1,'shit':1,'shitass':1,'shitcan':1,'shithead':1,'shits':1,'shitter':1,'shitty':1,'slope':1,'slut':1,'snuff':1,'sodomize':1,'sodomy':1,'splc':1,'sp1k':1,'spic':1,'spik':1,'streetwalker':1,'strip':1,'striptease':1,'suck':1,'t1t':1,'takeadump':1,'testicle':1,'tit':1,'tits':1,'tittie':1,'titty':1,'topless':1,'transsexual':1,'transvestite':1,'turd':1,'twat':1,'unitedparcel':1,'upms':1,'ups':1,'upyours':1,'ur1ne':1,'urinate':1,'urination':1,'urine':1,'uspostalservice':1,'usps':1,'v1rg1n':1,'v1rgin':1,'vagina':1,'vibrator':1,'virg1n':1,'walmart':1,'wetback':1,'wetdream':1,'wh0re':1,'whore':1};
		if(!inputs) inputs = form.getElements('input');
		var counter = 0;
		var klass = this;
		//var form = $(this.options.form);
		
		$each(inputs, function(input) {
			input.removeClass('error');
			input.setAttribute('tabIndex', '');
			
			switch(input.type) {
				case 'checkbox':
					(function() {
						input.getNext().setStyle('background-color', '#EEF3F9');
					}).attempt();
					if(!input.hasClass('required')) return;
					if(input.hasClass('required') && input.checked) return;
					
					input.getNext().setStyle('background-color', '#ffa');
					//input.setAttribute('tabIndex', ++counter);
					++counter;
					break;
				case 'text':
					if(input.id.contains('name') == true)
						input.value = input.value.replace(/([^A-Za-z0-9-'])+/gi, '');
										
					if($defined(profanity[input.value])) {
						if(!$(input.name+'-validation')) {
							var label = new Element('label');
							label.setAttribute('id', input.name+'-validation');
							label.setStyle('opacity', 0);
							label.addClass('name-validation');
							label.addClass('error');
							label.setStyles({
								'width': '95%',
								'overflow': 'hidden'
							});
							label.injectAfter(input.getParent());
						} else {
							label = $(input.name+'-validation');
						}
						label.setHTML('Name cannot contain profanity.');
						fade = new Fx.Style(label, 'opacity', { duration: 500 }).start(1);
					} else {
						if($(input.name+'-validation')) $(input.name+'-validation').remove();
						if(input.value != '') return;
					}

					if(!input.getParent().hasClass('required')) return;	
					
					if(counter == 0) { input.focus(); } // Selects the first input box
					input.addClass('error');
					++counter;
					//input.setAttribute('tabIndex', ++counter);
					break;
				default:
					this.onComplete;
					return;
			}	
		});
			
		$each($$('label.address-validation'), function(label) {
			if(!label.hasClass('success')) counter++;
		});
		if(counter == 0) {
			$('submit_button').addClass('disabled').setHTML('Please Wait...').setProperty('disabled', 'disabled');
			($(this.options.form) || document.getElementsByName(this.options.form)[0]).submit();
		}
	},

	_insertErrors: function(o) {
		console.log(o);
		$$('label.error').remove();
		$$('label input.error').removeClass('error');
		// o is "validator" object with each field assigned an error
		var counter = 0;
		for(error in o) {
			if(error == "num_errors") continue;
			if(counter == 0) { $(error).focus(); first=false; } // Selects the first input box

			$(error).addClass('error');
			//$(error).setAttribute('tabIndex', ++counter);
			span = new Element('label');
			span.innerHTML = o[error].replace(" ", "&nbsp;");
			span.setAttribute('id', error+"_error");
			span.addClass('error');
			span.injectAfter($(error).getParent());
			span.setStyle('opacity', 0);
			new Fx.Style(span, 'opacity').start(0,1);

			counter++;
		}
	}
});
Validator.implement(new Options);
