Metal Detector / js /

app.ui.js

/*
 * Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
 *
 * 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.
 */

/*global window, document*/

/**
 * Application UI module.
 * It is responsible for managing user interface.
 *
 * @module app.ui
 * @requires {@link app.model}
 * @namespace app.ui
 * @memberof app
 */

// make sure that "app" namespace is created
window.app = window.app || {};

// strict mode wrapper
(function defineAppUi(app) {
    'use strict';

    /**
     * Signal indicator bars count.
     *
     * @memberof app.ui
     * @private
     * @const {number}
     */
    var SIGNAL_INDICATOR_BARS_COUNT = 9,

        /**
         * Percentage width for signal-strength on indicator bars.
         * example: Indicator layer with set width SIGNAL_INDICATOR_PERCENT[4]
         * + % will highlight four indicator bars.
         *
         * @memberof app.ui
         * @private
         * @const {number[]}
         */
        SIGNAL_INDICATOR_PERCENT = [29, 34, 40, 50, 56, 63, 73, 81, 89, 100],

        /**
         * Not sensor not supported error.
         *
         * @memberof app.ui
         * @private
         * @const {string}
         */
        SENSOR_NOT_SUPPORTED_ERROR_MSG = 'Magnetic sensor\n is not ' +
            'supported\n on this device.',

        /**
         * Sensor failure error message.
         *
         * @memberof app.ui
         * @private
         * @const {string}
         */
        SENSOR_FALIURE_ERROR_MSG = 'Magnetic sensor\nfailed.',

        /**
         * Unknown error message.
         *
         * @memberof app.ui
         * @private
         * @const {string}
         */
        UNKNOWN_ERROR_MSG = 'Magnetic sensor\nunknown error\noccurred.\n' +
            'Application may not\nwork correctly',

        /**
         * Signal strength value element.
         *
         * @memberof app.ui
         * @private
         * @type {HTMLElement}
         */
        signalStrengthValueEl = null,

        /**
         * Signal strength indicator holding active indicator bars.
         *
         * @memberof app.ui
         * @private
         * @type {HTMLElement}
         */
        signalStrengthIndicatorEl = null,

        /**
         * Signal direction indicator element.
         *
         * @memberof app.ui
         * @private
         * @param {HTMLElement}
         */
        signalDirectionIndicatorEl = null,

        /**
         * Signal strength indicator active layer.
         *
         * @memberof app.ui
         * @private
         * @param {HTMLElement}
         */
        signalStrengthOnEl = null,

        /**
         * Signal strength indicator background layer.
         *
         * @memberof app.ui
         * @private
         * @param {HTMLElement}
         */
        signalStrengthOffEl = null,

        /**
         * If set to true signal direction indicators are visible.
         *
         * @memberof app.ui
         * @private
         * @type {boolean}
         */
        indicatorsTurnedOn = false,

        /**
         * Application model module reference.
         *
         * @memberof app.ui
         * @private
         * @type {object}
         */
        model = null;

    // create namespace for the module
    app.ui = app.ui || {};

    /**
     * Sets magnetic field strength value.
     *
     * @memberof app.ui
     * @private
     * @param {number} value
     */
    function setValue(value) {
        signalStrengthValueEl.innerText = value.toFixed(0);
    }

    /**
     * Highlights signal strength indicator bars.
     *
     * @memberof app.ui
     * @private
     * @param {number} value
     */
    function setSignalStrengthIndicator(value) {
        // how many indicator bars should be highlighted; logarithmic scale
        var indicatorCount =
                model.calculateRelativeSignalStrength(value,
                    SIGNAL_INDICATOR_BARS_COUNT);

        signalStrengthIndicatorEl.style.height =
            SIGNAL_INDICATOR_PERCENT[indicatorCount] + '%';
    }

    /**
     * Turns off direction and strength indicators.
     *
     * @memberof app.ui
     * @private
     */
    function turnOffIndicators() {
        indicatorsTurnedOn = false;
        signalDirectionIndicatorEl.classList.add('off');
        signalStrengthIndicatorEl.classList.add('hidden');
        signalStrengthOnEl.classList.add('hidden');
        signalStrengthOffEl.classList.add('hidden');
    }

    /**
     * Turns on direction and strength indicators.
     *
     * @memberof app.ui
     * @private
     */
    function turnOnIndicators() {
        indicatorsTurnedOn = true;
        signalDirectionIndicatorEl.classList.remove('off');
        signalStrengthIndicatorEl.classList.remove('hidden');
        signalStrengthOnEl.classList.remove('hidden');
        signalStrengthOffEl.classList.remove('hidden');
    }

    /**
     * Sets rotate direction indicators rotation.
     *
     * @memberof app.ui
     * @private
     * @param {number} rotation Rotation value in degrees.
     */
    function rotateDirectionIndicators(rotation) {
        signalDirectionIndicatorEl
            .style.webkitTransform = 'rotate(' + rotation + 'deg)';
        signalStrengthOnEl
            .style.webkitTransform = 'rotate(' + rotation + 'deg)';
        signalStrengthOffEl
            .style.webkitTransform = 'rotate(' + rotation + 'deg)';
    }

    /**
     * Handles model "model.magnetic.ready" event.
     *
     * @memberof app.ui
     * @private
     */
    function onMagneticReady() {
        turnOnIndicators();
    }

    /**
     * Handles model "model.magnetic.update" event.
     *
     * @memberof app.ui
     * @private
     * @param {CustomEvent} event
     */
    function onMagneticUpdate(event) {
        var data = event.detail,
            value = data.value,
            rotation = data.rotation,
            rotationVisible = data.rotationVisible;

        if (indicatorsTurnedOn && !rotationVisible) {
            turnOffIndicators();
        } else if (!indicatorsTurnedOn && rotationVisible) {
            turnOnIndicators();
        }

        setValue(value);
        setSignalStrengthIndicator(value);
        if (indicatorsTurnedOn) {
            rotateDirectionIndicators(rotation);
        }
    }

    /**
     * Handles model "model.magnetic.error" event.
     *
     * @memberof app.ui
     * @private
     * @param {CustomEvent} event
     */
    function onMagneticError(event) {
        var type = event.detail;

        switch (type) {
        case model.ERROR.NOT_SUPPORTED:
            window.alert(SENSOR_NOT_SUPPORTED_ERROR_MSG);
            model.exitApplication();
            break;
        case model.ERROR.START_FAILURE:
            window.alert(SENSOR_FALIURE_ERROR_MSG);
            model.exitApplication();
            break;
        default:
            window.alert(UNKNOWN_ERROR_MSG);
        }
    }

    /**
     * Registers event listeners.
     *
     * @memberof app.ui
     * @private
     */
    function bindEvents() {
        window.addEventListener('model.magnetic.ready', onMagneticReady);
        window.addEventListener('model.magnetic.update', onMagneticUpdate);
        window.addEventListener('model.magnetic.error', onMagneticError);
    }

    /**
     * Initialize application.
     *
     * @memberof app.ui
     * @public
     */
    function init() {
        model = app.model;
        signalStrengthValueEl =
            document.getElementById('value-number');
        signalStrengthIndicatorEl =
            document.querySelector('#signal-strength-on .resizable');
        signalDirectionIndicatorEl =
            document.getElementById('signal-direction-indicator');
        signalStrengthOnEl =
            document.getElementById('signal-strength-on');
        signalStrengthOffEl =
            document.getElementById('signal-strength-off');

        bindEvents();
        model.init();
    }

    app.ui.init =  init;

})(window.app);