// FieldController.class.js (Fertile Form JS Framework) || Version: 0.23 || Last Updated: 2011-07-25 17:00 || Updated by: Hidde-Finne Peters || Created: 2010-08-23 by Hidde-Finne Peters
//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------

var FieldController = Class.extend({
	
	init: function (field_name, form_id) {
		
		//	Attributes
		this.fieldName 		= field_name;
		this.formId 		= form_id;
		this.field 			= null;
		this.supportElement = null;
		this.conditions 	= Array();
		this.used 			= false;
		this.valid 			= null;
		this.feedback 		= '';
		
		$('document').ready($.proxy(this.documentReady, this));
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	--- documentReady ------------------------------------------------------------------------------------------	0.22
	//	------------------------------------------------------------------------------------------------------------
	//	Called after the document.ready event was triggered (when the page has finished loading and all physical objects are accesable) or if the document has already been loaded called immediatly.

	documentReady: function () {
		
		//	formIdentifier
		
		var formIdentifier = '';
		if (this.formId) {
			formIdentifier = '#'+ this.formId +' ';
		}
		
		//	field
		
		//	field - input
		this.field = $(formIdentifier +'input[name='+ this.fieldName +']');
		//	field - textarea
		if (this.field.length == 0) {
			this.field = $(formIdentifier +'textarea[name='+ this.fieldName +']');
		}
		//	field - select
		if (this.field.length == 0) {
			this.field = $(formIdentifier +'select[name='+ this.fieldName +']');
		}
		//	field - null
		if (this.field.length == 0) {
			this.field = null;
			alert('Field "'+ this.fieldName +'" not found!');
		}
		
		//	supportElement
		
		if (this.formId) {
			this.supportElement = $('#'+ this.formId +' #'+ this.fieldName +'_support');
		} else {
			this.supportElement = $('#'+ this.fieldName +'_support');	
		}
		if (this.supportElement.length == 0) {
			this.supportElement = null;
		}
		
		//
		
		if (this.field) {
			$(this.field).bind('focusin', $.proxy(this.fieldFocusInHandler, this));
			$(this.field).bind('focusout', $.proxy(this.fieldFocusOutHandler, this));
		}
		
		for (var i = 0; i < this.conditions.length; i++) {
			this.conditions[i].setField(this.field);
		}
		
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	------------------------------------------------------------------------------------------ documentReady ---
	//	------------------------------------------------------------------------------------------------------------
	
	//	------------------------------------------------------------------------------------------------------------
	//	--- fieldFocusHandlers -------------------------------------------------------------------------------------	0.22
	//	------------------------------------------------------------------------------------------------------------
	
	fieldFocusInHandler: function () {
		this.setHasFocus(true);
	},
	
	fieldFocusOutHandler: function () {
		this.setUsed(true);
		this.setHasFocus(false);
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	------------------------------------------------------------------------------------- fieldFocusHandlers ---
	//	------------------------------------------------------------------------------------------------------------
	
	//	------------------------------------------------------------------------------------------------------------
	//	--- addCondition -------------------------------------------------------------------------------------------	0.00
	//	------------------------------------------------------------------------------------------------------------
	
	addCondition: function (condition) {
		if (condition) {
			$(condition).bind('validChange', $.proxy(this.conditionValidChangeHandler, this));
			this.conditions.push(condition);
			if (this.field) {
				condition.setField(this.field);
			}
		}
	},
	
	//	------------------------------------------------------------------------------------------------------------

	//	------------------------------------------------------------------------------------------- addCondition ---
	//	------------------------------------------------------------------------------------------------------------
	
	//	------------------------------------------------------------------------------------------------------------
	//	--- removeCondition ----------------------------------------------------------------------------------------	0.00
	//	------------------------------------------------------------------------------------------------------------
	
	removeCondition: function (condition) {
		if (condition) {
			//	Replace with .indexOf() as soon as IE7 is ambigious (does not support it...)
			var index = -1;
			for (var i = 0; i < this.conditions.length; i++) {
				if (condition === this.conditions[i]) {
					index = i;
				}
			}

			if (index > -1) {
				$(condition).unbind('validChange', $.proxy(this.conditionValidChangeHandler, this));
				this.conditions.splice(index, 1);
				condition.setValid(null);	// Ensure the valid is reset so next change (to both true and false) will trigger a validChange event.
				this.updateValid();
			}
		}
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	---------------------------------------------------------------------------------------- removeCondition ---
	//	------------------------------------------------------------------------------------------------------------
	
	//	------------------------------------------------------------------------------------------------------------
	//	--- conditionValidChangeHandler ----------------------------------------------------------------------------	0.00
	//	------------------------------------------------------------------------------------------------------------
	
	conditionValidChangeHandler: function () {
		this.updateValid();
		this.updateFeedback();
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	---------------------------------------------------------------------------- conditionValidChangeHandler ---
	//	------------------------------------------------------------------------------------------------------------

	//	------------------------------------------------------------------------------------------------------------
	//	--- hasFocus -----------------------------------------------------------------------------------------------	0.22
	//	------------------------------------------------------------------------------------------------------------
	
	setHasFocus: function (value) {
		if (value != this.hasFocus) {
			this.hasFocus = value;
			this.updateLayout();
			$(this).trigger('hasFocusChange');
		}
	},
	
	getHasFocus: function () {
		return this.hasFocus;	
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	----------------------------------------------------------------------------------------------- hasFocus ---
	//	------------------------------------------------------------------------------------------------------------

	//	------------------------------------------------------------------------------------------------------------
	//	--- valid --------------------------------------------------------------------------------------------------	0.20
	//	------------------------------------------------------------------------------------------------------------
	
	setValid: function (value) {
		if (value != this.valid) {
			this.valid = value;
			this.updateLayout();
			$(this).trigger('validChange');
		}
	},
	
	getValid: function () {
		return this.valid;	
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	-------------------------------------------------------------------------------------------------- valid ---
	//	------------------------------------------------------------------------------------------------------------

	//	------------------------------------------------------------------------------------------------------------
	//	--- used ---------------------------------------------------------------------------------------------------	0.20
	//	------------------------------------------------------------------------------------------------------------
	//	True after user has "used" the field (focus out)
	
	setUsed: function (value) {
		if (value != this.used) {
			this.used = value;
			this.updateLayout();
			$(this).trigger('usedChange');
		}
	},
	
	getUsed: function () {
		return this.used;
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	--------------------------------------------------------------------------------------------------- used ---
	//	------------------------------------------------------------------------------------------------------------

	//	------------------------------------------------------------------------------------------------------------
	//	--- getFeedback --------------------------------------------------------------------------------------------	0.00
	//	------------------------------------------------------------------------------------------------------------
	
	setFeedback: function (value) {
		if (value != this.feedback) {
			this.feedback = value;
			$(this).trigger('feedbackChange');
		}
	},
	
	getFeedback: function () {
		//if (!this.valid) {
		//	//	Return first found invalid condition's feedback
		//	for (var i = 0; i < this.conditions.length; i++) {
		//		if (!this.conditions[i].getValid()) {
		//			return this.conditions[i].getFeedback();
		//		}
		//	}
		//}
		//return '';
		return this.feedback;
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	-------------------------------------------------------------------------------------------- getFeedback ---
	//	------------------------------------------------------------------------------------------------------------

	//	------------------------------------------------------------------------------------------------------------
	//	--- update -------------------------------------------------------------------------------------------------	0.00
	//	------------------------------------------------------------------------------------------------------------
	//	Methods called to change properties dynamically
	
	//	Reanalyze situation and set property "this.valid" accordingly
	updateValid: function () {
		for (var i = 0; i < this.conditions.length; i++) {
			if (this.conditions[i].field) {		//	Before initialization the conditions won't have their field yet and will throw an exception
				this.conditions[i].updateValid();
				if (!this.conditions[i].getValid()) {
					this.setValid(false);
					return;
				}
			}
		}
		this.setValid(true);
	},
	
	//	Reanalyze situation and set property "this.feedback" accordingly
	updateFeedback: function () {
		for (var i = 0; i < this.conditions.length; i++) {
			if (this.conditions[i].field) {		//	Before initialization the conditions won't have their field yet and will throw an exception
				this.conditions[i].updateValid();
				if (!this.conditions[i].getValid()) {
					var feedback = this.conditions[i].getFeedback();
					if (feedback.length > 0) {
						this.setFeedback(feedback);
						return;
					}
				}
			}
		}
		this.setFeedback('');
	},
	
	//	------------------------------------------------------------------------------------------------------------
	//	------------------------------------------------------------------------------------------------- update ---
	//	------------------------------------------------------------------------------------------------------------
	
	//	------------------------------------------------------------------------------------------------------------
	//	--- updateLayout -------------------------------------------------------------------------------------------	0.00
	//	------------------------------------------------------------------------------------------------------------

	updateLayout: function () {
		//	field
		if (this.field) {
			//	valid
			if (this.getValid() || !this.getUsed()) {
				//	invalid -> valid
				this.field.removeClass('invalid');
				this.field.addClass('valid');
			} else {
				//	valid -> invalid
				this.field.removeClass('valid');
				this.field.addClass('invalid');
			}
			//	focus
			if (this.getHasFocus()) {
				this.field.addClass('focus');
			} else {
				this.field.removeClass('focus');
			}
		}
		//	supportElement
		if (this.supportElement) {
			//	valid
			if (this.getValid() || !this.getUsed()) {
				//	invalid -> valid
				this.supportElement.removeClass('invalid');
				this.supportElement.addClass('valid');
			} else {
				//	valid -> invalid
				this.supportElement.removeClass('valid');
				this.supportElement.addClass('invalid');
			}
			//	focus
			if (this.getHasFocus()) {
				this.supportElement.addClass('focus');
			} else {
				this.supportElement.removeClass('focus');
			}
		}
		
	}
	
	//	------------------------------------------------------------------------------------------------------------
	//	------------------------------------------------------------------------------------------- updateLayout ---
	//	------------------------------------------------------------------------------------------------------------
	
});
