/**
 * Objeto de menus do Qualitor.
 * 
 * @author Guilherme Dalla Rosa
 */
function QMenu(menuName) {
	// Atributos da classe.
	this.menuName = menuName;
	this.caption = '';
	this.tableSize = '220';
	this.imagePath = pathWeb + '/framework/images/default/16/';

	// Array de controle de opções desabilitadas.
	this.arrayDisabledOptions = [];

	// Controlador de index dos separadores.
	this.separatorIndex = 0;

	/**
	 * Seta o caption do menu.
	 */
	this.setMenuCaption = function(menuCaption) {
		this.caption = menuCaption;
	};

	/**
	 * Seta a largura do menu.
	 */
	this.setTableSize = function(tableSize) {
		this.tableSize = tableSize;
	};

	/**
	 * Cria um objeto. 
	 */
	this._createObject = function(objectType, objectParameters) {
		// Cria o elemento.
		var objectElement = document.createElement(objectType);

		// Seta os parâmetros do elemento.
		if(objectParameters) {
			for(var parameter in objectParameters) {
				if(typeof(objectParameters[parameter]) == 'object') {
					for(var i in objectParameters[parameter])
						objectElement[parameter][i] = objectParameters[parameter][i];
				} else
					objectElement[parameter] = objectParameters[parameter];
			}
		}

		return objectElement;
	};

	/**
	 * Calcula a posição top para um submenu.
	 */
	this._getSubMenuPosition = function(listContainerId, optionId) {
		// Contador de retorno.
		var menuPosition = 0;

		// Seleciona as opções do menu.
		var listElements = $(listContainerId).getElementsByTagName('li');
		for(var i = 0; i < listElements.length; i++) {
			// Valida o objeto pai.
			if(listElements[i].parentNode.id == listContainerId) {
				if(this._isSeparator(listElements[i]))
					// Separador.
					menuPosition += 12;
				else if(listElements[i].id == optionId)
					return menuPosition;
				else
					// Opção normal.
					menuPosition += 18;
			}
		}

		return menuPosition;
	};

	/**
	 * Fecha os submenus até a raiz.
	 * (Necessária a chamada apenas no evento de clique, devido ao comportamento do IE).
	 */
	this._closeParentOption = function(optionName) {
		var parentObject = $(optionName).parentNode.parentNode;
		if($(parentObject.id + '_options')) {
			$(parentObject.id + '_options').className = 'DIVHIDE';
			this._closeParentOption(parentObject.id);
		}		
	};

	/**
	 * Verifica se uma opção é sepadador.
	 */
	this._isSeparator = function(optionObject) {
		return optionObject.id.indexOf(this.menuName + '_separator_') > -1;		
	};

	/**
	 * Verifica se uma opção esta desabilitada.
	 */
	this.isDisabled = function(optionName) {
		return typeof(inArray(optionName, this.arrayDisabledOptions)) == 'number';
	};

	/**
	 * Cria o menu.
	 */
	this.createMenu = function() {
		// Container do menu.
		var menuContainer = $(this.menuName + '_container');
		menuContainer.className = 'basicMenuContainer';

		if(this.caption != '') {
			// Container principal.
			var menuCaption = this._createObject('div', {className: 'basicMenuCaption'});

			// Imagem.
			var divElement = this._createObject('div', {className: 'captionImage'});
			var imgElement = this._createObject('img', {src: this.imagePath + 'icon_menuacoes.gif'});
			divElement.appendChild(imgElement);
			menuCaption.appendChild(divElement);

			// Caption.
			var divElement = this._createObject('div', {className: 'captionText', innerHTML: this.caption});
			menuCaption.appendChild(divElement);

			// Arrow.
			var divElement = this._createObject('div', {className: 'captionArrow'});
			var imgElement = this._createObject('img', {src: pathWeb + '/framework/skin/' + A_nmskin + '/images/menu/arrow_down.gif'});
			divElement.appendChild(imgElement);
			menuCaption.appendChild(divElement);

			// Adiciona o conteúdo no container do menu.					
			menuContainer.appendChild(menuCaption);
		} else {
			menuContainer.style.width = 0;
			menuContainer.style.height = 0;
		}

		// Cria o objeto de lista.
		var listObject = this._createObject('ul', {id: this.menuName + '_options', className: 'DIVHIDE', style: {width: this.tableSize - (getIeVersion() != null ? 3 : 0)}});

		// Adiciona a lista no container.
		var optionsContainer = this._createObject('div');
		optionsContainer.appendChild(listObject);

		menuContainer.appendChild(optionsContainer);

		// Adiciona os eventos ao container.
		var menuName = this.menuName;

		menuContainer.onmouseover = function() {
			var objectMenu = eval(menuName);
			objectMenu.openOptions();
		};

		menuContainer.onmouseout = function() {
			var objectMenu = eval(menuName);
			objectMenu.closeOptions();
		};				
	};
	
	/**
	 * Adiciona uma opção ao menu.
	 */
	this.addOption = function(objectParameters) {
		// Nome do objeto.
		var menuName = this.menuName;

		// Cria o objeto da opção.
		var optElement = this._createObject('li', {
			// ID da opção.
			id: objectParameters.name,

			// Evento de foco.
			onmouseover: function() {
				var objectMenu = eval(menuName);
				objectMenu.setFocusOption(objectParameters.name);
			},

			// Evento de blur.
			onmouseout: function() {
				var objectMenu = eval(menuName);
				objectMenu.blurFocusOption(objectParameters.name);
			},

			// Evento de clique.
			onclick: function() {
				var objectMenu = eval(menuName);

				// Verifica se a opção esta desabilitada.
				if(!objectMenu.isDisabled(objectParameters.name)) {					
					if(objectParameters.action) {
						// Fecha as opções superiores.
						objectMenu._closeParentOption(objectParameters.name);

						// Fecha o menu.
						objectMenu.closeOptions();

						// Executa a ação.
						eval(objectParameters.action);
					}
				}
			}
		});

		// Container de ícone.
		var divElement = this._createObject('div', {id: objectParameters.name + '_img', className: 'optionImg'});

		// Adiciona o ícone da opção.
		if(objectParameters.image) {
			var imgElement = this._createObject('img', {src: this.imagePath + objectParameters.image});
			divElement.appendChild(imgElement);
		}

		optElement.appendChild(divElement);

		// Container de caption.
		var divElement = this._createObject('div', {
			id: objectParameters.name + '_caption', 
			className: 'optionCaption', 
			innerHTML: objectParameters.caption,
			style: {width: this.tableSize - 40}
		});

		optElement.appendChild(divElement);

		// Container da imagem de submenu.
		var divElement = this._createObject('div', {id: objectParameters.name + '_submenu', className: 'optionSubMenu'});
		optElement.appendChild(divElement);

		if(objectParameters.parent) {
			// Adiciona a imagem no ítem superior.
			if(!$(objectParameters.parent + '_options')) {
				// Cria a imagem.
				var imgElement = this._createObject('img', {src: pathWeb + '/framework/skin/' + A_nmskin + '/images/menu/arrow.gif'});

				// Adiciona a imagem ao container.
				var divElement = $(objectParameters.parent + '_submenu'); 
				divElement.appendChild(imgElement);

				// Captura o objeto pai.
				var parentObject = $(objectParameters.parent);

				// Cria a lista de submenu.
				var listObject = this._createObject('ul', {
					id: objectParameters.parent + '_options', 
					className: 'DIVHIDE',
					style: {
						width: this.tableSize - (getIeVersion() != null ? 3 : 0),
						left: this.tableSize - (getIeVersion() != null ? 5 : 0),
						top: this._getSubMenuPosition(parentObject.parentNode.id, objectParameters.parent)
					}
				});

				// Adiciona a lista à opção.
				parentObject.appendChild(listObject);
			}
			
			// Verifica se a opção superior está desabilitada.
			if(this.isDisabled(objectParameters.parent))
				this.enableOption(objectParameters.parent);
		}

		// Adiciona a opção ao menu.
		var listObject = $((objectParameters.parent ? objectParameters.parent : this.menuName) + '_options');
		listObject.appendChild(optElement);
	};

	/**
	 * Adiciona um separador ao menu.
	 */
	this.addSeparator = function(parentName) {
		// Cria o elemento da lista.
		var optElement = this._createObject('li', {id: this.menuName + '_separator_' + this.separatorIndex});

		// Atualiza o controlador de index de separadores.
		this.separatorIndex++;

		// Container de imagem.
		var divElement = this._createObject('div', {className: 'separatorImg'});
		optElement.appendChild(divElement);

		// Container de caption.
		var divElement = this._createObject('div', {className: 'separatorContent'});
		divElement.style.width = this.tableSize - 30;

		// Adiciona a opção ao menu.
		var divContent = this._createObject('div');
		divElement.appendChild(divContent);
		optElement.appendChild(divElement);

		var listObject = $((parentName ? parentName : this.menuName) + '_options');
		listObject.appendChild(optElement);
	};

	/**
	 * Remove uma opção do menu.
	 */
	this.deleteOption = function(optionName) {
		if($(optionName))
			Element.remove(optionName);
	};

	/**
	 * Remove um separador do menu.
	 */
	this.deleteSeparator = function(separatorIndex) {
		var separatorObject = $(this.menuName + '_separator_' + separatorIndex);
		if(separatorObject)
			Element.remove(separatorObject);
	};

	/**
	 * Habilida uma opção do menu.
	 */
	this.enableOption = function(optionName) {
		// Valida a opção.
		if(!$(optionName))
			return;

		// Verifica se a opção esta desabilitada.		
		if(this.isDisabled(optionName)) {
			// Verifica se existe opção superior.
			var parentOption = $(optionName).parentNode.parentNode;
			if($(parentOption.id)) {
				// Verifica se a opção superior esta desabilitada.
				if(this.isDisabled(parentOption.id)) {
					// Habilita a opção superior.
					this.enableOption(parentOption.id);

					// Verifica o nível acima.
					var parentOption = parentOption.parentNode.parentNode;
					if($(parentOption.id)) {
						// Habilita a opção superior.
						if(this.isDisabled(parentOption.id))
							this.enableOption(parentOption.id);
					}
				}
			}

			// Exclui a opção do array de controle.
			var optionIndex = inArray(optionName, this.arrayDisabledOptions);
			delete this.arrayDisabledOptions[optionIndex];

			// Muda a cor do texto da opção.
			$(optionName + '_caption').style.color = '#444';			
		}
	};

	/**
	 * Desabilita uma opção do menu.
	 */
	this.disableOption = function(optionName) {		
		// Valida a opção.
		if(!$(optionName))
			return;

		if(!this.isDisabled(optionName)) {
			// Adiciona a opção no array de controle de ítens desabilitados.
			this.arrayDisabledOptions.push(optionName);

			// Muda a cor do texto da opção.
			$(optionName + '_caption').style.color = '#ccc';

			// Verifica se existe opção superior.
			var parentOption = $(optionName).parentNode.parentNode;
			if($(parentOption.id)) {
				// Seleciona as opções do menu.
				var arrayElements = parentOption.getElementsByTagName('li');
				for(var i = 0; i < arrayElements.length; i++) {
					// Valida a opção superior.
					if(arrayElements[i].parentNode.parentNode.id == parentOption.id) {
						// Descarta desabilitar a opção superior, pois ele possui opções habilitadas. 
						if(!this.isDisabled(arrayElements[i].id))
							return;
					}
				}

				// Desabilita a opção superior.
				this.disableOption(parentOption.id);				
			}
		}
	};

	/**
	 * Exibe as opções do menu.
	 */
	this.openOptions = function() {
		hiddenLayerCombos();
		$(this.menuName + '_options').className = 'DIVSHOW basicMenu';
	};

	/**
	 * Fecha as opções do menu.
	 */
	this.closeOptions = function() {
		$(this.menuName + '_options').className = 'DIVHIDE';
		showLayerCombos();
	};

	/**
	 * Seta o foco na opção do menu.
	 */
	this.setFocusOption = function(optionName) {
		// Verifica se a opção esta desabilitada.
		if(!this.isDisabled(optionName)) {
			// Seta a classe dos elementos.
			$(optionName + '_img').className = 'optionImg activeOption';
			$(optionName + '_caption').className = 'optionCaption activeOption';
			$(optionName + '_submenu').className = 'optionSubMenu activeOption';

			// Verifica o submenu.
			var objectSubMenu = $(optionName + '_options');
			if(objectSubMenu)
				objectSubMenu.className = 'basicMenu';
		}
	};

	/**
	 * Tira o foco da opção do menu.
	 */
	this.blurFocusOption = function(optionName) {
		// Seta a classe dos elementos.
		$(optionName + '_img').className = 'optionImg';
		$(optionName + '_caption').className = 'optionCaption';
		$(optionName + '_submenu').className = 'optionSubMenu';

		// Verifica o submenu.
		var objectSubMenu = $(optionName + '_options');
		if(objectSubMenu)
			objectSubMenu.className = 'DIVHIDE';
	};
	
	/**
	 * Exclui o menu.
	 */
	this.deleteMenu = function() {
		$(this.menuName + '_container').innerHTML = '';
	};
}