﻿/* Copyright by Steen F. Tøttrup, CreativeMinds (http://creativeminds.dk) */
CreativeMinds.Form = new Class({Extends: CreativeMinds, Implements: [Options, Events], options: {form: $empty, focusOnFirst: true, ajaxSubmit: false, statusBar: $empty, destination: $empty, type: 'append', reset: false},
	form: $empty, elements: $empty, failedElements: $empty, requestFailure: false,
	html: '',

	initialize: function(options) {
		this.setOptions(options);
		if (this.options.form && this.options.form != $empty) {
			this.form = this.options.form;
			this.elements = new Array();
			this.form.addEvent('submit', this.OnSubmit.bind(this));
		}
		else {
			throw new Error('No form provided.');
		}
	},
	OnSubmit: function(e) {
		this.failedElements = new Array();
		var formValid = true;
		this.elements.each(function(element) {
			element.HideErrors();
			if (!element.Validate()) {
				this.failedElements[this.failedElements.length] = element;
				formValid = false;
			}
		}.bind(this));
		
		if (!formValid) {
			new Event(e).stop();
			if (this.options.focusOnFirst) {
				this.failedElements[0].element.focus();
			}
			this.ShowFailures();
		}
		else {
			if (this.options.ajaxSubmit) {
				new Event(e).stop();
				this.success = false;
				e.target.set('send', {onFailure: this.Failure.bind(this), onSuccess: this.Success.bind(this), onComplete: this.Complete.bind(this)});
				// TODO: onError/onFailure/onSuccess ?!?!?
				if (this.options.statusBar != $empty) {
					this.options.statusBar.ShowStatus();
				}
				e.target.send('/ajaxcontent.ajax');
			}
			else {
				// Regular submit, time to let the form submit itself!!
			}
		}
	},
	Failure: function(e) {
		// TODO: Something a bit more permanent
		// TODO: e.status == 500
		/*if (e.status == 500) {
			alert('The request failed, please try again later.');
		}*/
		alert('The request failed, please try again later. ' + e.statusText);
		requestFailure = true;
	},
	ShowFailures: function() {
		this.failedElements.each(function(item, index) {
			item.ShowErrors();
		});
	},
	AddElement: function(element) {
		this.elements[this.elements.length] = element;
	},
	GetElement: function(index) {
		return this.elements[index];
	},
	Complete: function(tree, elements, html, js) {
	},
	Success: function(response) {
		if (response.indexOf('<error>') == 0) {
			this.fireEvent('failure', response.substr('<error>'.length, response.length - '<error>'.length - '</error>'.length));
			if (this.options.statusBar != $empty) {
				this.options.statusBar.HideStatus('Failed');
			}
		}
		else {
			if (this.options.destination != $empty && this.options.destination) {
				var newContent = response;
				if (this.options.type == 'append') {
					newContent = this.options.destination.get('html') + newContent;
				}
				if (this.options.statusBar != $empty && this.options.statusBar) {
					this.options.statusBar.HideStatus();
				}
				this.options.destination.set('html', newContent);
			}
			else {
				if (this.options.statusBar != $empty && this.options.statusBar) {
					this.options.statusBar.HideStatus();
				}
			}
			if (this.options.reset) {
				this.form.reset();
			}
			this.fireEvent('success', response);
		}
	}
});
CreativeMinds.FormElement = new Class({Extends: CreativeMinds, Implements: Options, options: {element: $empty},
	element: $empty, validations: $empty, failedValidations: $empty, errorElement: $empty, errorShown: false, errorMessages: $empty,

	initialize: function(options) {
		this.setOptions(options);
		if (this.options.element && this.options.element != $empty) {
			this.element = this.options.element;
			this.validations = new Array();
		}
		else {
			throw new Error('No element found!');
		}
	},
	AddValidation: function(validation) {
		this.validations[this.validations.length] = validation;
		validation.SetElement(this);
	},
	Validate: function() {
		this.errorMessages = new Array();
		this.failedValidations = new Array();
		var elementValid = true;
		this.validations.each(function(element) {
			if (!element.Valid()) {
				this.failedValidations[this.failedValidations.length] = element;
				this.errorMessages[this.errorMessages.length] = element.errorMessage;
				elementValid = false;
			}
		}.bind(this));
		return elementValid;
	},
	GetType: function() {
		return this.element.tagName.toLowerCase();
	},
	GetSubType: function() {
		if (this.element.tagName.toLowerCase() != 'input') {
			throw new Error('Element type is not input, so no subtype!');
		}
		return this.element.type.toLowerCase();
	},
	HideErrors: function() {
		if (this.errorShown) {
			this.errorElement.setStyle('opacity', '0');
			this.errorElement.destroy();
			this.errorElement = $empty;
			this.errorShown = false;
		}
	},
	ShowErrors: function() {
		this.HideErrors();
		// TODO: Prettyfy!
		this.errorElement = new Element('div', {'class': 'error', 'styles': {'border': 'solid 1px black', 'opacity': 0, 'position': 'absolute', 'float': 'left', 'top': this.element.getCoordinates().top, 'left': this.element.getCoordinates().right}}).injectBefore(this.element);
		var error = '';
		for (i = 0; i < this.errorMessages.length; i++) {
			error += this.errorMessages[i];
		}
		this.errorElement.set('html', error);
		this.errorElement.setStyle('opacity', 1);
		this.errorShown = true;
	}
});
/* type: required, integer, between, alpha, alphanum, email, url, radioselect, checkboxselect, dropdownnotfirst, multiselected */
CreativeMinds.Validation = new Class({Extends: CreativeMinds, Implements: Options, options: {type: '', errorMessage: 'Validation failed', upper: 10000, lower: 0},
	element: $empty, errorMessage: '',
	type: '',

	initialize: function(options) {
		this.setOptions(options);
		this.errorMessage = this.options.errorMessage;
		this.type = this.options.type;
	},
	Valid: function() {
		var valid = false;
		var elementType = this.element.GetType();
		if (elementType == 'input') {
			var subType = this.element.GetSubType();
			if (subType == 'text') {
				valid = this.ValidateTextBox();
			}
			else if (subType == 'password') {
				valid = this.ValidatePassword();
			}
			else if (subType == 'radio') {
			}
			else if (subType == 'checkbox') {
			}
			else if (subType == 'submit' || subType == 'image' || subType == 'file') { }
		}
		else if (elementType == 'select') {
			valid = this.ValidateDropDown();
		}
		else if (elementType == 'textarea') {
			valid = this.ValidateTextArea();
		}
		else {
			throw new Error('Unknown element type ' + elementType);
		}
		return valid;
	},
	ValidateRequiredTextStyle: function(value) {
		return value.length != 0;
	},
	ValidateTextBox: function() {
		var value = this.element.element.value.trim();
		if (this.options.type == 'required') {
			return this.ValidateRequiredTextStyle(value);
		}
		else if (this.options.type == 'email') {
			return IsValidEmail(value);
		}
		else if (this.options.type == 'url') {
			// TODO:
			return false;
		}
		else if (this.options.type == 'integer') {
			return ValueIsInteger(value);
		}
		//else if (this.options.type == 'between') {
			//return ValueIsInteger(value);
		//}
		// TODO:
		return false;
	},
	ValidatePassword: function() {
		if (this.options.type == 'required') {
			return this.ValidateTextBox();
		}
		// TODO:
		return false;
	},
	ValidateDropDown: function() {
		if (this.options.type == 'dropdownnotfirst') {
			return (this.element.element.selectedIndex > 0);
		}
		else if (this.options.type == 'multiselected') {
			// TODO:
			return (this.element.element.selectedIndex > -1);
		}
		return false;
	},
	ValidateTextArea: function() {
		if (this.options.type == 'required') {
			return this.ValidateTextBox();
		}
		// TODO:
		return false;
	},
	SetElement: function(element) {
		this.element = element;
	}
});