/*
 * 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 require, define, console, tizen*/

/**
 * Path module.
 *
 * @requires {@link core/event}
 * @requires {@link core/filesystem}
 * @namespace ArchiveManager/model/path
 * @memberof ArchiveManager/model
 */
define({
    name: 'model/path',
    requires: [
        'core/event',
        'core/filesystem'
    ],
    def: function modelPath(req) {
        'use strict';

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

            /**
             * Core filesystem module.
             * @type {Module}
             */
            coreFilesystem = req.core.filesystem,

            /**
             * Index of an empty archive.
             * @memberof ArchiveManager/model/path
             * @const {number}
             */
            EMPTY_ARCHIVE_INDEX = -1;

        /**
         * Fires the 'changed' event.
         * @param {Path} path
         * @return {string}
         */
        function fireChangedEvent(path) {
            var pathStr = path.toString();

            e.fire('changed', path);

            return pathStr;
        }

        /**
         * Path object constructor.
         * @memberof ArchiveManager/model/path
         * @class Path
         * @constructor
         */
        function Path() {
            this.path = [];
            this.archiveIndex = EMPTY_ARCHIVE_INDEX;
        }

        /**
         * Adds methods to prototype.
         * @memberof ArchiveManager/model/path
         */
        Path.prototype = {
            /**
             * Clears current path.
             * Returns current path.
             * @fires "changed"
             * @return {string}
             */
            goHome: function goHome() {
                this.archiveIndex = EMPTY_ARCHIVE_INDEX;
                this.path = [];
                return fireChangedEvent(this);
            },

            /**
             * Removes the last element from current path.
             * Returns current path.
             * @fires "changed"
             * @return {string}
             */
            goUp: function goUp() {
                this.path.pop();
                if (this.path.length < this.archiveIndex) {
                    this.archiveIndex = EMPTY_ARCHIVE_INDEX;
                }
                return fireChangedEvent(this);
            },

            /**
             * Adds new element to current path.
             * Returns current path.
             * @param {string} element
             * @fires "changed"
             * @return {string}
             */
            goDown: function goDown(element, isArchive) {
                this.path.push(element);
                if (isArchive) {
                    this.archiveIndex = this.path.length;
                }
                return fireChangedEvent(this);
            },

            /**
             * Removes the archive part from current path.
             * Returns current path.
             * @fires "changed"
             * @return {string}
             */
            goToArchiveDirectory: function goToArchiveDirectory() {
                if (this.archiveIndex === EMPTY_ARCHIVE_INDEX) {
                    return this.toString();
                }

                this.path.splice(this.archiveIndex - 1);
                this.archiveIndex = EMPTY_ARCHIVE_INDEX;
                return fireChangedEvent(this);
            },

            /**
             * Returns true in case of home path,
             * false otherwise.
             * @return {boolean}
             */
            isHome: function isHome() {
                if (this.archiveIndex === EMPTY_ARCHIVE_INDEX) {
                    return this.path.length === 0;
                }
                return this.path.length === this.archiveIndex;
            },

            /**
             * Returns current path.
             * @param {boolean} addPrefix When set to true,
             * preview path contains archive name prefix.
             * @return {string}
             */
            toString: function toString(addPrefix) {
                var shift = 0;

                if (addPrefix) {
                    shift = 1;
                }
                if (this.archiveIndex === EMPTY_ARCHIVE_INDEX) {
                    return this.path.join('/');
                }
                return this.path.slice(this.archiveIndex - shift).join('/');
            },

            /**
             * Returns archive path with archive name.
             * @return {string}
             */
            getFullArchivePath: function getFullArchivePath() {
                if (this.archiveIndex === EMPTY_ARCHIVE_INDEX) {
                    return '';
                }
                return this.path.slice(0, this.archiveIndex).join('/');
            },

            /**
             * Returns archive path without archive name.
             * @return {string}
             */
            getArchivePath: function getArchivePath() {
                if (this.archiveIndex === EMPTY_ARCHIVE_INDEX) {
                    return '';
                }
                return this.path.slice(0, this.archiveIndex - 1).join('/');
            },

            /**
             * Returns archive name with archive file extension.
             * @return {string}
             */
            getFullArchiveName: function getFullArchiveName() {
                if (this.archiveIndex === EMPTY_ARCHIVE_INDEX) {
                    return '';
                }
                return this.path[this.archiveIndex - 1];
            },

            /**
             * Returns archive name without archive file extension.
             * @return {string}
             */
            getArchiveName: function getArchiveName() {
                if (this.archiveIndex === EMPTY_ARCHIVE_INDEX) {
                    return '';
                }

                return coreFilesystem.getFileNameWithoutExtension(
                    this.path[this.archiveIndex - 1]
                );
            }
        };

        return {
            Path: Path,
            EMPTY_ARCHIVE_INDEX: EMPTY_ARCHIVE_INDEX
        };
    }
});
