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

/**
 * Main page module.
 * @requires {@link core/event}
 * @requires {@link ArchiveManager/model/filesystem}
 * @requires {@link ArchiveManager/model/archive}
 * @requires {@link ArchiveManager/views/pages/name}
 * @requires {@link ArchiveManager/views/popup}
 * @requires {@link ArchiveManager/views/filelist}
 * @requires {@link ArchiveManager/views/modes/archive}
 * @requires {@link ArchiveManager/views/modes/preview}
 * @requires {@link ArchiveManager/views/modes/standard}
 * @requires {@link ArchiveManager/helpers/page}
 * @requires {@link ArchiveManager/helpers/keyboard}
 * @requires {@link ArchiveManager/helpers/router}
 * @namespace ArchiveManager/views/pages/main
 * @memberof ArchiveManager/views/pages
 */
define({
    name: 'views/pages/main',
    requires: [
        'core/event',
        'model/filesystem',
        'model/archive',
        'views/pages/name',
        'views/popup',
        'views/filelist',
        'views/modes/archive',
        'views/modes/preview',
        'views/modes/standard',
        'helpers/page',
        'helpers/keyboard',
        'helpers/router'
    ],
    def: function viewsPagesMain(req) {
        'use strict';

        /**
         * Event module object.
         */
        var e = req.core.event,

            /**
             * Filesystem module object.
             */
            filesystem = req.model.filesystem,

            /**
             * Archive model module object.
             */
            archive = req.model.archive,

            /**
             * File list view module object.
             */
            fileList = req.views.filelist,

            /**
             * Archive view module object.
             */
            archiveMode = req.views.modes.archive,

            /**
             * Preview view module object.
             */
            previewMode = req.views.modes.preview,

            /**
             * Standard view module object.
             */
            standardMode = req.views.modes.standard,

            /**
             * Name view module object.
             */
            nameView = req.views.pages.name,

            /**
             * Popup view module object.
             */
            popupView = req.views.popup,


            /**
             * Router helper module object.
             */
            router = req.helpers.router,

            /**
             * Descriptor of archiving process.
             * @type {object}
             */
            archivingDescriptor = null,

            /**
             * Identifier of extraction task.
             * @type {number}
             */
            extractionTaskId = 0,

            /**
             * Zip archive already exists error message.
             * @type {string}
             */
            ZIP_ARCHIVE_ALREADY_EXISTS_ERROR = 'Zip archive already exists',

            /**
             * Page id.
             * @type {string}
             */
            PAGE_ID = '#main';

        /**
         * Shows main page.
         * @memberof ArchiveManager/views/pages/main
         */
        function open() {
            tau.changePage(PAGE_ID);
        }

        /**
         * Activates archive mode.
         * @param {boolean} animate When it is set to true,
         * content list is animated during mode changing, otherwise not.
         */
        function activateArchiveMode(animate) {
            archiveMode.activate(animate);
        }

        /**
         * Activates standard mode.
         * @param {boolean} animate When it is set to true,
         * content list is animated during mode changing, otherwise not.
         */
        function activateStandardMode(animate) {
            standardMode.activate(animate);
        }

        /**
         * Activates preview mode.
         * @param {object} data
         */
        function activatePreviewMode(data) {
            previewMode.activate(data);
        }

        /**
         * Calls model method which loads storages.
         */
        function getStorages() {
            filesystem.getStorages();
        }

        /**
         * Handles model.archive.completed event.
         */
        function onArchiveCompleted() {
            popupView.hide();
            if (fileList.getMode() === fileList.PREVIEW_MODE) {
                router.navigate('views/modes/standard/show');
                fileList.getPath().goToArchiveDirectory();
            } else {
                filesystem.getFiles(fileList.getPath().toString());
            }
        }

        /**
         * Handles model.archive.open.error event.
         * @param {Event} ev
         */
        function onArchiveOpenError(ev) {
            if (ev.detail.message === ZIP_ARCHIVE_ALREADY_EXISTS_ERROR) {
                console.error(ZIP_ARCHIVE_ALREADY_EXISTS_ERROR);
            }
        }

        /**
         * Handles model.archive.entries.loaded event.
         * @param {CustomEvent} ev
         */
        function onArchiveEntriesLoaded(ev) {
            router.navigate('views/modes/preview/show', ev.detail);
        }

        /**
         * Handles model.archive.progress event.
         * @param {CustomEvent} ev
         */
        function onArchiveProgress(ev) {
            popupView.setProgress(ev.detail);
        }

        /**
         * Handles model.archive.create.started event.
         */
        function onArchiveCreateStarted() {
            popupView.activateCreateProgress();
        }

        /**
         * Handles model.archive.extraxt.started event.
         * @param {object} ev Event object.
         */
        function onArchiveExtractStarted(ev) {
            extractionTaskId = ev.detail;
            popupView.showExtractProgress();
        }

        /**
         * Prepares list of URLs of files to be archived
         * and calls model method which counts number of data of given files.
         */
        function countNumberOfArchivedData() {
            var files = fileList.getSelectedFiles();

            filesystem.countNumberOfData(fileList.getPath().toString(), files);
        }

        /**
         * Prepares list of files to archive
         * and calls model method which creates archive.
         * @param {string} name Archive name.
         * @param {object} sizes Array indexed by file names,
         * containing information about the size of those files.
         */
        function createArchive(name, sizes) {
            var list = fileList.getSelectedFiles(sizes),
                archiveName = fileList.getPath().toString() +
                    '/' + name + '.zip';

            archivingDescriptor = archive.createArchive(list, archiveName);
        }

        /**
         * Handles 'views.popup.abort.button.click' event.
         */
        function onAbortBtnClicked() {
            popupView.showUnclosableMessage('Abort in progress...',
                'Abort');

            if (fileList.getMode() === fileList.PREVIEW_MODE) {
                archive.abortExtraction(extractionTaskId);
            } else {
                archive.abortArchiving(archivingDescriptor);
            }
        }

        /**
         * Handles 'model.archive.aborted' event.
         */
        function onArchiveAborted() {
            popupView.hide();
        }

        /**
         * Handles model.filesystem.foldersize.read event.
         * @param {CustomEvent} ev
         */
        function onFolderSizeRead(ev) {
            createArchive(
                nameView.getName(),
                ev.detail.sizes
            );
        }

        /**
         * Route handler showing archive mode.
         */
        function showArchiveMode() {
            activateArchiveMode(true);
        }

        /**
         * Starts archiving process.
         */
        function startArchiving() {
            popupView.showUnclosableMessage('Preparing...', 'Archive');
            countNumberOfArchivedData();
        }

        /**
         * Route handler showing standard mode.
         * @param {object} options
         */
        function showStandardMode(options) {
            if (options.start) {
                activateStandardMode(false);
                // immediately start archiving
                startArchiving();
            } else {
                // just show the standard mode
                activateStandardMode(true);
            }
        }

        /**
         * Route handles showing preview mode.
         * @param {object} data
         */
        function showPreviewMode(data) {
            activatePreviewMode(data);
        }

        /**
         * Displays the 'exit app' popup.
         * @memberof ArchiveManager/views/pages/main
         */
        function exit() {
            popupView.showExitConfirm();
        }

        /**
         * Registers routes.
         */
        function registerRoutes() {
            router.register('views/modes/standard/show', showStandardMode);
            router.register('views/modes/preview/show', showPreviewMode);
            router.register('views/modes/archive/show', showArchiveMode);
        }

        /**
         * Initializes module.
         * @memberof ArchiveManager/views/pages/main
         */
        function init() {
            registerRoutes();
            getStorages();
        }

        e.listeners({
            'model.archive.progress': onArchiveProgress,
            'model.archive.create.started': onArchiveCreateStarted,
            'model.archive.extract.started': onArchiveExtractStarted,
            'model.archive.completed': onArchiveCompleted,
            'model.archive.open.error': onArchiveOpenError,
            'model.archive.entries.loaded': onArchiveEntriesLoaded,
            'model.filesystem.foldersize.read': onFolderSizeRead,
            'views.popup.abort.button.click': onAbortBtnClicked,
            'model.archive.aborted': onArchiveAborted
        });

        return {
            init: init,
            open: open,
            exit: exit
        };
    }

});
