/*
 * 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 define, document, tau */

/**
 * Details view module.
 * @requires {@link core/event}
 * @requires {@link SoundManager/helpers/ui}
 * @requires {@link SoundManager/models/soundProfiles}
 * @namespace SoundManager/views/details
 * @memberof SoundManager/views
 */
define({
    name: 'views/details',
    requires: [
        'core/event',
        'helpers/ui',
        'models/soundProfiles'
    ],
    def: function main(req) {
        'use strict';

        /**
         * Event module instance.
         * @type {Module}
         */
        var event = req.core.event,

            /**
             * Ui helper module instance.
             * @type {Module}
             */
            uiHelper = req.helpers.ui,

            /**
             * SoundProfiles module instance.
             * @type {Module}
             */
            soundProfiles = req.models.soundProfiles,

            /**
             * Reference to sound types list.
             * @type {HTMLElement}
             */
            soundTypesList = null,

            /**
             * Displayed sound profile.
             * @type {object}
             */
            profile = null,

            /**
             * Copy of loaded sound profile. Used to reset the profile to
             * initial values.
             * @type {object}
             */
            originalProfile = null,

            /**
             * Reference to page header.
             * @type {HTMLElement}
             */
            pageHeader = null,

            /**
             * Map of slider objects, where key is sound type string and value
             * is an object with the following fields:
             * {
             * widget: TAU Slider widget,
             * input: Input range HTML element,
             * label: Span HTML element displaying value of the slider
             * }
             * @type {object}
             */
            sliders = {},

            /**
             * Reference to reset button.
             * @type {HTMLElement}
             */
            resetButton = null,

            /**
             * Reference to 'delete' button.
             * @type {HTMLElement}
             */
            deleteButton = null,

            /**
             * Reference to 'yes' button on the 'confirm deletion' panel.
             * @type {HTMLElement}
             */
            confirmDeleteButton = null,

            /**
             * Reference to the page element.
             * @type {HTMLElement}
             */
            page = null,

            /**
             * Reference to the 'delete profile' popup.
             * @type {HTMLElement}
             */
            deletePopup = null,

            /**
             * Indicates whether the user tapped the confirm button on the
             * 'delete profile' popup or not.
             * @type {boolean}
             */
            isDeleteConfirmed = false;

        /**
         * Loads sound types.
         */
        function loadSoundTypes() {
            var templateArguments = [],
                soundTypes = soundProfiles.getSoundTypes(),
                i = 0;

            for (i = 0; i < soundTypes.length; i += 1) {
                templateArguments.push({name: soundTypes[i]});
            }

            uiHelper.fillList(soundTypesList, templateArguments,
                'soundTypeItem');
        }

        /**
         * Updates text of the slider label related to the specified sound type.
         * @param {string} soundType
         */
        function refreshSliderLabel(soundType) {
            sliders[soundType].label.innerText =
                (sliders[soundType].input.value * 10) + '%';
        }

        /**
         * Updates slider of given type with proper value.
         * @param {string} soundType
         */
        function refreshSlider(soundType) {
            var slider = sliders[soundType].widget;
            slider.value(profile[soundType] * 10);
            slider.refresh();
            refreshSliderLabel(soundType);
        }

        /**
         * Loads sound profile.
         */
        function loadProfile() {
            var soundTypes = soundProfiles.getSoundTypes(), i = 0;
            pageHeader.innerText = profile.title;

            for (i = 0; i < soundTypes.length; i += 1) {
                refreshSlider(soundTypes[i]);
            }
        }

        /**
         * Returns cloned soundProfile variable.
         * @returns {object}
         */
        function cloneProfile() {
            var clone = {},
                soundTypes = soundProfiles.getSoundTypes(),
                soundType = null,
                i = 0;

            for (i = 0; i < soundTypes.length; i += 1) {
                soundType = soundTypes[i];
                clone[soundType] = profile[soundType];
            }

            return clone;
        }

        /**
         * Handles 'views.main.profile.clicked' event.
         * @param {event} ev
         */
        function onOpenedProfile(ev) {
            profile = soundProfiles.getProfile(ev.detail);
            originalProfile = cloneProfile();
        }

        /**
         * Handles click event on reset button.
         */
        function onResetClicked() {
            var soundTypes = soundProfiles.getSoundTypes(),
                soundType = null,
                i = 0;

            for (i = 0; i < soundTypes.length; i += 1) {
                soundType = soundTypes[i];
                if (originalProfile[soundType] !== profile[soundType]) {
                    soundProfiles.updateProfile(profile.id, soundType,
                        originalProfile[soundType]);
                    refreshSlider(soundType);
                }
            }
        }

        /**
         * Registers event listeners for list item content elements related to
         * the specified sound type.
         * @param {string} soundType
         */
        function bindListItemEvents(soundType) {
            var sliderInput = sliders[soundType].input;

            sliderInput.addEventListener('change', function updateSpan() {
                refreshSliderLabel(soundType);
                soundProfiles.updateProfile(profile.id, soundType,
                    sliderInput.value / 10);
            });
        }

        /**
         * Handles close events of the 'delete profile' popup.
         */
        function onDeletePopupClose() {
            if (isDeleteConfirmed) {
                isDeleteConfirmed = false;
                tau.back();
            }
        }

        /**
         * Handles click event on 'delete' button.
         */
        function onConfirmDeleteClicked() {
            soundProfiles.deleteProfile(profile.id);
            isDeleteConfirmed = true;
        }

        /**
         * Initializes TAU slider widgets.
         */
        function initSliders() {
            var soundTypes = soundProfiles.getSoundTypes(),
                soundType = null,
                rangeInput = null,
                i = 0;

            for (i = 0; i < soundTypes.length; i += 1) {
                soundType = soundTypes[i];
                rangeInput = document.getElementById(soundType);
                sliders[soundType] = {
                    input: rangeInput,
                    label: document.querySelector('label[for="' +
                        soundType + '"] span'),
                    widget: null // will be initialized by the initSliderWidgets
                    // function when the page will be rendered
                };
                bindListItemEvents(soundType);
                refreshSliderLabel(soundType);
            }
        }

        /**
         * Initializes TAU Slider widgets.
         */
        function initSliderWidgets() {
            var soundTypes = soundProfiles.getSoundTypes(),
                sliderData = null,
                len = soundTypes.length,
                i = 0;

            for (i = 0; i < len; i += 1) {
                sliderData = sliders[soundTypes[i]];
                sliderData.widget = tau.widget.Slider(sliderData.input);
            }
        }

        /**
         * Handles the 'pagebeforeshow' event.
         */
        function onPageBeforeShow() {
            initSliderWidgets();
            loadProfile();
        }

        /**
         * Registers event listeners.
         */
        function bindEvents() {
            resetButton.addEventListener('click', onResetClicked);
            deleteButton.addEventListener('click', function onClick() {
                uiHelper.openPopup('deleteProfilePopup');
            });
            confirmDeleteButton.addEventListener('click',
                onConfirmDeleteClicked);

            page.addEventListener('pagebeforeshow', onPageBeforeShow, false);
            deletePopup.addEventListener('popupafterclose', onDeletePopupClose);
            event.listeners({
                'views.main.profile.clicked': onOpenedProfile
            });
        }

        /**
         * Initializes module.
         * @memberof SoundManager/views/details
         */
        function init() {
            soundTypesList = document.getElementById('soundTypes');
            pageHeader = document.querySelector('#details h2');
            resetButton = document.getElementById('reset');
            deleteButton = document.getElementById('delete');
            confirmDeleteButton = document.getElementById('confirmDelete');
            page = document.getElementById('details');
            deletePopup = document.getElementById('deleteProfilePopup');
            loadSoundTypes();
            bindEvents();
            initSliders();
        }

        return {
            init: init
        };
    }
});
