/*
 * 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*/

/**
 * Router module.
 *
 * Provides simple routing between views.
 * @requires {@link core/window}
 * @namespace ArchiveManager/helpers/router
 * @memberof ArchiveManager/helpers
 */

define({
    name: 'helpers/router',
    requires: [
        'core/window'
    ],
    def: function helpersRouter(window) {
        'use strict';

        var
            /**
             * Array of route objects.
             * @type {array}
             */
            routes = [],

            /**
             * Current route.
             * @type {array}
             */
            currentRoute = {},

            /**
             * Error object.
             * @type {Error}
             */
            Error = window.Error;


        /**
         * Creates objects representing routes.
         * @param {function} load Route load function.
         * @param {function} unload Router unload function.
         * @memberof ArchiveManager/helpers/router
         * @constructor
         */
        function Route(load, unload) {
            this.load = load;
            this.unload = unload;
        }

        /**
         * Register a route.
         *
         * @param {string} path
         * @param {function} load Loads the route.
         * @param {function} unload Unloads the route.
         * @memberof ArchiveManager/helpers/router
         */
        function register(path, load, unload) {
            if (routes[path]) {
                throw new Error('Route ' + path + ' is already registered');
            }
            routes[path] = new Route(load, unload);
        }

        /**
         * Navigate to path.
         *
         * Loads the path, unloading the previous one first.
         * @param {string} path
         * @param {object} options
         * @return {*}
         * @memberof ArchiveManager/helpers/router
         */
        function navigate(path, options) {
            var route = routes[path];

            if (typeof route !== 'object' || typeof route.load !== 'function') {
                throw new Error('Route ' + path + ' does not exist');
            }

            if (typeof currentRoute.unload === 'function') {
                currentRoute.unload();
            }

            currentRoute = route;

            return route.load(options || {});
        }

        return {
            register: register,
            navigate: navigate
        };
    }
});
