Source: components/settings.js

define('application/components/settings', [
    'rofl/widgets/component',
    'rofl/widgets/label',
    'rofl/widgets/container',
    'rofl/lib/l10n',
    'antie/runtimecontext',
    'rofl/lib/utils',
    'rofl/events/keyevent',
    'rofl/analytics/web/google',
    'rofl/widgets/horizontallist',
    'application/widgets/clock',
    'application/widgets/settings/button',
    'antie/storageprovider',
    'application/managers/feature',
    'application/managers/session'
], function (
    Component,
    Label,
    Container,
    L10N,
    RuntimeContext,
    Utils,
    KeyEvent,
    GoogleAnalytics,
    HorizontalList,
    Clock,
    Button,
    StorageProvider,
    FeatureManager,
    SessionManager
) {
    'use strict';

    var l10n = L10N.getInstance(),
        application = RuntimeContext.getCurrentApplication(),
        Settings,
        GA = GoogleAnalytics.getInstance(),
        device = RuntimeContext.getDevice(),
        sessionManager = SessionManager.getInstance(),
        version = application.getConfiguration().version,
        storage;

    Settings = Component.extend({

        /**
         * Initialises the component.
         */
        init: function init () {
            init.base.call(this, 'settings');
            storage = device.getStorage(StorageProvider.STORAGE_TYPE_SESSION, 'storage');

            this._build();

            this._parentalSetting = false;
            this._subtitlesSetting = false;

            this._lastFocusedWidget = null;

            this._createVersionLabel();
            this._getParentalSetting();
            this._getSubtitlesSetting();

            this._onKeyDownBound = Utils.bind(this._onKeyDown, this);
            this._onSelectBound = Utils.bind(this._onSelect, this);
        },

        /**
         * Creates the version label.
         *
         * @private
         */
        _createVersionLabel: function () {
            var versionText = l10n.get('menu.version') + ' ' + version,
                versionLabel = new Label({ text: versionText, classNames: ['version'] });

            this.appendChildWidget(versionLabel);
        },

        /**
         * Builds the component.
         *
         * @private
         */
        _build: function () {
            this._buildBackButton();
            this._buildGradient();
            this._buildTitle();
            this._buildClock();
            this._buildSettingsButtons();
        },

        /**
         * Builds the top bar list.
         *
         * @private
         */
        _buildBackButton: function () {
            var topBar = this._topBar = new HorizontalList(),
                branding = this._branding = new Container();

            branding.addClass('page-branding');
            topBar.addClass('topbar');
            topBar.appendChildWidget(branding);
            this.appendChildWidget(topBar);
        },

        /**
         * Builds the top bar list.
         *
         * @private
         */
        _buildGradient: function () {
            var gradient = this._gradient = new Container();

            gradient.addClass('gradient');

            this._topBar.appendChildWidget(gradient);
        },

        /**
         * Builds the title.
         *
         * @private
         */
        _buildTitle: function () {
            var title = this._title = new Label({ text: l10n.get('settings.title'), classNames: ['top-title'] });

            this._branding.appendChildWidget(title);
        },

        /**
         * Builds the clock.
         *
         * @private
         */
        _buildClock: function () {
            var clock = this._clock = new Clock();

            clock.addClass('header-clock');
            this._topBar.appendChildWidget(clock);
        },

        /**
         * Builds settings buttons.
         *
         * @private
         */
        _buildSettingsButtons: function () {
            var buttonsList = this._buttonsList = new HorizontalList('settings-actions'),
                buttonChildLock = this._buttonChildLock = new Button(l10n.get('settings.buttons.child_lock'), 'child-lock'),
                buttonSubtitles = this._buttonSubtitles = new Button(l10n.get('settings.buttons.subtitles'), 'subtitles'),
                buttonLogout = new Button(l10n.get('settings.buttons.logout'), 'logout');

            buttonChildLock.getLabelIcon().addClass('icon-lock');
            buttonSubtitles.getLabelIcon().addClass('icon-subtitles');
            buttonLogout.getLabelIcon().addClass('icon-logout');

            buttonChildLock.setOnOffValue(this._getParentalSetting());
            buttonSubtitles.setOnOffValue(this._getSubtitlesSetting());

            if (FeatureManager.getInstance().isParentalEnabled()) {
                buttonsList.appendChildWidget(buttonChildLock);
            }

            if (FeatureManager.getInstance().isSubtitlesEnabled()) {
                buttonsList.appendChildWidget(buttonSubtitles);
            }

            buttonsList.appendChildWidget(buttonLogout);

            this.appendChildWidget(buttonsList);
        },

        /**
         * Handle KeyEvent.
         *
         * @param {KeyEvent} e - KeyEvent instance.
         * @private
         */
        _onKeyDown: function (e) {

            switch (e.keyCode) {
                case KeyEvent.VK_LEFT:
                    e.stopPropagation();

                    application.focusMenu('main');
                    break;
                case KeyEvent.VK_RIGHT:
                    e.stopPropagation();
                    break;
                case KeyEvent.VK_BACK:
                    this._onClose();
                    break;
            }
        },

        /**
         * Stores settings value to storage.
         *
         * @param {boolean} value - Value.
         * @private
         */
        _storeSubtitlesSetting: function (value) {
            storage.setItem('subtitles', value);
            this._subtitlesSetting = value;

            this._setEventListeners();
            this._buttonSubtitles.setOnOffValue(value);
        },

        /**
         * Returns subtitles setting.
         *
         * @returns {boolean|*} Subtitles setting.
         * @private
         */
        _getSubtitlesSetting: function () {
            this._subtitlesSetting = storage.getItem('subtitles');

            return this._subtitlesSetting;
        },

        /**
         * Stores settings value to storage.
         *
         * @param {boolean} value - Value.
         * @private
         */
        _storeParentalSetting: function (value) {
            storage.setItem('parental', value);
            this._parentalSetting = value;

            if (value) {
                sessionManager.setUserPin(null);
            }

            this._setEventListeners();
            this._buttonChildLock.setOnOffValue(value);
        },

        /**
         * Returns childlock setting.
         *
         * @returns {boolean|*} Childlock setting.
         * @private
         */
        _getParentalSetting: function () {
            this._parentalSetting = storage.getItem('parental');

            return this._parentalSetting;
        },

        /**
         * Callback when modal closes.
         *
         * @private
         */
        _closeModalCallback: function () {

            this._setEventListeners();
            this._lastFocusedWidget.focus();
        },

        /**
         * Reopens settings modal.
         *
         * @private
         */
        _reopenChildLockModal: function () {
            application.route('settingsmodal', {
                title: l10n.get('settings.parental.title'),
                subtitle: l10n.get('settings.parental.subtitle'),
                description: l10n.get('settings.parental.description'),
                onOff: this._parentalSetting,
                iconClass: 'icon-lock',
                pinCallback: Utils.bind(this._checkPIN, this),
                closeModalCallback: Utils.bind(this._closeModalCallback, this)
            });
        },

        /**
         * Check pin.
         *
         * @param {string} value - Pin value.
         * @private
         */
        _checkPIN: function (value) {
            application.route('parentalpin', {
                successCallback: Utils.bind(function () {
                    this._lastFocusedWidget.focus();
                    this._storeParentalSetting(value);
                }, this),
                escapeCallback: Utils.bind(this._reopenChildLockModal, this),
                description: l10n.get('settings.parental.modal_description'),
                errorCallback: Utils.bind(function (result) {

                    if (Utils.getNested(result, 'resultObj', 'remainingAttempts') === 0) {

                        this.focus();
                        this._setEventListeners();
                    }
                }, this)
            });

        },

        /**
         * OnSelect event.
         *
         * @param {Object} e - Event.
         * @private
         */
        _onSelect: function (e) {
            var selectedId = e.target.id;

            this._lastFocusedWidget = e.target;

            switch (selectedId) {
                case 'logout':
                    application.route('logout');
                    break;
                case 'child-lock':
                    this._removeEventListeners();
                    application.route('settingsmodal', {
                        title: l10n.get('settings.parental.title'),
                        subtitle: l10n.get('settings.parental.subtitle'),
                        description: l10n.get('settings.parental.description'),
                        onOff: this._parentalSetting,
                        callback: Utils.bind(this._storeParentalSetting, this),
                        iconClass: 'icon-lock',
                        pinCallback: Utils.bind(this._checkPIN, this),
                        closeModalCallback: Utils.bind(this._closeModalCallback, this)
                    });
                    break;
                case 'subtitles':
                    this._removeEventListeners();
                    application.route('settingsmodal', {
                        title: l10n.get('settings.subtitles.title'),
                        subtitle: l10n.get('settings.subtitles.title'),
                        description: l10n.get('settings.subtitles.description'),
                        onOff: this._subtitlesSetting,
                        callback: Utils.bind(this._storeSubtitlesSetting, this),
                        iconClass: 'icon-subtitles',
                        closeModalCallback: Utils.bind(this._closeModalCallback, this)
                    });
                    break;
            }
        },

        /**
         * BeforeShow event.
         */
        onBeforeShow: function () {

            this._setEventListeners();
            GA.onPageView('settings');
            this._buttonsList.setActiveChildIndex(0);
            this._buttonsList.focus();
            application.hideLoader();
            this._lastFocusedWidget = application.getFocussedWidget();
            this._buttonChildLock.setOnOffValue(this._getParentalSetting());
        },

        /**
         * BeforeHide event.
         */
        onBeforeHide: function () {
            this._removeEventListeners();
        },

        /**
         * Sets the event listeners.
         *
         * @private
         */
        _setEventListeners: function () {
            if (this._listening) {
                return;
            }

            this._listening = true;
            this.addEventListener('keydown', this._onKeyDownBound);
            this._buttonsList.addEventListener('select', this._onSelectBound);
        },

        /**
         * Removes the event listeners.
         *
         * @private
         */
        _removeEventListeners: function () {
            if (this._listening) {
                this._listening = false;
                this.removeEventListener('keydown', this._onKeyDownBound);
                this.removeEventListener('select', this._onSelectBound);
            }
        },

        /**
         * Executes the close functionality.
         */
        _onClose: function () {

            // Go back and focus the player.
            application.focusMenu('main');
        }
    });

    return Settings;
});