/*-----------------------------------------------------------------------------


@author:		Martí Congost
@contact:		marti.congost@whads.com
@organization:	Whads/Accent SL
@since:			August 2007
-----------------------------------------------------------------------------*/

weblib.controls.ValidableForm = function () {
	
	this.__validations = weblib.state.get(this, "validations", []);
	this.__languages = weblib.state.get(this, "languages");
	
	this.onsubmit = function () {
		this.validate();
		if (!this.__valid) {
			return false;
		}
	}

	this.getValue = function (name, language) {		
		var control = this.getControl(name, language);
		return control.getValue();
	}

	this.getFieldName = function (name, language /* optional */) {
		
		if (language) {
			name += "-" + language;
		}

		return name;
	}

	this.getFieldId = function (name, language) {
		return this.getFieldName(name, language) + "-control";
	}

	this.getControl = function (name, language) {
		var selector = "#" + this.getFieldId(name, language);
		var container = weblib.dom.get(this, selector);
		return weblib.dom.get(container, ".control", { excludeRoot: false });
	}

	this.controls = function () {
		return weblib.dom.select(this, ".control");
	}

	this.shouldApply = function (validation, language /* optional */) {
		return true;
	}

	this.isValid = function () {
		return this.errors().length == 0;
	}

	this.errors = function () {
		
		var errors = [];

		for (var i = 0; i < this.__validations.length; i++) {
			
			var validation = this.__validations[i];
						
			if (validation.multiLanguage) {
									
				for (var l = 0; l < this.__languages.length; l++) {

					var language = this.__languages[l];

					if (this.shouldApply(validation, language)) {

						var value = this.getValue(validation.fieldName, language);
						
						if (!validation.test(this, value, language)) {
							errors.push({
								validation: validation,
								language: language,
								value: value
							});
						}
					}
				}
			}
			else if (this.shouldApply(validation)) {
				var value = this.getValue(validation.fieldName);
				if (!validation.test(this, value)) {
					errors.push({
						validation: validation,
						language: language,
						value: value
					});
				}
			}
		}

		this.__valid = (errors.length == 0);
		return errors;
	}

	this.fieldErrors = function () {
		
		var errors = this.errors();
		var fieldErrors = {};

		for (var i = 0; i < errors.length; i++) {

			var error = errors[i];
			var fieldName = this.getFieldName(
				error.validation.fieldName, error.language);

			var errorList = fieldErrors[fieldName];

			if (!errorList) {
				errorList = [];
				fieldErrors[fieldName] = errorList;
			}

			errorList.push(error);
		}

		return fieldErrors;
	}

	this.validate = function () {		
		this.__errorStyle(this);
	}

	this.getErrorStyle = function () {
		return this.__errorStyle;
	}

	this.setErrorStyle = function (errorStyle) {
		
		function normalize(errorStyle) {
			if (typeof(errorStyle) == "string") {
				errorStyle =
					weblib.controls.ValidableForm.errorStyle[errorStyle];
			}

			return errorStyle;
		}

		if (errorStyle instanceof Array) {
			var handlers = [];
			for (var i = 0; i < errorStyle.length; i++) {
				handlers.push(normalize(errorStyle[i]));
			}
			errorStyle = function () {
				for (var i = 0; i < handlers.length; i++) {
					handlers[i].apply(this, arguments);
				}
			}
		}
		else {
			errorStyle = normalize(errorStyle);
		}

		this.__errorStyle = errorStyle;
	}

	this.setErrorStyle(
		weblib.state.get(
			this,
			"errorStyle",
			weblib.controls.ValidableForm.DEFAULT_ERROR_STYLE
		)
	);
}

weblib.dom.bind(".validable", weblib.controls.ValidableForm);

weblib.controls.ValidableForm.errorStyle = {

	summary: function (form) {
		
		var panel = form.__errorPanel;
		var messages = {};

		if (!panel) {			
			var panel = document.createElement("div");
			form.__errorPanel = panel;
			panel.className = "errorPanel";

			var header = document.createElement("div");
			header.className = "errorHeader";
			header.innerHTML = weblib.state.get(form, "text-formErrorsHeader");
			panel.appendChild(header);

			var detail = document.createElement("p");
			detail.className = "errorDetail";
			detail.innerHTML = weblib.state.get(form, "text-formErrorsDetail");
			panel.appendChild(detail);

			panel.__container = document.createElement("ul");
			panel.__container.className = "errors";
			panel.appendChild(panel.__container);

			weblib.dom.prepend(form, panel);
		}
		else {
			weblib.dom.empty(panel.__container);
		}
		
		var errors = form.errors();

		for (var i = 0; i < errors.length; i++) {

			var error = errors[i];
			var msg = error.validation.errorMessage;

			if (!messages[msg]) {
				messages[msg] = true;
				var item = document.createElement("li");
				item.className = "error";
				item.appendChild(document.createTextNode(msg));
				panel.__container.appendChild(item);
			}
		}

		if (!panel.__container.firstChild) {
			form.removeChild(panel);
			form.__errorPanel = null;
		}
	},

	highlight: function (form) {
		
		var fieldErrors = form.fieldErrors();
		var controls = form.controls();
		
		for (var c = 0; c < controls.length; c++) {
			
			var control = controls[c];
			var errors = fieldErrors[control.name];
			
			if (errors && errors.length) {
				weblib.ui.addClass(control, "error");
				if (!control.__prevTitle) {
					control.__prevTitle = control.title;
				}
				control.title = errors[0].validation.errorMessage;
			}
			else {
				weblib.ui.removeClass(control, "error");
				if (control.__prevTitle) {
					control.title = control.__prevTitle;
				}
			}
		}
	}
}

weblib.controls.ValidableForm.DEFAULT_ERROR_STYLE = "highlight";


