    /**
     * @class Ext.button.Cycle
     * @extends Ext.button.Split
     * A specialized SplitButton that contains a menu of {@link Ext.menu.CheckItem} elements.  The button automatically
     * cycles through each menu item on click, raising the button's {@link #change} event (or calling the button's
     * {@link #changeHandler} function, if supplied) for the active menu item. Clicking on the arrow section of the
     * button displays the dropdown menu just like a normal SplitButton.
     * {@img Ext.button.Cycle/Ext.button.Cycle.png Ext.button.Cycle component}
     * Example usage:
     * <pre><code>
    Ext.create('Ext.button.Cycle', {
        showText: true,
        prependText: 'View as ',
        renderTo: Ext.getBody(),
        menu: {
            id: 'view-type-menu',
            items: [{
                text:'text only',
                iconCls:'view-text',
                checked:true
            },{
                text:'HTML',
                iconCls:'view-html'
            }]
        },
        changeHandler:function(cycleBtn, activeItem){
            Ext.Msg.alert('Change View', activeItem.text);
        }
    });
    </code></pre>
     */
    Ext.define('Ext.button.Cycle', {

        /* Begin Definitions */

        alias: 'widget.cycle',

        extend: 'Ext.button.Split',
        alternateClassName: 'Ext.CycleButton',

        /* End Definitions */

        /**
         * @cfg {Array} items <p>Deprecated as of 4.0. Use the {@link #menu} config instead. All menu items will be created
         * as {@link Ext.menu.CheckItem CheckItem}s.</p>
         * <p>An array of {@link Ext.menu.CheckItem} <b>config</b> objects to be used when creating the
         * button's menu items (e.g., {text:'Foo', iconCls:'foo-icon'})
         */
        /**
         * @cfg {Boolean} showText True to display the active item's text as the button text (defaults to false).
         * The Button will show its configured {@link #text} if this. config is omitted.
         */
        /**
         * @cfg {String} prependText A static string to prepend before the active item's text when displayed as the
         * button's text (only applies when showText = true, defaults to '')
         */
        /**
         * @cfg {Function} changeHandler A callback function that will be invoked each time the active menu
         * item in the button's menu has changed.  If this callback is not supplied, the SplitButton will instead
         * fire the {@link #change} event on active item change.  The changeHandler function will be called with the
         * following argument list: (SplitButton this, Ext.menu.CheckItem item)
         */
        /**
         * @cfg {String} forceIcon A css class which sets an image to be used as the static icon for this button.  This
         * icon will always be displayed regardless of which item is selected in the dropdown list.  This overrides the
         * default behavior of changing the button's icon to match the selected item's icon on change.
         */
        /**
         * @property menu
         * @type Menu
         * The {@link Ext.menu.Menu Menu} object used to display the {@link Ext.menu.CheckItem CheckItems} representing the available choices.
         */

        // private
        getButtonText: function(item) {
            var me = this,
                text = '';

            if (item && me.showText === true) {
                if (me.prependText) {
                    text += me.prependText;
                }
                text += item.text;
                return text;
            }
            return me.text;
        },

        /**
         * Sets the button's active menu item.
         * @param {Ext.menu.CheckItem} item The item to activate
         * @param {Boolean} suppressEvent True to prevent the button's change event from firing (defaults to false)
         */
        setActiveItem: function(item, suppressEvent) {
            var me = this;

            if (!Ext.isObject(item)) {
                item = me.menu.getComponent(item);
            }
            if (item) {
                if (!me.rendered) {
                    me.text = me.getButtonText(item);
                    me.iconCls = item.iconCls;
                } else {
                    me.setText(me.getButtonText(item));
                    me.setIconCls(item.iconCls);
                }
                me.activeItem = item;
                if (!item.checked) {
                    item.setChecked(true, false);
                }
                if (me.forceIcon) {
                    me.setIconCls(me.forceIcon);
                }
                if (!suppressEvent) {
                    me.fireEvent('change', me, item);
                }
            }
        },

        /**
         * Gets the currently active menu item.
         * @return {Ext.menu.CheckItem} The active item
         */
        getActiveItem: function() {
            return this.activeItem;
        },

        // private
        initComponent: function() {
            var me = this,
                checked = 0,
                items;

            me.addEvents(
                /**
                 * @event change
                 * Fires after the button's active menu item has changed.  Note that if a {@link #changeHandler} function
                 * is set on this CycleButton, it will be called instead on active item change and this change event will
                 * not be fired.
                 * @param {Ext.button.Cycle} this
                 * @param {Ext.menu.CheckItem} item The menu item that was selected
                 */
                "change"
            );

            if (me.changeHandler) {
                me.on('change', me.changeHandler, me.scope || me);
                delete me.changeHandler;
            }

            // Allow them to specify a menu config which is a standard Button config.
            // Remove direct use of "items" in 5.0.
            items = (me.menu.items||[]).concat(me.items||[]);
            me.menu = Ext.applyIf({
                cls: Ext.baseCSSPrefix + 'cycle-menu',
                items: []
            }, me.menu);

            // Convert all items to CheckItems
            Ext.each(items, function(item, i) {
                item = Ext.applyIf({
                    group: me.id,
                    itemIndex: i,
                    checkHandler: me.checkHandler,
                    scope: me,
                    checked: item.checked || false
                }, item);
                me.menu.items.push(item);
                if (item.checked) {
                    checked = i;
                }
            });
            me.itemCount = me.menu.items.length;
            me.callParent(arguments);
            me.on('click', me.toggleSelected, me);
            me.setActiveItem(checked, me);

            // If configured with a fixed width, the cycling will center a different child item's text each click. Prevent this.
            if (me.width && me.showText) {
                me.addCls(Ext.baseCSSPrefix + 'cycle-fixed-width');
            }
        },

        // private
        checkHandler: function(item, pressed) {
            if (pressed) {
                this.setActiveItem(item);
            }
        },

        /**
         * This is normally called internally on button click, but can be called externally to advance the button's
         * active item programmatically to the next one in the menu.  If the current item is the last one in the menu
         * the active item will be set to the first item in the menu.
         */
        toggleSelected: function() {
            var me = this,
                m = me.menu,
                checkItem;

            checkItem = me.activeItem.next(':not([disabled])') || m.items.getAt(0);
            checkItem.setChecked(true);
        }
    });