/*
 *  Copyright 2017 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 tool displays the hierarchy of registered content types
 * @private
 */
Ext.define('Ametys.plugins.contenttypeseditor.tree.ContentTypeHierarchyTool', {
	extend: "Ametys.tool.Tool",
    
    /**
	 * @private
	 * @property {Ext.tree.Panel} _tree the tree representing the content types' hierarchy
	 */
    
    constructor: function(config)
    {
        this.callParent(arguments);
        Ametys.message.MessageBus.on(Ametys.message.Message.SELECTION_CHANGED, Ext.Function.createBuffered(this._onSelectionChanged, 1, this), this);
    },

	createPanel: function ()
	{
		this._tree = Ext.create('Ametys.plugins.cms.contenttype.ContentTypeTree', {
			border: false,
			
			listeners: {
				'selectionchange': Ext.bind(this.sendCurrentSelection, this),
				'itemdblclick': Ext.bind(this._openContentType, this)
            },
            
            selModel: { mode: 'MULTI' }
		});
		
		return this._tree;
	},
	
	getMBSelectionInteraction: function()
	{
		return Ametys.tool.Tool.MB_TYPE_ACTIVE;
	},
	
    sendCurrentSelection: function()
    {
        var selection = this._tree.getSelectionModel().getSelection();
        
        var targets = [];
        for (var i = 0 ; i < selection.length ; i++)
        {
            targets.push(this.getMessageTargetConfiguration(selection[i]));
        }
        
        Ext.create('Ametys.message.Message', {
            type: Ametys.message.Message.SELECTION_CHANGED,
            targets: targets
        });
	},
    
    /**
     * @private
     * Get the target configuration object for given record
     * @param {Ext.data.Model} record The tree record to convert to its Ametys.message.MessageTarget configuration
     * @return {Object} The configuration to create a Ametys.message.MessageTarget. Can be null, if the record is null or not relevant to be a messagetarget.
     */
    getMessageTargetConfiguration: function (record)
    {
        if (record == null)
        {
            // Empty selection
            return null;
        }
        else
        {
            return {
                id: Ametys.message.MessageTarget.CONTENT_TYPE,
                parameters: {id: record.get('contentTypeId'), editor: false}
            };
        }
    },
	
	/**
	 * @private
	 * Open content type editor on double-click event
	 * @param {Ext.view.View} view the tree view
	 * @param {Ext.data.Model} node The record that belongs to the double-clicked item
	 */
	_openContentType: function (view, node)
	{
		if (node.isRoot())
		{
			return;
		}

		// Open page
		Ametys.tool.ToolsManager.openTool ("uitool-contenttypeseditor", {id: node.get('contentTypeId')});
	},
    
    /**
     * @private
     * Listener on the current selection
     * @param {Ametys.message.Message} message the selection message
     */
    _onSelectionChanged: function(message)
    {
        var targets = message.getTargets(Ametys.message.MessageTarget.CONTENT_TYPE);
        if (targets.length > 0)
        {
            var nodesToSelect = [];
            
            var currentSelection = this._tree.getSelectionModel().getSelection();
            for (var i = 0; i < targets.length; i++)
            {
                var target = targets[i];
                var id = target.getParameters().id;
                if (Ext.Array.findBy(currentSelection, function(item) { return item.get('contentTypeId') == id; }, this))
                {
                    // same selection
                }
                else
                {
                    var node = this._tree.getStore().findNode('contentTypeId', id);
                    if (node)
                    {
                        nodesToSelect.push(node);
                    }
                }
            }
            
            if (nodesToSelect.length > 0) 
            {
                this._tree.getSelectionModel().select(nodesToSelect);
                this._tree.ensureVisible(nodesToSelect[0].getPath());
            }
        }
    },
    
    getParams: function()
    {
        return Ext.applyIf(this.callParent(arguments), {
            hierarchicalView: true,
            excludeAbstract: false,
            excludeMixin: false,
            excludePrivate: false,
            excludeReferenceTable: false
        });
    },
	
	setParams: function(params)
    {
        params = Ext.applyIf(params, this.getParams());
        
        this.callParent(arguments);
        
        this._tree.hierarchicalView = params.hierarchicalView;
        
        if (this._tree.hierarchicalView)
        {
            // No apply exclude in hierarchical view
            this._tree.excludeAbstract = false;
            this._tree.excludePrivate = false;
            this._tree.excludeMixin = false;
            this._tree.excludeReferenceTable = false;
        }
        else
        {
            this._tree.excludeAbstract = params.excludeAbstract;
            this._tree.excludePrivate = params.excludePrivate;
            this._tree.excludeMixin = params.excludeMixin;
            this._tree.excludeReferenceTable = params.excludeReferenceTable;
        }
        this.refresh();
    },
	
	refresh: function ()
	{
        var selection = this._tree.getSelectionModel().getSelection();
		this._tree.getStore().load({ callback: Ext.bind(this._refreshCb, this, [selection])});
	},
	
	/**
	 * @private
	 * Callback function after #refresh is process
	 */
	_refreshCb: function (selection)
	{
		this.showRefreshed();
        if (selection && selection.length > 0) 
        {
            var nodes = [];
            for (var i = 0 ; i < selection.length ; i++)
            {
                var selectionId = selection[i].get('contentTypeId');
                var node = this._tree.getStore().findNode('contentTypeId', selectionId);
                if (node)
                {
                    nodes.push(node);
                }
            }
            if (nodes.length > 0)
            {
                this._tree.getSelectionModel().select(nodes);
                this._tree.ensureVisible(nodes[0].getPath());
            }
            else
            {
                this._tree.setSelection(this._tree.getStore().getAt(0));
            }
        }
        else 
        {
            this._tree.setSelection(this._tree.getStore().getAt(0));
        }
       
	}
    
});