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

/**
 * This class is the "group" container, that you can see in each tab to host buttons and other components.
 * For real, it is just a host for the three underlying icon, small, medium and large sized groups.
 */
Ext.define(
	"Ametys.ui.fluent.ribbon.Group",
	{
		extend: "Ext.container.Container",
		alias: 'widget.ametys.ribbon-group',

        statics: {
            /**
             * @readonly
             * @private
             * @property {String} SIZE_ICON The name of the iconized group in items, to find the index
             */
            SIZE_ICON: "icon",
            /**
             * @readonly
             * @private
             * @property {String} SIZE_SMALL The name of the small group in items, to find the index
             */
            SIZE_SMALL: "small",
            /**
             * @readonly
             * @private
             * @property {String} SIZE_MEDIUM The name of the medium group in items, to find the index
             */
            SIZE_MEDIUM: "medium",
            /**
             * @readonly
             * @private
             * @property {String} SIZE_LARGE The name of the large group in items, to find the index
             */
            SIZE_LARGE: "large"
        },
        
        /**
         * @property {String} groupCls The CSS classname to set on the group
         * @readonly
         * @private
         */
        groupCls: 'a-fluent-group',
        
		/**
		 * @cfg {String} layout Doesn't apply to ribbon element. The value HAS TO be the default value.
		 * @private
		 */
		layout: 'card',

        
		/**
		 * @cfg {Boolean} frame Doesn't apply to ribbon element. The value HAS TO be the default value.
		 * @private
		 */
		frame: false,
		/**
		 * @cfg {String} defaultType Doesn't apply to ribbon element. The value HAS TO be the default value.
		 * @private
		 */
		/**
		 * @cfg {Object} defaults Doesn't apply to ribbon element. The value HAS TO be the default value.
		 * @private
		 */

		/**
		 * @cfg {Number} width Doesn't apply to ribbon element. The value HAS TO be the default value.
		 * @private
		 */

        /**
         * @cfg {Object[]} iconItems Items in the group when it is in icon size 
         */
		/**
		 * @cfg {Object[]} smallItems Items in the group when it is in small size 
		 */
		/**
		 * @cfg {Object[]} items Items in the group when it is in medium size. Beware that those items will not be transmitted as direct children of this panel.
		 */
		/**
		 * @cfg {Object[]} largeItems Items in the group when it is in large size
		 */
		/**
		 * @cfg {Boolean} dialogBoxLauncher When true, a tool button to launch a dialog box will be set in the header. It will launch the event {@link #dialogboxlaunch}
		 */
		/**
         * @cfg {String} icon Full path to the icon reprensenting the group when collapsed
		 */
        /**
         * @cfg {String} iconGlyph Glyph name reprensenting the group when collapsed
         */
        /**
         * @cfg {String} title The group title
         */

		/**
		 * @property {Object[]} items The children of the group. The items here are not thoses given in the configuration. You will find here 1, 2 or 3 items, that are the medium container and optionnaly the large and/or the small ones.
		 */
		
		/**
		 * @private
		 * @property {Object} _scaleContainer Is an association between ("icon", "small", "medium" and "large") with the index of the associated container in the {@link #property-items} property. Will be null if the container does not exist
		 */
		
		/**
		 * Creates a group
		 * @param {Object} config The configuration object
		 */
		constructor: function(config)
		{
            config = config || {};
            
            config.cls = Ext.Array.from(config.cls);
            config.cls.push(this.groupCls);
            
            var mediumItems = config.items;
            config.items = [];
            
            var defaultConfig = {
                xtype: 'ametys.ribbon-groupscale',
                title: config.title,
                tools: []
            };
            
            // Initialize the pointers
            this._scaleContainer = {};
            
            // Add the dialogbox launcher
            if (config.dialogBoxLauncher)
            {
                defaultConfig.tools.push({
                    type: 'openlinkto',
                    handler: Ext.bind(this._onDialogBoxLauncherClickSendEvent, this)
                });
            }                
            
            // Creates the icon sized container
            config.items.push(Ext.applyIf({
                cls: this.groupCls + "-icon",
                title: " ",
                tools: [],
                
                items: [ {
                    xtype: 'ametys.ribbon-button',
                    text: config.title,
                    icon: config.icon,
                    iconCls: "a-ribbon-button-default-icon " + config.iconGlyph, // this ensure that button will be structured with an icon, even if icon is undefined
                    iconAlign: 'top',
                    scale: 'large',
                    arrowAlign: 'bottom',
                    menu: {
                        plain: true,
                        minWidth: 1, 
                        items: [ {xtype: 'container'} ]
                    },
                    listeners: {
                        'menushow': this._onIconizedMenuShow,
                        'menuhide': this._onIconizedMenuHide,
                        scope: this
                    }
                }]
            }, defaultConfig));
            this._scaleContainer[Ametys.ui.fluent.ribbon.Group.SIZE_ICON] = config.items.length - 1;
            
			// Creates a smallContainer if smallItems are set
			if (config.smallItems && config.smallItems.length > 0)
			{
				config.items.push(Ext.apply({
                    cls: this.groupCls + "-small",
					items: config.smallItems
				}, defaultConfig));
                this._scaleContainer[Ametys.ui.fluent.ribbon.Group.SIZE_SMALL] = config.items.length - 1; 
			}
			
			// Creates a mediumContainer (items are mandatory)
            config.items.push(Ext.apply({
                cls: this.groupCls + "-medium",
                items: mediumItems
            }, defaultConfig));            
            config.activeItem = this._scaleContainer[Ametys.ui.fluent.ribbon.Group.SIZE_MEDIUM] = config.items.length - 1;
            
			// Creates a largeContainer if largeItems are set
			if (config.largeItems && config.largeItems.length > 0)
			{
                config.items.push(Ext.apply({
                    cls: this.groupCls + "-large",
                    items: config.largeItems
                }, defaultConfig));
                config.activeItem = this._scaleContainer[Ametys.ui.fluent.ribbon.Group.SIZE_LARGE] = config.items.length - 1;
			}

			this.callParent([config]);
		},
        
        /**
         * @private
         * The icon button menu is shown: let's insert the buttons in the menu
         * @param {Ext.button.Button} button The icon button
         * @param {Ext.menu.Menu} menu The menu displayed
         */
        _onIconizedMenuShow: function(button, menu)
        {
            var groupContainer = menu.items.get(0);
            var smallerGroupScale = this.items.get(1); 
            groupContainer.add(smallerGroupScale);
            smallerGroupScale.show();
        },
		        
        /**
         * @private
         * The icon button menu is hiden: let's put the buttons back in the ribbon
         * @param {Ext.button.Button} button The icon button
         * @param {Ext.menu.Menu} menu The menu displayed
         */
        _onIconizedMenuHide: function(button, menu)
        {
            var groupContainer = menu.items.get(0);
            var smallerGroupScale = groupContainer.items.get(0); 
            smallerGroupScale.hide();
            this.items.insert(1, smallerGroupScale);
        },
        
		/**
		 * @private
		 * Listener on dialog box launcher tool to fire the event
		 */
		_onDialogBoxLauncherClickSendEvent: function ()
		{
            /**
             * @event dialogboxlaunch
             * Fires when the dialog box button was clicked
             * @param {Ext.Panel} p the current Panel.
             */
			this.fireEvent('dialogboxlaunch', this);
		},
		
		/**
		 * Get the currently set scale
		 * @return {String} The scale as a constant (such as Ametys.ui.fluent.ribbon.Group#SIZE_MEDIUM)
		 */
		getScale: function()
		{
            var scale = null;
            
            var currentIndex = this.items.indexOf(this.getLayout().getActiveItem());
            Ext.Object.each(this._scaleContainer, function (key, value) {
                if (value == currentIndex)
                {
                    scale = key;
                    return false;
                }
            });
            
			return scale;
		},

		/**
		 * Is the given scale supported?
		 * @param {String} newScale The scale to test
		 * @returns {Boolean} true if the scale does exist, false if not
		 */
		supportScale: function(newScale)
		{
			return this._scaleContainer[newScale] != null;
		},
		
		/**
		 * Change the scale. If the new scale is not supproted, the method will silently fail.
		 * @param {String} newScale The scale to set.
		 */
		setScale: function(newScale)
		{
			if (newScale == this.scale || !this.supportScale(newScale))
			{
				return;
			}

            this.getLayout().setActiveItem(this._scaleContainer[newScale]);
		}
	}
);