/*
 * Copyright (c) 2014 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, console, setTimeout, clearTimeout, require*/

/**
 * PhotoPage module.
 * @requires {@link core/event}
 * @requires {@link MiniGallery/models/content}
 * @requires {@link MiniGallery/views/ui}
 * @requires {@link MiniGallery/views/swipe}
 * @namespace MiniGallery/views/photoPage
 * @memberof MiniGallery/views
 * @author Dominik Koleda <d.koleda@samsung.com>
 * @author Piotr Dabrowski <p.dabrowski2@samsung.com>
 * @author Kamil Stepczuk <k.stepczuk@samsung.com>
 */
define({
    name: 'views/photoPage',
    requires: [
        'core/event',
        'models/content',
        'views/ui',
        'views/swipe'
    ],
    def: function photoPage(req) {
        'use strict';

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

            /**
             * Content module object.
             * @type {Module}
             */
            content = req.models.content,

            /**
             * Ui module object.
             * @type {Module}
             */
            ui = req.views.ui,

            /**
             * Galleries page module object.
             * @type {Module}
             */
            galleriesPage = null,

            /**
             * Path of the currently opened gallery.
             * @type {string}
             */
            currentGalleryPath = '',

            /**
             * Currently opened gallery object.
             * @type {object}
             */
            currentGallery = null,

            /**
             * Index of currently displayed Photo.
             * @type {number}
             */
            currentPhotoIndex = -1,

            /**
             * Currently displayed Photo object.
             * @type {object}
             */
            currentPhoto = null,

            /**
             * Addons controls hiding timeout.
             * @type {number}
             */
            addonsTimeout = 0,

            /**
             * Photo page element.
             * @type {HTMLElement}
             */
            page = null,

            /**
             * Photo element.
             * @type {HTMLElement}
             */
            photo = null,

            /**
             * Footer button.
             * @type {HTMLElement}
             */
            footer = null,

            /**
             * Header element.
             * @type {HTMLElement}
             */
            header = null,

            /**
             * Title element.
             * @type {HTMLElement}
             */
            title = null,

            /**
             * Remove popup.
             * @type {HTMLElement}
             */
            removePopup = null,

            /**
             * No button.
             * @type {HTMLElement}
             */
            noBtn = null,

            /**
             * Yes button.
             * @type {HTMLElement}
             */
            yesBtn = null;

        /**
         * Draws photo on page.
         * @memberof MiniGallery/views/photoPage
         * @param {string} galleryPath
         * @param {number} photoIndex
         * @return {boolean} true on success, false otherwise
         */
        function drawPhoto(galleryPath, photoIndex) {
            var galleries = [];

            currentGalleryPath = galleryPath;
            currentPhotoIndex = photoIndex;
            galleries = content.getGalleries();
            currentGallery = galleries[galleryPath];
            if (!currentGallery) {
                console.warn('Gallery "' + galleryPath + '" does not exist!');
                return false;
            }
            currentPhoto = currentGallery.images[currentPhotoIndex];
            if (!currentPhoto) {
                console.warn(
                    'Photo #' + currentPhotoIndex +
                        ' does not exist in gallery ' + galleryPath + '!'
                );
                return false;
            }
            photo.style.backgroundImage =
                'url("' + currentPhoto.contentURI + '")';
            title.innerText = currentGallery.name + ' (' +
                (currentPhotoIndex + 1) + '/' +
                currentGallery.images.length + ')';
            return true;
        }

        /**
         * Switches photo.
         * @param {number} direction
         */
        function switchPhoto(direction) {
            var lastPhotoIndex = currentGallery.images.length - 1,
                newPhotoIndex = currentPhotoIndex + direction;

            if (newPhotoIndex < 0) {
                newPhotoIndex = 0;
            }
            if (newPhotoIndex > lastPhotoIndex) {
                newPhotoIndex = lastPhotoIndex;
            }
            drawPhoto(currentGalleryPath, newPhotoIndex);
        }

        /**
         * Hides addons.
         */
        function hideAddons() {
            header.classList.add('hidden');
            footer.classList.add('hidden');
        }

        /**
         * Starts hiding addons.
         */
        function startHidingAddons() {
            if (addonsTimeout) {
                clearTimeout(addonsTimeout);
            }
            addonsTimeout = setTimeout(
                function timeoutHideAddons() {
                    addonsTimeout = null;
                    hideAddons();
                },
                2000
            );
        }

        /**
         * Shows single photo page.
         * @memberof MiniGallery/views/photoPage
         */
        function show() {
            tau.changePage(page);
            startHidingAddons();
        }

        /**
         * Shows addons.
         */
        function showAddons() {
            header.classList.remove('hidden');
            footer.classList.remove('hidden');
            startHidingAddons();
        }

        /**
         * Shows confirm popup.
         */
        function showConfirmPopup() {
            hideAddons();
            tau.openPopup(removePopup);
        }

        /**
         * Handles swipe left event.
         */
        function onSwipeLeft() {
            switchPhoto(1);
        }

        /**
         * Handles swipe right event.
         */
        function onSwipeRight() {
            switchPhoto(-1);
        }

        /**
         * Handles models.content.refreshed event.
         * @param {object} data
         */
        function onContentRefreshed(data) {
            if (currentGalleryPath !== '') {
                currentGallery = content.getGalleries()[currentGalleryPath];

                if (data.detail.reason === 'removed') {
                    if (currentGallery &&
                            currentGallery.images.length > 0) {
                        if (currentPhoto.id === data.detail.id) {
                            ui.showNotification(
                                'Photo has been deleted.',
                                function switchPhotoOnDelete() {
                                    switchPhoto(-1);
                                }
                            );
                        } else {
                            switchPhoto(0);
                        }
                    } else {
                        ui.showNotification(
                            'Photo has been deleted.',
                            function showGalleriesPageOnDelete() {
                                galleriesPage.show();
                            }
                        );
                    }
                } else {
                    switchPhoto(0);
                }
            }
        }

        /**
         * Handles models.content.delete.file.failed event.
         */
        function onDeleteFileFailed() {
            ui.showNotification('Photo has not been deleted.');
        }

        /**
         * Handles click event on No button.
         */
        function onNoBtnClick() {
            tau.closePopup();
        }

        /**
         * Handles click event on Yes button.
         */
        function onYesBtnClick() {
            tau.closePopup();
            content.deleteFile(currentPhoto.contentURI);
        }

        /**
         * Registers module event listeners.
         */
        function bindEvents() {
            photo.addEventListener('touchend', showAddons);
            footer.addEventListener('click', showConfirmPopup);
            photo.addEventListener('swipeleft', onSwipeLeft);
            photo.addEventListener('swiperight', onSwipeRight);
            noBtn.addEventListener('click', onNoBtnClick);
            yesBtn.addEventListener('click', onYesBtnClick);
        }

        /**
         * Initializes module.
         * @memberof MiniGallery/views/photoPage
         */
        function init() {
            galleriesPage = require('views/galleriesPage');
            page = document.getElementById('photo-page');
            header = document.getElementById('photo-header');
            title = document.getElementById('photo-title');
            footer = document.getElementById('photo-footer');
            photo = document.getElementById('photo');
            removePopup = document.getElementById('remove-popup');
            noBtn = document.getElementById('remove-no');
            yesBtn = document.getElementById('remove-yes');
            bindEvents();
        }

        e.listeners({
            'models.content.refreshed': onContentRefreshed,
            'models.content.delete.file.failed': onDeleteFileFailed
        });

        return {
            init: init,
            show: show,
            drawPhoto: drawPhoto
        };

    }
});
