/*
 *      Copyright (c) 2015 Samsung Electronics Co., Ltd
 *
 *      Licensed under the Flora License, Version 1.1 (the "License");
 *      you may not use this file except in compliance with the License.
 *      You may obtain a copy of the License at
 *
 *              http://floralicense.org/license/
 *
 *      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, window, tau*/

/**
 * Select view helper module.
 *
 * @module helpers/select
 * @requires {@link helpers/line}
 * @namespace helpers/select
 */

define({
    name: 'helpers/select',
    requires: [
        'helpers/line'
    ],
    def: function helpersSelect(line) {
        'use strict';

        /**
         * Class dictionary.
         *
         * @memberof helpers/select
         * @private
         * @const {Object}
         */
        var CLASSES = Object.freeze({
                SELECT_OVERLAY: 'select-overlay',
                VISIBLE: 'visible',
                OPEN: 'open',
                POPUP: 'popup',
                BTN_ALL: 'main-select-popup-all',
                BTN_NONE: 'main-select-popup-none',
                SELECTED: 'selected',
                SELECTOR_INDICATOR: 'ui-selector-indicator',
                PICTURE: 'picture',
                HIDDEN: 'hidden',
                DELETE_ICON: 'delete-icon',
                SEND_ICON: 'send-icon'
            }),

            /**
             * Id dictionary.
             *
             * @memberof helpers/select
             * @private
             * @const {Object}
             */
            ID = Object.freeze({
                PAGE: 'main',
                SEND_PAGE: 'send-page',
                SELECT_OVERLAY: 'main-select',
                FOOTER_BUTTON: 'main-footer-button',
                SELECT_BUTTON: 'main-select-button',
                SELECT_BUTTON_TEXT: 'main-select-button-text',
                SELECT_POPUP_ALL: 'main-select-popup-single-all',
                SELECT_POPUP_NONE: 'main-select-popup-single-none',
                SELECT_POPUP_BOTH: 'main-select-popup',
                SELECTOR_BUTTON: 'main-selector-button',
                SELECTOR_POPUP: 'main-selector-popup',
                SELECTOR: 'main-selector',
                DELETE_POPUP: 'main-delete-popup',
                DELETE_POPUP_TEXT: 'main-delete-popup-text',
                DELETE_POPUP_OK: 'main-delete-popup-ok',
                DELETE_POPUP_CANCEL: 'main-delete-popup-cancel'
            }),

            /**
             * Delete popup text.
             *
             * @memberof helpers/select
             * @private
             * @const {string}
             */
            DELETE_POPUP_TEXT = ' images will be deleted',

            /**
             * Page element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            page = null,

            /**
             * Select overlay element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selectOverlay = null,

            /**
             * Footer button element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            footerButton = null,

            /**
             * Select button element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selectButton = null,

            /**
             * Select button text element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selectButtonText = null,

            /**
             * Select popup all element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selectPopupAll = null,

            /**
             * Select popup none element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selectPopupNone = null,

            /**
             * Select popup both element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selectPopupBoth = null,

            /**
             * Selector button element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selectorButton = null,

            /**
             * Selector popup element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selectorPopup = null,

            /**
             * Selector element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            selector = null,

            /**
             * Delete popup element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            deletePopup = null,

            /**
             * Delete popup text element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            deletePopupText = null,

            /**
             * Delete popup cancel button element.
             *
             * @memberof helpers/select
             * @private
             * @type {HTMLElement}
             */
            deletePopupCancel = null,

            /**
             * Selector widget.
             *
             * @memberof helpers/select
             * @private
             * @type {Object}
             */
            selectorWidget = null,

            /**
             * Selected items count.
             *
             * @memberof helpers/select
             * @private
             * @type {number}
             */
            selectedCount = 0,

            /**
             * Defines, if delete popup was opened after 'main-selector-popup'
             * element.
             *
             * @memberof helpers/select
             * @private
             * @type {Boolean}
             */
            selectorPopupDelete = false;

        /**
         * Updates select counter in button.
         *
         * @memberof helpers/select
         * @private
         */
        function updateSelectCounter() {
            selectButtonText.innerHTML =
                selectedCount < 10 ? '0' + selectedCount : selectedCount;

            footerButton.disabled = !selectedCount;

            if (!selectedCount) {
                selectorButton.classList.add(CLASSES.HIDDEN);
            } else {
                selectorButton.classList.remove(CLASSES.HIDDEN);
            }
        }

        /**
         * Click event handler.
         * Selects clicked element.
         *
         * @memberof helpers/select
         * @public
         * @param {Event} event Click event.
         * @returns {number|null} Display mode change.
         */
        function clickHandler(event) {
            var target = event.target;

            if (target.classList.contains(CLASSES.SELECTED)) {
                target.classList.remove(CLASSES.SELECTED);
                selectedCount -= 1;
                updateSelectCounter();
            } else {
                target.classList.add(CLASSES.SELECTED);
                selectedCount += 1;
                updateSelectCounter();
            }
            return null;
        }

        /**
         * Shows select overlay.
         *
         * @memberof helpers/select
         * @public
         */
        function showOverlay() {
            page.classList.add(CLASSES.SELECT_OVERLAY);
        }

        /**
         * Deselects all elements.
         *
         * @memberof helpers/select
         * @private
         */
        function deselectAll() {
            var pictures = page.querySelectorAll('.' + CLASSES.PICTURE),
                len = pictures.length,
                i = 0,
                picture = null;

            for (i = 0; i < len; i += 1) {
                picture = pictures[i];
                if (picture.classList.contains(CLASSES.SELECTED)) {
                    picture.classList.remove(CLASSES.SELECTED);
                    selectedCount -= 1;
                    updateSelectCounter();
                }
            }
        }

        /**
         * Closes select popup.
         *
         * @memberof helpers/select
         * @private
         */
        function closeSelectPopup() {
            selectOverlay.classList.remove(CLASSES.POPUP);
            selectPopupAll.classList.remove(CLASSES.OPEN);
            selectPopupNone.classList.remove(CLASSES.OPEN);
            selectPopupBoth.classList.remove(CLASSES.OPEN);
        }

        /**
         * Hides select overlay.
         *
         * @memberof helpers/select
         * @public
         */
        function hideOverlay() {
            page.classList.remove(CLASSES.SELECT_OVERLAY);
            deselectAll();
            closeSelectPopup();
        }

        /**
         * Opens select popup.
         *
         * @memberof helpers/select
         * @private
         * @param {Event} event
         */
        function openSelectPopup(event) {
            var popup = null;

            selectOverlay.classList.add(CLASSES.POPUP);
            if (selectedCount === 14) {
                popup = selectPopupNone;
            } else if (selectedCount) {
                popup = selectPopupBoth;
            } else {
                popup = selectPopupAll;
            }

            popup.classList.add(CLASSES.OPEN);
            event.stopPropagation();
            event.preventDefault();
        }

        /**
         * Opens delete popup.
         *
         * @memberof helpers/select
         * @private
         */
        function openDeletePopup() {
            deletePopupText.innerText = selectedCount + DELETE_POPUP_TEXT;
            tau.openPopup(deletePopup);
        }

        /**
         * Selects all elements.
         *
         * @memberof helpers/select
         * @private
         */
        function selectAll() {
            var pictures = page.querySelectorAll('.' + CLASSES.PICTURE),
                len = pictures.length,
                i = 0,
                picture = null;

            for (i = 0; i < len; i += 1) {
                picture = pictures[i];
                if (!picture.classList.contains(CLASSES.SELECTED)) {
                    picture.classList.add(CLASSES.SELECTED);
                    selectedCount += 1;
                    updateSelectCounter();
                }
            }
        }

        /**
         * Initializes selector widget.
         *
         * @memberof helpers/select
         * @private
         */
        function initSelector() {
            var radius = window.innerHeight / 2 * 0.8;

            selectorWidget = tau.widget.Selector(selector, {
                itemRadius: radius
            });
        }

        /**
         * Destroys selector widget.
         *
         * @memberof helpers/select
         * @private
         */
        function destroySelector() {
            selectorWidget.destroy();
        }

        /**
         * Handles click event on selector widget.
         *
         * @memberof helpers/select
         * @private
         * @param {Event} event
         */
        function onSelectorClick(event) {
            var target = event.target;

            // 'ui-selector-indicator' is default indicator class name
            // of Selector component
            if (target.classList.contains(CLASSES.SELECTOR_INDICATOR)) {
                if (target.dataset.index === '0') {
                    selectorPopupDelete = true;
                    openDeletePopup();
                } else if (target.dataset.index === '1') {
                    tau.changePage('#' + ID.SEND_PAGE);
                }
            }

            if (target.classList.contains(CLASSES.DELETE_ICON)) {
                selectorPopupDelete = true;
                openDeletePopup();
            }

            if (target.classList.contains(CLASSES.SEND_ICON)) {
                tau.changePage('#' + ID.SEND_PAGE);
            }
        }

        /**
         * Handles page hide event.
         *
         * @memberof helpers/select
         * @private
         */
        function onPageHide() {
            destroySelector();
        }

        /**
         * Handles footer button click event.
         *
         * @memberof helpers/select
         * @private
         */
        function onFooterButtonClick() {
            if (selectedCount > 0) {
                openDeletePopup();
            }
        }

        /**
         * Handles delete popup hide event.
         *
         * @memberof helpers/select
         * @private
         */
        function onDeletePopupHide() {
            selectorPopupDelete = false;
        }

        /**
         * Handles delete popup cancel button click event.
         *
         * @memberof helpers/select
         * @private
         */
        function onDeletePopupCancelClick() {
            if (selectorPopupDelete) {
                tau.openPopup(selectorPopup);
            }
        }

        /**
         * Registers event handlers.
         *
         * @memberof helpers/select
         * @private
         */
        function bindEvents() {
            var allButtons = document.getElementsByClassName(CLASSES.BTN_ALL),
                noneButtons = document.getElementsByClassName(CLASSES.BTN_NONE),
                i = 0;

            for (i = 0; i < allButtons.length; i += 1) {
                allButtons[i].addEventListener('click', selectAll);
            }
            for (i = 0; i < noneButtons.length; i += 1) {
                noneButtons[i].addEventListener('click', deselectAll);
            }

            page.addEventListener('pagebeforeshow', initSelector);
            page.addEventListener('pagebeforehide', onPageHide);

            selectOverlay.addEventListener('click', closeSelectPopup);
            selectButton.addEventListener('click', openSelectPopup);
            selector.addEventListener('click', onSelectorClick);

            footerButton.addEventListener('click', onFooterButtonClick);

            deletePopup.addEventListener('popuphide', onDeletePopupHide);
            deletePopupCancel
                .addEventListener('click', onDeletePopupCancelClick);
        }

        /**
         * Initializes the module.
         *
         * @memberof helpers/select
         * @public
         */
        function init() {
            page = document.getElementById(ID.PAGE);
            selectOverlay = document.getElementById(ID.SELECT_OVERLAY);
            footerButton = document.getElementById(ID.FOOTER_BUTTON);
            selectButton = document.getElementById(ID.SELECT_BUTTON);
            selectButtonText = document.getElementById(ID.SELECT_BUTTON_TEXT);
            selectPopupAll = document.getElementById(ID.SELECT_POPUP_ALL);
            selectPopupNone = document.getElementById(ID.SELECT_POPUP_NONE);
            selectPopupBoth = document.getElementById(ID.SELECT_POPUP_BOTH);
            selectorButton = document.getElementById(ID.SELECTOR_BUTTON);
            selectorPopup = document.getElementById(ID.SELECTOR_POPUP);
            selector = document.getElementById(ID.SELECTOR);
            deletePopup = document.getElementById(ID.DELETE_POPUP);
            deletePopupText = document.getElementById(ID.DELETE_POPUP_TEXT);
            deletePopupCancel = document.getElementById(ID.DELETE_POPUP_CANCEL);

            initSelector();
            bindEvents();
        }

        return {
            init: init,
            showOverlay: showOverlay,
            hideOverlay: hideOverlay,
            getContainerWidth: line.getContainerWidth,
            getElementWidth: line.getElementWidth,
            getElementPosition: line.getElementPosition,
            getElementScroll: line.getElementScroll,
            getNextScroll: line.getNextScroll,
            clickHandler: clickHandler,
            longPressHandler: line.longPressHandler,
            doubleClickHandler: line.doubleClickHandler
        };
    }
});
