
window.addEvent('domready', function() {
	//set forms (auto clear input and check)
	$$('form').each(function(e) {
		new jpForm(e, {
			inlineErrorMsg: function() {
				$('compulsory').setStyle('display', 'block');
			},
			afterSending: function() {
				$('compulsory').setStyle('display', 'none');
				$('thankYou').setStyle('display', 'block');
			},
			highlightParent: true
		});
	});
});

var jpForm = new Class({
	form: null,
	fields: [],
	errorMessageContainer: null,
	options: {
		autoClear: true,
		valuesToConsiderNull: [],
		errorMessageContainerTag: 'div',
		errorMessageContainerId: 'jpFrmMessage',
		errorMessage: 'Please fill in all the required fields.',
		autoScrollOnError: false, //in case of error, scroll back to the top of the form (usefull in case the error message displays out of the screen)
		afterSending: null,
		inlineErrorMsg: true, //can optionally be passed a function to execute when an error occurs
		resetButtonClass: 'reset',
		highlightParent: false
	},
	initialize: function(form, options) {
		this.form = $(form);
		if (!this.form) return;
		this.setOptions(options);
		
		if (this.form.hasClass('jpFrmNoInlineErrorMsg')) {
			this.options.inlineErrorMsg = false;
		}
		
		this.errorMessageContainer = $(this.options.errorMessageContainerId);
		
		//get all fields
		this.form.getElements('input, textarea').each(function(e) {
			this.fields.push(new jpField(e, this.options));
		}, this);
		
		//submit event
		this.form.addEvent('submit', function(evt) {this.fireEvent('submit', evt)}.bindWithEvent(this));
		this.addEvent('submit', function(evt) {this.submit(evt)}.bindWithEvent(this));
		
		this.setResetButtons();
	},
	setResetButtons: function() {
		this.form.getElements('.' + this.options.resetButtonClass).each(function(e) {
			e.addEvent('click', function(evt) {
				evt.stop();
				this.reset();
			}.bindWithEvent(this));
		}, this);
	},
	submit: function(evt) {
		//check fields
		var checked = true;
		for (var i = 0; i < this.fields.length; i++) {
			checked *= this.fields[i].check();
		}
		if (checked) {
			for (var i = 0; i < this.fields.length; i++) {
				this.fields[i].clearNullFields();
			}
			if (this.options.afterSending) {
				(this.options.afterSending)(evt, this);
			}
		}
		else {
			new Event(evt).stop();
			if (this.options.inlineErrorMsg) {
				if (typeof this.options.inlineErrorMsg == 'function') {
					typeof this.options.inlineErrorMsg();
				}
				else {
					if (!this.errorMessageContainer) {
						this.errorMessageContainer = new Element(this.options.errorMessageContainerTag, {
							id: this.options.errorMessageContainerId
						});
						this.errorMessageContainer.injectTop(this.form);
					}
					this.errorMessageContainer.set('html', this.options.errorMessage);
				}
				if (this.options.autoScrollOnError) { //go back to the top of the form
					new Fx.Scroll(window, {wheelStops: false, duration: 100}).toElement(this.form);
				}
			}
			else {
				alert(this.options.errorMessage);
			}
		}
	},
	reset: function() {
		this.form.reset();
	}
});
jpForm.implement(new Options, new Events);

var jpField = new Class({
	element: null,
	cleared: false,
	initialValue: '',
	type: null,
	options: {
		autoClear: true,
		valuesToConsiderNull: [], //those values will be considered null
		requiredClass: 'jpFrmRequired',
		errorClass: 'jpFrmError',
		emailClass: 'jpFrmEmail',
		numericClass: 'jpFrmNumeric',
		highlightParent: false
	},
	initialize: function(element, options) {
		this.element = $(element);
		if (!this.element) return;
		this.setOptions(options);
		
		this.initialValue = this.element.value;
		
		var tag = this.element.get('tag');
		if (tag == 'input') {
			this.type = this.element.getAttribute('type') || 'text';
		}
		else {
			this.type = tag;
		}
		
		if (this.options.autoClear && (this.type == 'text' || this.type == 'password')) {
			this.element.addEvent('focus', function() {
				this.clearDefault();
			}.bind(this));
			this.element.addEvent('blur', function() {
				this.setToDefault();
			}.bind(this));
		}
	},
	getValue: function(getActualValue) {
		var value = this.element.value;
		if (!getActualValue) {
			var i = 0;
			while (i < this.options.valuesToConsiderNull.length) {
				if (value == this.options.valuesToConsiderNull[i]) {
					value = '';
					break;
				}
				i++;
			}
		}
		return value;
	},
	clearNullFields: function() {
		this.element.value = this.getValue();
	},
	isRequired: function() {
		return this.element.hasClass(this.options.requiredClass);
	},
	check: function() {
		var checked = true;
		if (this.isRequired()) {
			switch (this.type) {
				case 'text':
				case 'password':
				case 'textarea':
				case 'file':
					var value = this.getValue();
					checked = value != '';
					if (checked) {
						if (this.element.hasClass(this.options.emailClass)) {
							checked = value.match(/.+\@.+\..+/) ? true : false;
						}
						else if (this.element.hasClass(this.options.numericClass)) {
							checked = value.match(/\d+/) ? true : false;
						}
					}
					break;
				case 'checkbox':
					checked = this.element.checked;
					break;
			}
		}
		
		if (!checked) { // highlight field
			(this.options.highlightParent ? this.element.getParent() : this.element).addClass(this.options.errorClass);
		}
		else {
			(this.options.highlightParent ? this.element.getParent() : this.element).removeClass(this.options.errorClass);
		}
		return checked;
	},
	clearDefault: function() {
		if (this.element && !this.cleared) {
			this.element.value = '';
		}
		this.cleared = true;
	},
	setToDefault: function () {
		if (this.getValue(true) == '') {
			this.element.value = this.initialValue;
			this.cleared = false;
		}
	}
});
jpField.implement(new Options);
