Source: components/modals/dropdown.js

define('application/components/modals/dropdown', [
    'application/components/modals/abstract',
    'rofl/lib/utils',
    'rofl/widgets/container',
    'application/widgets/dropdown/item',
    'rofl/widgets/carousel',
    'rofl/widgets/carousel/aligners/natural',
    'antie/widgets/carousel/keyhandlers/activatefirsthandler',
    'rofl/widgets/carousel/aligners/basic',
    'application/widgets/guide/pointerverticalcontainer',
    'application/widgets/detail/iconbutton',
    'rofl/widgets/verticallist',
    'rofl/events/keyevent'
], function (
    Abstract,
    Utils,
    Container,
    Button,
    Carousel,
    NaturalAligner,
    ActivateFirstHandler,
    Aligner,
    PointerVerticalContainer,
    IconButton,
    VerticalList,
    KeyEvent
) {
    'use strict';

    var modalConfigParams = {
        layoutType: 'horizontal'
    };

    return Abstract.extend({

        /**
         * Initialises the button.
         */
        init: function init () {
            init.base.call(this, null, ['time-filters', 'modal', 'dropdown'], modalConfigParams);
        },

        /**
         * Creates modal component based on passed options with one button.
         */
        _createModal: function () {
            var view,
                overlay,
                topGradient = new Container(),
                bottomGradient = new Container(),
                pointerVerticalContainer = new PointerVerticalContainer(),
                carousel = this._carousel = new Carousel(null, Carousel.orientations.VERTICAL),
                aligner = this._aligner = new Aligner(carousel.getMask()),
                list = this._list = new VerticalList(),
                handler = new ActivateFirstHandler();

            topGradient.addClass(['gradient', 'top-gradient']);
            bottomGradient.addClass(['gradient', 'bottom-gradient']);

            view = this._view = new Container();
            view.addClass(['modal-view', 'modal-filter']);

            carousel.addClass('carousel');
            carousel.setAligner(aligner);
            carousel.setNormalisedAlignPoint(0.5);
            carousel.setNormalisedWidgetAlignPoint(0.5);
            carousel.setContinuousListener(true);
            handler.attach(carousel);

            overlay = this._overlay = new Container();
            overlay.addClass('overlay');

            view.appendChildWidget(carousel);
            pointerVerticalContainer.appendChildWidget(topGradient);
            pointerVerticalContainer.appendChildWidget(bottomGradient);
            pointerVerticalContainer.appendChildWidget(overlay);
            pointerVerticalContainer.appendChildWidget(view);
            list.appendChildWidget(pointerVerticalContainer);
            this.appendChildWidget(list);
        },

        /**
         * BeforeRender event.
         *
         * @param {Object} e - Inherited data.
         */
        onBeforeShow: function (e) {
            var args = e.args,
                options = args.dataOptions,
                values = args.dataValues || {},
                carousel = this._carousel,
                prevValue = args.prevValue,
                filter = args.filter,
                focusableIndex = 0,
                button,
                showGoBackButton = args.showGoBackButton;

            if (showGoBackButton) {
                this._backButton.show();
            } else {
                this._backButton.hide();
            }

            this._callback = args.callback;
            this._filterName = e.args.filter;
            this._view.addClass(this._filterName);
            carousel.removeChildWidgets();

            if (values.length) {
                Utils.each(options, function (option, index) {
                    button = new Button(option);
                    button._filterName = filter;
                    button._labelText = option;
                    button.setValueObject(values[index]);
                    carousel.appendChildWidget(button);

                    if (option === prevValue) {
                        focusableIndex = index;
                    }
                });
            }

            carousel.focus();
            carousel.alignToIndex(focusableIndex, {
                skipAnim: true
            });
        },

        /**
         * BeforeHide event.
         */
        onBeforeHide: function onBeforeHide () {
            this._view.removeClass(this._filterName);
            this._backButton.hide();
            this._carousel.removeChildWidgets();

            onBeforeHide.base.call(this);
        },

        /**
         * Select event.
         *
         * @param {event} event - Passed select event.
         */
        _onSelect: function (event) {
            var callback = this._callback,
                target = event.target,
                targetId = target.id,
                options = {
                    skipAnim: true
                };

            if (target.hasClass('up-pointer')) {
                this._carousel.alignPrevious(options);
            } else if (target.hasClass('down-pointer')) {
                this._carousel.alignNext(options);
            } else {
                if (Utils.isFunction(callback) && targetId !== 'back-button') {
                    callback(event);
                }
                this.parentWidget.back();
            }

        },

        /**
         * Returns number of assets in carousel.
         *
         * @returns {number} Number of assets.
         */
        getLengthOfAssets: function () {
            return this._carousel.getMask().getWidgetStrip().getChildWidgets().length;
        },

        /**
         * OnKeyDownEvent.
         *
         * @param {Event} event - The event data.
         */
        _onKeyDown: function _onKeyDown (event) {
            switch (event.keyCode) {
                case KeyEvent.VK_DOWN:
                    if (this._carousel.isFocussed()) {
                        this._carousel.alignToIndex(0);
                    } else if (this._backButton.isFocussed()) {
                        this._carousel.focus();
                        event.stopPropagation();
                        event.preventDefault();
                    }
                    break;
                case KeyEvent.VK_UP:
                    if (this._carousel.isFocussed()) {
                        this._carousel.alignToIndex(this._carousel.getChildWidgetCount() - 1);
                        event.stopPropagation();
                        event.preventDefault();
                    }
                    break;
                default:
                    _onKeyDown.base.call(this, event);
            }
        }
    });
});