/*
 *  Copyright 2014 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 provides a widget to select a skin.<br>
 *
 * This widget is registered for fields of type Ametys.form.WidgetManager#TYPE_STRING.
 */
Ext.define('Ametys.web.form.widget.SelectSkin', {
    extend: 'Ametys.form.AbstractFieldsWrapper',

    xtype: 'edition.select-skin',

    /**
     * @cfg {Boolean|String} [allowCreation=false] If true, a menu to create a new skin will be present (defaults to false).
     */
    allowCreation: false,

    /**
     * @cfg {Number} [valueField=id] The underlying data value name to bind to the ComboBox.
     */
    valueField: 'id',
    /**
     * @cfg {Number} [displayField=fullLabel] The underlying data field name to bind to the ComboBox.
     */
	displayField: 'fullLabel',
	
    /**
     * @cfg {String} buttonIcon The full path to the button icon (in 16x16 pixels)
     */
    buttonIcon: Ametys.getPluginResourcesPrefix('web') + '/img/uitool-site/configure_site_16.png',
    /**
     * @cfg {String} buttonTooltipText The button tooltip text
     */
    buttonTooltipText: "{{i18n PLUGINS_WEB_ADMINISTRATOR_SKINS_TITLE}}",
    
    /**
	 * @cfg {Boolean} [triggerOnClick=true] Set to `true` to activate the trigger when clicking in empty space in the field.
	 */
	triggerOnClick: true,

    initComponent: function()
    {
    	this.layout = 'hbox';
        this.cls = 'x-form-select-skin-widget';
        
        this.items = this.getItems();
        this.callParent();
        
        this.loadSkins();
    },

    /**
     * @private
     * Get the items of this widget
     * @return {Ext.Component[]} The items to create the widget
     */
    getItems: function ()
    {
    	this.combobox = Ext.create('Ext.form.field.ComboBox', this.getComboBoxConfig());
    	
        var items = [this.combobox];
        
        if (this.allowCreation)
        {
            this.createButton = Ext.create('Ext.button.Button', {
                icon: this.buttonIcon,
                tooltip: this.buttonTooltipText,
                hidden: true
            });
            
            items.push(this.createButton);
            
        	Ametys.data.ServerComm.callMethod({
				role: 'org.ametys.core.ui.widgets.WidgetsManager',
				id: "edition.select-skin",
				methodName: "getCreateSkinActions",
				callback: {
					handler: this._getCreateSkinActionsCb,
				 	scope: this
				}
			});
        }

        return items;
    },
    
    /**
     * Get combo box configuration
     * @return {Object} The combo box configuration
     * @private
     */
    getComboBoxConfig: function ()
    {
        return {
            editable: true,
            autoSelect: false,
            multiSelect: this.multiple,
            
            queryMode: 'local',
            
            store: Ext.create('Ext.data.Store', {
                model: "Ametys.plugins.web.skin.Skin",
                proxy: { type: 'memory',  reader: 'array' },
                sorters: [{property: 'group', direction:'ASC'}, {property: 'fulllabel', direction:'ASC'}]
            }),
            valueField: this.valueField,
            displayField: this.displayField,
            
            flex: 1,
            allowBlank: this.allowBlank,
            emptyText: this.emptyText,

            tpl: Ext.create('Ext.XTemplate',
	    		 '<ul class="x-list-plain">',
	    		 	'<tpl for=".">',
		    		 	'<tpl if="this.group != values.group">',
		    			'<tpl exec="this.group = values.group"></tpl>',
		    			'<h1>{group}</h1>',
		    			'</tpl>',
	    		 		'<li role="option" class="x-boundlist-item level-1">{label} <em>({id})</em></li>',
	    		 	'</tpl>',
	    		 '</ul>'),
            
            readOnly: this.readOnly || false,
            triggerOnClick: this.triggerOnClick,
            hideTrigger: this.hideTrigger
        };
    },

    constructor: function (config)
    {
        config.allowCreation = Ext.isString(config.allowCreation) ? config.allowCreation == "true" : (config.allowCreation || false);

        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);

        this.callParent(arguments);
    },

    /**
     * Listener when a modified, created or deleted message was sent on message bus.
     * Updates the combo box store if a skin is concerned.
     * @param {Ametys.message.Message} message The message received.
     */
    _onMessage: function(message)
    {
        var skinTarget = message.getTarget(Ametys.message.MessageTarget.SKIN);
        if (skinTarget != null)
        {
            this.loadSkins();
        }
    },

    getValue: function ()
    {
    	return this.combobox.getValue();
    },
    
    setValue: function (value)
    {
    	value = Ext.Array.from(value);
    	
    	this.combobox.value = this.combobox.multiSelect ? value : value[0];
    	this.callParent([value]);
    	this.combobox.setValue(value);
    },
    
    getSubmitValue: function ()
    {
    	return this.combobox.multiSelect ? Ext.encode(this.getValue()) : this.getValue();
    },
    
    /**
     * Loads skins store
     */
    loadSkins: function ()
    {
    	Ametys.plugins.web.skin.SkinDAO.getSkins([false], Ext.bind(this._loadSkinsCb, this));
    },
   
    /**
     * Callback on retrieving the skins
     * @param {Object} response The server response
     * @param {Object[]} response.skins The list of available skins
     * @private
     */
    _loadSkinsCb: function (response)
    {
    	var currentValue = this.combobox.getValue();
        this.combobox.getStore().loadData(response.skins || []);
        
        if (this.combobox.getStore().find('id', currentValue) != -1)
        {
        	this.combobox.setValue(currentValue);
        }
        else
        {
        	this.combobox.setValue('');
        }
    },

    /**
     * Callback function invoked after retrieving the list of create actions.
     * Draw menu items for #createButton.
     * @param {Object[]} actions The list of actions
     * @private
     */
    _getCreateSkinActionsCb: function (actions)
    {
        var menuitems = [];

        for (var i=0; i < actions.length; i++)
        {
            menuitems.push(Ext.create('Ext.menu.Item', {
                text: actions[i].label,
                icon: Ametys.CONTEXT_PATH + actions[i].icon,
                handler: Ametys.getFunctionByName(actions[i].action)
            }));
        }
        
        if (menuitems.length > 0)
        {
            this.createButton.setMenu({items: menuitems});
            this.createButton.show();
        }
    },
    
    onDestroy: function ()
    {
        Ametys.message.MessageBus.unAll(this);
    }
});