/*
 * 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, history*/
/**
 * Name page module.
 * @requires {@link core/event}
 * @requires {@link ArchiveManager/model/filesystem}
 * @requires {@link ArchiveManager/helpers/router}
 * @namespace ArchiveManager/views/pages/name
 * @memberof ArchiveManager/views/pages
 */
define({
    name: 'views/pages/name',
    requires: [
        'core/event',
        'model/filesystem',
        'helpers/router'
    ],
    def: function viewsPagesName(req) {
        'use strict';

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

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

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

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

            /**
             * Input text element to which the user can enter archive name.
             * @type {HTMLElement}
             */
            nameText = null,

            /**
             * Element which displays error message.
             * @type {string}
             */
            nameErrorMessage = null,

            /**
             * Page id.
             * @type {string}
             */
            PAGE_ID = '#name',

            /**
             * The name of the archive,
             * which has been recently typed into the nameText element.
             * @type {string}
             */
            name = '',

            /**
             * Flag indicating if enter key have been pressed.
             * @type {boolean}
             */
            enterPressed = false,

            /**
             * Flag indicating if entered name is correct.
             * @type {boolean}
             */
            validated = false,

            /**
             * String representing current path.
             * @type {string}
             */
            currentPath = '',

            /**
             * Invalid characters message.
             * @type {string}
             */
            INVALID_CHARACTERS_MSG = 'Name contains invalid characters.',

            /**
             * Zip name already exists message.
             * @type {string}
             */
            ZIP_NAME_ALREADY_EXISTS_MSG =
                'Zip archive with given name already exists.',

            /**
             * Regular expression recognizing incorrect archive name.
             */
            INCORRECT_ARCHIVE_NAME_REGEXP = new RegExp('[^\\w-]');

        /**
         * Shows name page.
         * @memberof ArchiveManager/views/pages/name
         * @param {string} path
         */
        function open(path) {
            currentPath = path;
            tau.changePage(PAGE_ID);
        }

        /**
         * Returns text that was written into nameText element.
         * @memberof ArchiveManager/views/pages/name
         * @return {string}
         */
        function getName() {
            return name;
        }

        /**
         * Checks if there is a file with given name on current path.
         * @param {string} name
         */
        function validateDuplicates(name) {
            filesystem.checkDuplicates(currentPath, name + '.zip');
        }

        /**
         * Checks if typed archive name contains correct characters.
         * @param {string} name
         * @return {boolean}
         */
        function validateName(name) {
            return !INCORRECT_ARCHIVE_NAME_REGEXP.test(name);
        }

        /**
         * Handles pageshow event on page element.
         */
        function onPageShow() {
            nameText.classList.remove('hidden');
            nameText.focus();
        }

        /**
         * Handles pagehide event on page element.
         */
        function onPageHide() {
            nameText.value = '';
            nameErrorMessage.innerText = '';
        }

        /**
         * Handles blur event on nameText element.
         */
        function onNameTextBlur() {
            nameText.focus();
        }

        /**
         * Handles keydown event on nameText element.
         * @param {event} ev
         */
        function onNameTextKeyDown(ev) {
            var trimmedName = nameText.value.trim();

            if (ev.keyCode === 13) {
                if (validated) {
                    nameText.value = trimmedName;
                    if (nameText.value !== '') {
                        enterPressed = true;
                        name = nameText.value;
                        nameText.classList.add('invisible');
                        nameText.classList.add('hidden');
                        nameText.blur();
                        history.back();
                    }
                }
            } else {
                validated = validateName(trimmedName);
                if (validated) {
                    validateDuplicates(trimmedName);
                } else {
                    nameErrorMessage.innerText = INVALID_CHARACTERS_MSG;
                }
            }
        }

        /**
         * Handles helpers.keyboard.opened event.
         */
        function onKeyboardOpened() {
            nameText.classList.remove('invisible');
        }

        /**
         * Handles helpers.keyboard.closed event.
         */
        function onKeyboardClosed() {
            if (enterPressed) {
                enterPressed = false;
                router.navigate('views/modes/standard/show', {start: true});
            }
        }

        /**
         * Handles model.filesystem.duplicate.detected event.
         */
        function onDuplicateDetected() {
            nameErrorMessage.innerText = ZIP_NAME_ALREADY_EXISTS_MSG;
            validated = false;
        }

        /**
         * Handles model.filesystem.duplicate.not.detected event.
         */
        function onDuplicateNotDetected() {
            nameErrorMessage.innerText = '';
            validated = true;
        }

        /**
         * Registers event listeners.
         */
        function bindEvents() {
            page.addEventListener('pageshow', onPageShow);
            page.addEventListener('pagehide', onPageHide);
            nameText.addEventListener('blur', onNameTextBlur);
            nameText.addEventListener('keyup', onNameTextKeyDown);
        }

        /**
         * Initializes module.
         * @memberof ArchiveManager/views/pages/name
         */
        function init() {
            page = document.getElementById('name');
            nameText = document.getElementById('name-text');
            nameErrorMessage = document.getElementById('name-error-message');
            router.register('views/pages/name/show', open);
            bindEvents();
        }

        e.listeners({
            'helpers.keyboard.opened': onKeyboardOpened,
            'helpers.keyboard.closed': onKeyboardClosed,
            'model.filesystem.duplicate.detected': onDuplicateDetected,
            'model.filesystem.duplicate.not.detected': onDuplicateNotDetected
        });

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

});
