/**
 * @author hrw7
 * @version 1.0
 */

ILR.namespace("Widget");

if( !ILR.Widget.TextInput ) {
	
	/**
	 * Provides an editable text field.
	 * @namespace ILR.Widget
	 * @class TextInput
	 * @constructor
	 * @param {String} textEl The text field element id OR
	 * @param {HTMLElement} textEl The text field element
	 * @param {String} inputEl The input field element id OR
	 * @param {HTMLElement} inputEl The input field element
	 */
	ILR.Widget.TextInput = function(textEl, inputEl, config) {
		if( YAHOO.lang.isString(textEl) ) {
			textEl = document.getElementById(textEl);
		}
		
		if( YAHOO.lang.isString(inputEl) ) {
			inputEl = document.getElementById(inputEl);
		}
		
		this.textEl = textEl;
		this.inputEl = inputEl;
		
		apply(this, config);
		
		this.initEvents();
		this.synchronize(this.textEl.innerHTML);
		
		YAHOO.util.Event.addListener(this.textEl, "click", this.handleClickText, this, true);
		YAHOO.util.Event.addListener(this.inputEl, "blur", this.handleBlurInput, this, true);
		YAHOO.util.Event.addListener(this.extraFields, "click", this.handleClickText, this, true);
	};
	
	ILR.Widget.TextInput.prototype = {
		/**
		 * The text module.
		 * @property textEl
		 * @type HTMLElement
		 */
		textEl: null,
		
		/**
		 * The input module.
		 * @property inputEl
		 * @type HTMLElement
		 */
		inputEl: null,
		
		/**
		 * The extra clickable fields.
		 * @property extraFields
		 * @type Array
		 */
		extraFields: [],
		
		/**
		 * Whether or not this input accepts empty strings.
		 * @property allowNull
		 * @type Boolean
		 */
		allowNull: true,
		
		/**
		 * Initializes the custom events.
		 * @method initEvents
		 */
		initEvents:function() {
			/**
			 * CustomEvent fired when the text becomes visible and the input is hidden
			 * @event textVisibleEvent
			 */
			this.textVisibleEvent = new YAHOO.util.CustomEvent("textVisible", this);
			
			/**
			 * CustomEvent fired when the input becomes visible and the text is hidden
			 * @event textVisibleEvent
			 */
			this.inputVisibleEvent = new YAHOO.util.CustomEvent("inputVisible", this);
			
			/**
			 * CustomEvent fired when the the value is changed via the input
			 * @event changeValueEvent
			 */
			this.changeValueEvent = new YAHOO.util.CustomEvent("inputVisible", this);
		},
		
		/**
		 * Handles the event when a user clicks on the text element.
		 * @method handleClickText
		 * @param {Event} ev The event
		 */
		handleClickText:function(ev) {
			this.clickText();
		},
		
		/**
		 * Handles the event when a user blurs the input element.
		 * @method handleBlurInput
		 * @param {Event} ev The event
		 */
		handleBlurInput:function(ev) {
			this.blurInput();
		},
		
		/**
		 * Synchronizes the input with the text field and updates the display.
		 * @method synchronize
		 * @param {String} value Optional value to set the textinput to
		 */
		synchronize:function(value) {
			if( YAHOO.lang.isString(value) ) {
				value = value.trim();
				this.setValue(value);
			}
			
			if( this.getValue().trim() == "" ) {
				this.showInput();
			} else {
				this.showText();
			}
		},
		
		/**
		 * Set the value of the input and text field.
		 * @method setValue
		 * @param {String} value The value
		 */
		setValue:function(value) {
			value = value.trim();
			
			if( this.textEl.value != value ) {
				this.changeValueEvent.fire(value);
			}
			
			this.textEl.innerHTML = value;
			this.inputEl.value = value;
		},
		
		/**
		 * Return the current value of the text field.
		 * @method getValue
		 * @return {String} The current innerHTML of the text field
		 */
		getValue:function() {
			return this.textEl.innerHTML;
		},
		
		/**
		 * Handles when a user clicks on the text element or an extra field.
		 * @method clickText
		 */
		clickText:function() {
			this.setValue(this.textEl.innerHTML);
			
			this.showInput();
			this.inputEl.focus();
		},
		
		/**
		 * Handles when a user blurs the input element.
		 * @method blurInput
		 */
		blurInput:function() {
			if( this.inputEl.value.trim() == "" ) {
				if( !this.allowNull ) {
					alert("Must enter a non-blank value.");
					this.synchronize(this.textEl.innerHTML);
					return;
				} else {
					this.synchronize(this.inputEl.value);
					return;
				}
			}
			
			this.synchronize(this.inputEl.value);
			
			this.showText();
		},
		
		/**
		 * Shows the text field, hides the input field.
		 * @method showText
		 */
		showText:function() {
			YAHOO.util.Dom.removeClass(this.textEl, "hidden");
			YAHOO.util.Dom.addClass(this.inputEl, "hidden");
			
			this.textVisibleEvent.fire(this.inputEl.value);
		},
		
		/**
		 * Shows the input field, hides the text field.
		 * @method showText
		 */
		showInput:function() {
			YAHOO.util.Dom.addClass(this.textEl, "hidden");
			YAHOO.util.Dom.removeClass(this.inputEl, "hidden");
			
			this.inputVisibleEvent.fire(this.textEl.innerHTML);
		}
	};
}