/*
 *  Copyright 2013 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * This class controls a ribbon menu for semantic annotation in editor.
 * It can call a configured function when the selection changed in inline editor.
 * @private
 */
Ext.define('Ametys.plugins.cms.editor.controller.SemanticAnnotationController', {
	extend: 'Ametys.cms.editor.EditorButtonController',
	
	createUI: function()
	{
		var elt = this.callParent(arguments);
		elt.on('menushow', this._onMenuShow, this);
		return elt;
	},
	
	_getMenuPanel: function()
	{
		var menuPanel = Ext.create("Ametys.ui.fluent.ribbon.controls.gallery.MenuPanel", {
			title: "{{i18n CONTENT_EDITION_SEMANTIC_ANNOTATION_MENUGALLERY_GROUP}}",
			items: []
		});
		
		return this._createGalleryWrapper([menuPanel]);
	},	
	
	/**
	 * Listener on 'menushow' event<br>
	 * @param {Ext.button.Button} btn The button
	 * @param {Ext.menu.Menu} menu The menu
	 * @private
	 */
	_onMenuShow: function(btn, menu)
	{
		var message = Ametys.message.MessageBus.getCurrentSelectionMessage();
		
		var target = message.getTarget('node');
		var node = target != null ? target.getParameters()['object'] : null;
		
		// FIXME "tinyMCE.activeEditor" a better method is to use the field.getEditor()
		var nodesel = tinyMCE.activeEditor.selection.getNode();
		var elt = tinyMCE.activeEditor.dom.getParent(nodesel, 'span[annotation]');
		var sel = tinyMCE.activeEditor.selection.getContent();
		var overlapAnnotation = elt == null && new RegExp("<span[^>]*annotation=").test(sel);
		
		var currentAnnotations = [];
		if (overlapAnnotation)
		{
			var matches = sel.match(/<span[^>]*annotation=\"([^\"]*)\"/g);
			if (matches != null)
			{
				for (var i=0; i < matches.length; i++)
				{
					currentAnnotations.push(/<span[^>]*annotation=\"([^\"]*)\"/.exec(matches[i])[1]);
				}
			}
		}
		else if (elt != null)
		{
			currentAnnotations.push(elt.getAttribute('annotation'));
		}
		
        this._getGalleries(btn).get(0).items.each(function(item) {
			var off = !target || !node;
			var state = !off;
			var disabled = false;
			
			if (!off)
			{
			    // FIXME "tinyMCE.activeEditor" a better method is to use the field.getEditor()
				disabled = (/<p[> \/]|<td[> \/]|<th[> \/]|<li[> \/]|<div[> \/]/.test(sel)) || (sel == '' && !elt) || nodesel != null && tinyMCE.activeEditor.dom.hasClass(nodesel, 'mceNonEditable');
				disabled = disabled || overlapAnnotation || (currentAnnotations.length > 0 && !Ext.Array.contains (currentAnnotations, item.annotationName))
				state = Ext.Array.contains (currentAnnotations, item.annotationName);
			}

			item.setDisabled(off || disabled);
			item.toggle(state, true);
		});
	},
	
	/**
	 * Updates the menu gallery.
	 * Removes the items of the gallery and add new item form existing semantic annotation of the new focused rich text. 
	 * @param {String} fieldName The field name of focused rich text
	 * @param {Ametys.form.field.RichText} richtext The focused rich text
	 */
	updateMenuGallery: function(fieldName, richtext)
	{
		if (richtext != null && this._currentFieldName != fieldName)
		{
			this._currentFieldName = fieldName;
			
			var me = this;
			this._getGalleries().each(function(menuPanel) {
				
				// Remove old items
				menuPanel.removeAll();
				
				// Sort by alphabetical order on label
				var annotations = Ext.Array.sort(richtext.getSemanticAnnotations(), function(a1, a2) {
					
					if (a1.label == a2.label)
					{
						return 0;
					}
					
					return (Ext.data.SortTypes.asNonAccentedUCString(a1.label) < Ext.data.SortTypes.asNonAccentedUCString(a2.label)) ? -1 : 1;
				});
				
				var gpItems = [];
				
				for (var i=0; i < annotations.length; i++)
				{
					var element = Ext.create("Ametys.ui.fluent.ribbon.controls.Button", {
				        text: annotations[i].label,
				        tooltip: annotations[i].description || annotations[i].label,
				        icon: Ametys.getPluginResourcesPrefix('cms') + '/img/content/edition/annotations/xml_32.png',
				        scale: 'large',
				        
				        controlId: me.getId(),
				        annotationName: annotations[i].name,
				        
						toggleHandler: Ext.bind(me._onItemPress, me),
						enableToggle: true,
						pressed: false
					});
					
					gpItems.push(element);
				}
				
				menuPanel.add(gpItems);
			});
		}
	},
	
	/**
	 * This function is called when an item of the gallery is pressed
	 * @param {Ametys.ui.fluent.ribbon.controls.Button} button The pressed button
	 * @param {Boolean} pressed The button state.
	 * @private
	 */
	_onItemPress: function(button, pressed)
	{
		Ametys.plugins.cms.editor.SemanticAnnotation.apply(this, button, pressed);
	}
	
});