Source: components/modals/abstract.js

define('application/components/modals/abstract', [
    'rofl/widgets/component',
    'rofl/widgets/container',
    'rofl/widgets/label',
    'application/widgets/pointerfocusablebutton',
    'rofl/events/keyevent',
    'rofl/lib/utils',
    'rofl/widgets/verticallist',
    'rofl/widgets/horizontallist',
    'application/widgets/detail/iconbutton'
], function (
    Component,
    Container,
    Label,
    PointerFocusableButton,
    KeyEvent,
    Utils,
    VerticalList,
    HorizontalList,
    IconButton
) {
    'use strict';

    return Component.extend({

        /**
         * Initialises the component.
         *
         * @param {string} [id] - The id.
         * @param {Array} [classNames] - The modal's class names.
         * @param {Object} [modalConfig] - Additional modal configuration params.
         */
        init: function init (id, classNames, modalConfig) {
            var config = modalConfig || {},
                ModalContentList = config.layoutType === 'horizontal' ? HorizontalList : VerticalList;

            init.base.call(this, id);
            this._title = null;
            this._text = null;
            this._errorCode = null;
            this._callback = null;
            this._callingComponent = null;

            this.setIsModal(true);

            if (classNames) {
                this.addClass(['modal'].concat(classNames));
            } else {
                this.addClass('modal');
            }

            this._onKeydownBound = Utils.bind(this._onKeyDown, this);
            this._onSelectBound = Utils.bind(this._onSelect, this);
            this._modalContent = new ModalContentList('modal-content');
            this._backButton = new IconButton('back-button', '', ['icon', 'icon-back-v2']);
            this._backButton.addClass('back-button');
            this.appendChildWidget(this._modalContent, true);
            this.appendChildWidget(this._backButton);

            this._createModal();
        },

        /**
         * OnBeforeRenderEvent.
         */
        onBeforeRender: function () {
            this.setListeners();
        },

        /**
         * OnBeforeShowEvent.
         *
         * @param {Event} event - Event.
         * @param {string} event.args.title - The modal title.
         * @param {string} event.args.text - The modal text.
         * @param {string} event.args.confirmButtonLabel - The modal confirm button label.
         * @param {Function} event.args.callback - The callback function, which focuses back
         * on component which called modal component.
         */
        onBeforeShow: function (event) {
            var args = event.args;

            this._title.setText(args.title || 'title');
            this._text.setText(args.text || '');

            if (args.errorCode) {
                this._errorCode.setText('(' + args.errorCode + ')');
            } else {
                this._errorCode.setText('');
            }

            this._callback = args.callback;
            this._buttonsList.removeChildWidgets();
            this._createButtons(event);
            this.showGoBackButton(args.showGoBackButton);
        },

        /**
         * OnBeforeHideEvent.
         */
        onBeforeHide: function () {
            this.removeListeners();
        },

        /**
         * Creates modal component based on passed options with one button.
         *
         * @param {Event} event - Event.
         */
        _createButtons: function (event) {
            var buttons = event.args.buttons,
                buttonList = this._buttonsList;

            Utils.each(buttons, function (buttonData) {
                var button = new PointerFocusableButton(buttonData.button),
                    label = new Label({ id: buttonData.label });

                button.addClass([buttonData.class, 'kpn-button']);
                button.appendChildWidget(label);
                buttonList.appendChildWidget(button);
                buttonList.focus();
            });
        },

        /**
         * Sets the event listeners.
         */
        setListeners: function () {
            this.addEventListener('keydown', this._onKeydownBound);
            this.addEventListener('select', this._onSelectBound);

            if (this._onBlurBound) {
                this.addEventListener('blur', this.onBlurBound);
            }

            if (this._onTextValidatedBound) {
                this.addEventListener('textvalidated', this._onTextValidatedBound);
            }

            if (this._onTextChangeBound) {
                this.addEventListener('textchange', this._onTextChangeBound);
            }
        },

        /**
         * Removes the event listeners.
         */
        removeListeners: function () {
            this.removeEventListener('keydown', this._onKeydownBound);
            this.removeEventListener('select', this._onSelectBound);

            if (this._onBlurBound) {
                this.removeEventListener('blur', this.onBlurBound);
            }

            if (this._onTextValidatedBound) {
                this.removeEventListener('textvalidated', this._onTextValidatedBound);
            }

            if (this._onTextChangeBound) {
                this.removeEventListener('textchange', this._onTextChangeBound);
            }
        },

        /**
         * Creates modal component based on passed options with one button.
         */
        _createModal: function () {
            var view, title, text, overlay, verticalList, errorCode;

            view = this._view = new Container();
            view.addClass('modal-view');

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

            verticalList = this._buttonsList = new VerticalList();
            verticalList.addClass('buttons-list');
            verticalList.focus();

            title = this._title = new Label({ text: '', classNames: 'title', enableHTML: true });

            text = this._text = new Label({ text: '', classNames: 'text', enableHTML: true });

            errorCode = this._errorCode = new Label({ text: '', classNames: ['error-code'] });

            view.appendChildWidget(title);
            view.appendChildWidget(text);
            view.appendChildWidget(errorCode);
            view.appendChildWidget(verticalList);

            this.appendChildWidget(overlay);
            this.appendChildWidget(view);
        },

        /**
         * OnKeyDownEvent.
         *
         * @param {Event} event - The event data.
         */
        _onKeyDown: function (event) {
            switch (event.keyCode) {
                case KeyEvent.VK_BACK:
                    this._onClose();
                    break;
                case KeyEvent.VK_LEFT:
                case KeyEvent.VK_RIGHT:
                    event.stopPropagation();
                    event.preventDefault();
                    break;
            }
        },

        /**
         * Select event.
         *
         * @param {event} event - Passed select event.
         */
        _onSelect: function (event) {

            switch (event.target.id) {
                case 'confirmbutton':
                    this.parentWidget.back();
                    if (Utils.isFunction(this._callback)) {
                        this._callback();
                    }
                    break;
                case 'back-button':
                    this._onClose();
                    break;
            }
        },

        /**
         * Gets executed when the popup should close.
         *
         * @private
         */
        _onClose: function () {
            this.parentWidget.back();

            if (Utils.isFunction(this._closeModalCallback)) {
                this._closeModalCallback();
            } else if (Utils.isFunction(this._callback)) {
                this._callback();
            }
        },


        /**
         * Appends widget to the component or modal content widget.
         *
         * @param {Object} widget - Widget to append.
         * @param {boolean} appendToMainContent - True if it should append to the base component.
         * @returns {Object} - The appended child widget.
         */
        appendChildWidget: function appendChildWidget (widget, appendToMainContent) {
            if (appendToMainContent) {
                return appendChildWidget.base.call(this, widget);
            }

            return this._modalContent.appendChildWidget(widget);
        },

        /**
         * Enables or disables backbutton for the modal.
         *
         * @param {boolean} show - True if the modal should set the go back button.
         */
        showGoBackButton: function (show) {
            if (show) {
                this._backButton.setDisabled(false);
                this._backButton.show();
            } else {
                this._backButton.setDisabled(true);
                this._backButton.hide({
                    skipAnim: true
                });
            }
        }
    });
});