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

/**
 * @private
 * This tool displays the available skins
 */
Ext.define('Ametys.plugins.web.skin.SkinTool', {
    extend: 'Ametys.tool.Tool',

    /**
     * @private
     * @property {Ext.view.View} _dataViews The list of handled data views.
     */
    _dataViews: [],
    
    /**
     * @private
     * @property {Ext.XTemplate} _dataViewTemplate Template used by data view for skins
     */
    _dataViewTemplate: Ext.create('Ext.XTemplate',
        '<tpl for=".">',
            '<div class="skin-item">',
                '<img src="' + Ametys.CONTEXT_PATH + '{iconLarge}">',
                '<div class="text">',
                    '<span class="title">{label}</span> ({id})<br/>',
                    '{shortDescription}<br/>',
                '</div>',
            '</div>',
        '</tpl>'
    ),
    
    /**
     * @private
     * @property {Ext.XTemplate} _tooltipDescTpl Template used for tooltip description
     */
    _tooltipDescTpl: Ext.create('Ext.XTemplate',
        '<tpl for=".">',
                '{description}<br/><br/>',
                '<tpl if="type == \'skin\'">',
                    '<tpl if="model != null">',
                        '{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_FROM_MODEL}}<b>{model.name}</b> ({model.id}).<br/><br/>',
                    '</tpl>',
                    '<tpl if="extendingSkins.length">',
                        '{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_HINT_EXTENDING}} <tpl for="extendingSkins">{.} </tpl><br/><br/>',
                    '</tpl>',
                    '<tpl if="extendedIntoSkins.length">',
                        '{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_HINT_EXTENDED}} <tpl for="extendedIntoSkins">{.} </tpl><br/><br/>',
                    '</tpl>',
                    '<tpl if="nbSites != 0">',
                        '{nbSites}{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_HINT_USED}}<br/>{sites}',
                    '</tpl>',
                '</tpl>',
        '</tpl>'
    ),

    constructor: function (config)
    {
        this.callParent(arguments);

        Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onMessage, this);
        Ametys.message.MessageBus.on(Ametys.message.Message.CREATED, this._onMessage, this);
        Ametys.message.MessageBus.on(Ametys.message.Message.DELETED, this._onMessage, this);
    },

    /**
     * Called when a message is received
     * @param {Ametys.message.Message} message The message received.
     * @private
     */
    _onMessage: function(message)
    {
    	if (message.getTarget(Ametys.message.MessageTarget.SKIN))
        {
            this.showOutOfDate();
        }
    },

    getMBSelectionInteraction: function ()
    {
        return Ametys.tool.Tool.MB_TYPE_ACTIVE;
    },

    createPanel: function ()
    {
    	this._dataViews = [];
        var items = this._getItems();

        return Ext.create('Ext.panel.Panel', {
            border: false,
            scrollable : true,
            cls: ['uitool-skins', 'a-panel-spacing'],

            items: items,
            
            dockedItems: this._getDockedItems()
        });
    },
    
    /**
     * @template
     * @protected
     * Get the docked items
     * @return {Ext.Component[]} the docked items
     */
    _getDockedItems: function ()
    {
    	return [];
    },
    
    
    /**
     * @template
     * @protected
     * Get the data views handled by this tool wrapped in their fieldset.
     * @return {Ext.form.FieldSet[]} the fieldsets.
     */
    _getItems: function ()
    {
    	return [
                this._createDataView("unusedSkins", "Ametys.plugins.web.skin.Skin", "{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_UNUSED_SKINS_TITLE}}", Ametys.message.MessageTarget.SKIN),
                this._createDataView("usedSkins", "Ametys.plugins.web.skin.Skin", "{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_USED_SKINS_TITLE}}", Ametys.message.MessageTarget.SKIN),
                this._createDataView("abstractSkins", "Ametys.plugins.web.skin.Skin", "{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_ABSTRACT_SKINS_TITLE}}", Ametys.message.MessageTarget.SKIN)
        ];
    },

    /**
     * Create a data view wrapped in a fieldset
     * @param {String} id The id of the dataview
     * @param {String} model The name of model used by the data view store
     * @param {String} title The title of the fieldset
     * @param {String} messageTargetType The message target type for data view records
     * @return {Ext.form.FieldSet} A fieldset containing the data view 
     * @private
     */
    _createDataView: function (id, model, title, messageTargetType)
    {
        var dv = Ext.create ('Ext.view.View', {
        	scrollable: true,

            xtype: 'dataview',
            ui: 'view',
            border: false,
            
            _title: title,
            _messageTargetType: messageTargetType,

            store: {
            	model: model
            },
            
            itemId: id,
            tpl: this._dataViewTemplate,
            itemSelector: 'div.skin-item',
            overItemCls:'x-view-over',

            selectionModel: {
                mode: 'SINGLE',
                allowDeselect: false
            },

            listeners: {
                'itemmouseenter': Ext.bind(this._createQtip, this, [id], 3),
                'beforeselect': Ext.bind(this._onBeforeSelect, this),
                'selectionchange': Ext.bind(this.sendCurrentSelection, this)
            }
        });

        this._dataViews.push(dv);
        
        return {
            xtype: 'panel',
            itemId: 'dataview-' + id,
            
            title: title,
            header: {
            	titlePosition: 1
            },
            titleCollapse: true,
            collapsible: true,
            items: dv
        };
    },

    /**
     * Listener on the beforeSelect event, deselect all the currently selected items across all DataViews.
     * @private
     */
    _onBeforeSelect: function ()
    {
    	Ext.Array.each (this._dataViews, function (dv) {
    		dv.getSelectionModel().deselectAll(true);
    	});
    },

    sendCurrentSelection: function ()
    {
    	var hasSelection = false;
    	
    	Ext.Array.each (this._dataViews, function (dv) {
    		var selected = dv.getSelectionModel().getSelection();
    		var targets = [];
    		
    		Ext.Array.forEach(selected, function (record) {
    			targets.push ({
    				id: dv._messageTargetType,
                    parameters: {
                        id: record.get('id')
                    }
    			});
            });
    		
    		if (targets.length > 0)
    		{
    			hasSelection = true;
    			Ext.create("Ametys.message.Message", {
                    type: Ametys.message.Message.SELECTION_CHANGED,
                    targets: targets
                });
    		}
    	});
    	
    	if (!hasSelection)
    	{
    		Ext.create("Ametys.message.Message", {
                type: Ametys.message.Message.SELECTION_CHANGED,
                targets: []
            });
    	}
    },

    setParams: function (params)
    {
        this.callParent(arguments);
        this.refresh();
    },

    refresh: function ()
    {
        this.showRefreshing();
        Ametys.plugins.web.skin.SkinDAO.getSkins([true], this._refreshCb, {
            waitMessage: false,
            scope: this
        });
    },

    /**
     * Callback invoked after retrieving all skins
     * @param {Object} response The server response
     * @param {Object[]} response.skins The list of skins
     * @private
     */
    _refreshCb: function (response)
    {
        var usedSkins = [];
        var unusedSkins = [];
        var abstractSkins = [];

        var abstractSkinsStore = this.getContentPanel().getComponent("dataview-abstractSkins").getComponent("abstractSkins").getStore();
        var usedSkinsStore = this.getContentPanel().getComponent("dataview-usedSkins").getComponent("usedSkins").getStore();
        var unusedSkinsStore = this.getContentPanel().getComponent("dataview-unusedSkins").getComponent("unusedSkins").getStore();

        abstractSkinsStore.removeAll();
        usedSkinsStore.removeAll();
        unusedSkinsStore.removeAll();

        if (response.skins)
        {
            Ext.Array.forEach (response.skins, function (skin) {
                if (skin.abstract)
                {
                    abstractSkins.push(skin);
                }
                else if (skin.nbSites > 0 || skin.extendedIntoSkins.length > 0)
                {
                    usedSkins.push(skin);
                }
                else 
                {
                    unusedSkins.push(skin);
                }
            });

            abstractSkinsStore.add(abstractSkins);
            usedSkinsStore.add(usedSkins);
            unusedSkinsStore.add(unusedSkins);
        }

        Ext.Array.each (this._dataViews, function (dv) {
        	var count = dv.getStore().getCount();
        	dv.ownerCt.setTitle (dv._title + " (" + count + ")");
        	dv.ownerCt.setVisible(count > 0);
        })
        
        this.showRefreshed();
    },

    /**
     * Destroy and create tooltip when the mouse enters the item.
     * @param {Ext.view.View} view The data view
     * @param {Ext.data.Model} record The record that belongs to the item
     * @param {HTMLElement} el The item's element
     */
    _createQtip: function (view, record, el)
    {
    	// Destroy old quick tip if exists
    	Ext.QuickTips.unregister(el);
    	
        Ext.QuickTips.register({
        	target: el,
            
        	image: Ametys.CONTEXT_PATH + record.data.iconLarge,
        	imageWidth: 48,
    		imageHeight: 48,
            title: record.data.label,
            text:  this._tooltipDescTpl.apply(record.data),
            inribbon: false
        });
    }
});