var Validation = Class.create({
	initialize: function (element) {
		this.element = $(element);
		this.form_elements = this.element.getInputs();
		this.validation_rules = {
			email: {
				message: 'Please enter a valid email address',
				regex: /^[A-Za-z\/-9!#-'*+\-\/=?_`{-~\^]([A-Za-z.-9!#-'*+\-\/=?_`{-~\^]*[A-Za-z\/-9!#-'*+\-\/=?_`{-~\^])?@([A-Za-z0-9]+\.)+[A-Za-z0-9]+\.?$/i
			},
			phone: {
				message: 'Sorry, but your phone number doesn\'t look valid',
				regex: /^[0-9\s\(\)\+#\-\*]{6,21}$/i
			},
			date: {
				message: 'The date should be in the format dd/mm/yyyy',
				regex: /^[0-3][0-9]\/[0-1][0-9]\/[12][0-9]{3}\/$/
			},
			match: {
				message: 'No matching forms',
				regex: /^validate\-match\-([A-Za-z0-9_\-]+?)$/
			}
		};
		
		this.element.observe('submit', function (event) {
			// event.stop();
			var invalid_elements = this.form_elements.inject($A(), function (accumulator, input) {
				input = $(input);
				var is_valid_element = true,
				tag_name = input.tagName.toLowerCase();
				
				switch (tag_name) {
				case 'input':
					is_valid_element = (this.checkBlank(input) && this.checkEmail(input) && this.checkMatch(input)) ? true : false;
					break;
				case 'textarea':
					is_valid_element = (this.checkBlank(input)) ? true : false;
					break;
				case 'select':
					is_valid_element = (this.checkFirst(input)) ? true : false;
					break;
				default:
					is_valid_element = (this.checkBlank(input)) ? true : false;
					break;
				}
				
				
				if (is_valid_element) {
					input.clearError();
				} else {
					accumulator.push(input); }
				
				return $A(accumulator);
			}, this);
			
			if (invalid_elements.length > 0) {
				event.stop();
				alert('Please fill in all of the required fields.')
				invalid_elements.first().activate();
				window.scrollBy(0, -20);
			}
		}.bindAsEventListener(this));
		
		this.element.observe('reset', this.reset.bindAsEventListener(this));
		
		return this;
	},
	
	checkBlank: function (input) {
		input = $(input);
		console.log(input);
		if (input.hasClassName('required')) {
			if (input.readAttribute('type') === 'checkbox') {
				if (!input.checked) {
					input.errorMessage();
					return false;
				}
			} else {
				if ($F(input).blank()) {
					input.errorMessage();
					return false;
				}
			}
		}
		
		return true;
	},
	
	checkFirst: function (input) {
		input = $(input);
		if (input.hasClassName('validate-selection')) {
			if ($F(input) === input.down('option').readAttribute('value')) {
				input.errorMessage();
				return false;
			}
		}
		
		return true;
	},
	
	checkEmail: function (input) {
		input = $(input);
		if (input.readAttribute('type') === 'text' && input.hasClassName('validate-email')) {
			if (!(this.validation_rules.email.regex).test($F(input))) {
				input.errorMessage();
				return false;
			}
		}
		
		return true;
	},
	
	checkMatch: function (input) {
		input = $(input);
		var classes = $w(input.className),
		regex = this.validation_rules.match.regex;
		
		var matches = classes.inject(true, function (accumulator, class_name) {
			if (regex.test(class_name)) {
				var field = class_name.replace(regex, "$1");
				if (!$(field) || $F(input) !== $F(field)) {
					input.errorMessage();
					return false;
				}
			}
			
			return accumulator;
		}, this);
		
		return matches;
	},
	
	reset: function () {
		this.invalid_elements = 0;
		this.form_elements.each(function (input) {
			return $(input).clearError();
		}, this);
	}
});

Object.extend(Form.Element.Methods, {
	errorMessage: function (element) {
		element = $(element);
		if (element.up('p')) {
			$(element).up('p').addClassName('error_message');
		}
		
		return element;
	},
	
	clearError: function (element) {
		element = $(element);
		if (element.up('p')) {
			$(element).up('p').removeClassName('error_message');
		}
		
		return element;
	}
});

Element.addMethods();