/*
 *  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.
 */

/**
 * Class to handle link insertion in inline editor
 * @private
 */
Ext.define('Ametys.plugins.cms.editor.Styles', {
    singleton: true,
    
    /**
     * Fires when at least one list item is selected.
     * @param {Ext.form.field.ComboBox} combo The combobox applying the style
     * @param {Ext.data.Model/Ext.data.Model[]} records The selected records to apply (only the first one will be applied)
     */
    applyStyle: function (combo, records)
    {
        if (!records || records.length == 0)
            return;
        
        var record = Ext.isArray(records) ? records[0] : records;
        
        // FIXME "tinyMCE.activeEditor" a better method is to use the field.getEditor()
        tinyMCE.activeEditor.focus();
        tinyMCE.activeEditor.execCommand('mceBeginUndoLevel');
        
        var carretLocation = tinymce.activeEditor.selection.getBookmark(); // CMS-3513

        var selectedBlocks = tinyMCE.activeEditor.selection.getSelectedBlocks();
        for (var i = 0; i < selectedBlocks.length; i++)
        {
            var block = selectedBlocks[i];
            var selectionParentNode = tinyMCE.activeEditor.dom.getParent(block, record.get('tagName'));

            if (selectionParentNode == null)
            {
                tinymce.activeEditor.selection.select(block);
                tinyMCE.activeEditor.execCommand('FormatBlock', false, record.get('tagName'));
                block = tinyMCE.activeEditor.selection.getSelectedBlocks()[0];
                selectionParentNode = tinyMCE.activeEditor.dom.getParent(block, record.get('tagName'));
            }

            if (selectionParentNode != null)
            {
                if (record.get('style'))
                {
                    // remove existing classes
                    for (var k = 0; k < combo.getStore().getCount(); k++)
                    {
                        var r = combo.getStore().getAt(k); 
                        if (r.get("tagName") == record.get("tagName") 
                            && r.get('style') 
                            && tinyMCE.activeEditor.dom.hasClass(selectionParentNode, r.get("style")))
                        {
                            tinyMCE.activeEditor.dom.removeClass(selectionParentNode, r.get("style"));
                        }
                    }
                    tinyMCE.activeEditor.dom.addClass(selectionParentNode, record.get('style'));
                }
                else
                {
                    selectionParentNode.className = "";
                }
            }
        }

        tinymce.activeEditor.selection.moveToBookmark(carretLocation); // CMS-3513
        tinyMCE.activeEditor.execCommand('mceEndUndoLevel');
    },
    
    /**
     * Enable/disable and set value of the controller according the current selection
     * @param {Ametys.cms.editor.EditorButtonController} controller The controller
     * @param {Ametys.cms.form.widget.RichText} field The current field. Can be null
     * @param {HTMLElement} node The current selected node. Can be null.
     */
    styleSelectionListener: function (controller, field, node)
    {
        if (!node)
        {
            return;
        }
        
        var records = controller.getStore().queryBy(this._testStyle, node);
        if (records.getCount() == 1)
        {
            controller.setValue(records.getAt(0).getId());
        }
        else if (records.getCount() > 1)
        {
            var i = 0;
            if (!records.getAt(0).get('style'))
            {
                i = 1;
            }
            
            controller.setValue(records.getAt(i).getId());
        }
        else
        {
            controller.setValue(null);
        }
    },
    
    /**
     * @private
     * Test if the style defined in the record is used
     * @param {Ext.data.Model} record The record to test for filtering
     * @param {Object} id The ID of the Record passed.
     */
    _testStyle: function(record, id)
    {
        var style = record.get('style');
        var className = style ? '.' + style : '';
        // FIXME "tinyMCE.activeEditor" a better method is to use the field.getEditor()
        var node = tinyMCE.activeEditor ? tinyMCE.activeEditor.dom.getParent(this, record.get('tagName') + className) : null;
        return node != null;  
    }
});

/**
 * Model for the style store
 * @private
 */
Ext.define('Ametys.plugins.cms.editor.Styles.StyleEntry', {
    extend: 'Ext.data.Model',
    
    fields: [
        {name: 'label', type: 'string'},
        {name: 'description', type: 'string'},
        {name: 'cls'},
        {name: 'style'},
        {name: 'tagName'},
        {name: 'inlineEditorRender'}
    ],
    
    idProperty: 'inlineEditorRender'
    
});