/**
 * @fileoverview ModuleDropdown.js
 * Generates dropdown buttons
 * @author José Fernández Alameda
 * @date 2010 04 20
 */

var Dropdown = jQuery.Class.create({
	/**
	 * Stores the generated HTML code
	 * @type DOM Element
	 */
	_element: null,
	/**
	 * Indicates if the dropdown menu is already shown
	 */
	_isVisible: null,
	/**
	 * Stores the options object
	 * @type Object
	 */
	_options: null,
	/**
	 * Stores the dropdown list element
	 * @type DOM Element
	 */
	_list: null,
	/**
	 * Avoid closing the list, to avoid interaction with the observer on document.body
	 */
	_blockHide: null,
	/**
	 * Determines whether the button is active or not
	 */
	_enabled: true,
	/**
	 * Intializator of the class
	 * @param options {Object} The module options
	 */
	init: function(options) {
		this._processOptions(options);
		this._drawInterface();
		//Generating the dropdown list in case its needed
		if(this._options.dropdown) {
			this._buildDropdownList();
			this._initDropdown();
		}
		else {
			this._buildButton();
		}
	},
	/**
	 * Returns the generated HTML by the code
	 */
	getHtml: function() {
		return this._element;
	},
	/**
	 * Creates the button mode functionalities
	 */
	_buildButton: function() {
		var _this = this;
		this._element.bind("click", function() {
			if(_this._options && _this._enabled) {
				_this._options.callback();
			}
		});
	},
	/**
	 * Processes the options and determines if any of the mandatory attributes is missing
	 */
	_processOptions: function(options) {
		var requiredFields = "label,dropdown";
		//Checking if the required attributes exists on the options
		$.each(requiredFields.split(","),function(index,optionAttribute) {
			if(options[optionAttribute] == null)
				throw "Error, the options attribute '"+optionAttribute+"' is mandatory";
		});
		this._options = options;
	},
	/**
	 * Draws the button interfaces
	 */
	_drawInterface: function() {
		//Creating the button
		this._element = $('<div class="dropdown" ' + (this._options.id ? 'id="'+this._options.id+'"' : '') +'>'+
					   '<div class="dropdown-left"></div>'+
					   '<div class="dropdown-middle"><div class="left" id="label">'+this._options.label+'</div>'+(this._options.dropdown ? '<div class="dropdown-arrow"></div>' : '')+'</div>'+
					   '<div class="dropdown-right"></div></div>');
	},
	/**
	 * Build the dropdown menu (If applicable) that will be displayed when clicking on the
	 * dropdown
	 */
	_buildDropdownList: function() {
		var _this = this;
		var list = $('<ul class="dropdown-list"></ul>');
		$.each(this._options.data, function(index, data) {
			var listElement = $("<li>"+data.label+"</li>");
			list.append(listElement);
			listElement.bind("click",data.callback);
		});
		this._list = list;
		$(document.body).append(list);
		list.hide();
		$(document.body).bind("click", function() {
			if(!_this._blockHide) {
				_this._list.hide();
				_this._isVisible = false;
			}
			else
				_this._blockHide = false;
		});
	},
	/**
	 * Initializes the dropdown behaviour
	 */
	_initDropdown: function() {
		var _this = this;
		this._element.bind("click", function() {
			if(_this._enabled)
				_this._handleDropdownVisualization();
		});
	},
	_handleDropdownVisualization: function() {
		var _this = this;
		if(!this._isVisible) {
			this._list.show();
			this._isVisible = true;
		}
		else {
			this._list.hide();
			this._isVisible = false;
		}
		var position = this._element.position();
		
		this._list.css("left", position.left+'px');
		this._list.css("top", position.top+this._element.height()+'px');
		this._list.css("position", 'absolute');
		this._blockHide = true;
	},
	/**
	 * Enables de button
	 */
	enable: function() {
		this._enabled = true;
		this._element.removeClass("button-disabled");
	},
	/**
	 * Disables de button
	 */
	disable: function() {
		this._enabled = false;
		this._element.addClass("button-disabled");
	},
	setTitle: function(label) {
		$(this._element.find("#label")).text(label);
	}
});
