/*
 * Copyright (c) 2012 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 $, console, define, document, window */

/**
 * Main view module
 */

define({
    name: 'views/main',
    requires: [
        'core/application',
        'models/ball',
        'views/space',
        'views/gravity',
        'views/sky'
    ],
    def: function appInit(req) {
        'use strict';

        var view = null,

            /**
             * Ball model object.
             * @type {Object}
             */
            ball = req.models.ball,

            /**
             * Space view object.
             * @type {Object}
             */
            space = req.views.space,

            /**
             * Gravity view object.
             * @type {Object}
             */
            gravity = req.views.gravity,

            /**
             * Sky view object.
             * @type {Object}
             */
            sky = req.views.sky,

            /**
             * Core application module object.
             * @type {Object}
             */
            app = req.core.application,

            /**
             * Gravity button id.
             * @type {string}
             */
            GRAVITY_BUTTON_ID = 'btn-gravity',

            /**
             * Sky button id.
             * @type {string}
             */
            SKY_BUTTON_ID = 'btn-sky',

            /**
             * Space button id.
             * @type {string}
             */
            SPACE_BUTTON_ID = 'btn-space',

            /**
             * Last deactiveted button Id
             * @type {string}
             */
            lastInactiveButtonId = null;

        /**
         * Deactivates button with given id.
         * @param {string} buttonId
         */
        function setInactiveButton(buttonId) {
            $('#' + lastInactiveButtonId).button('enable');
            $('#' + buttonId).button('disable');
            lastInactiveButtonId = buttonId;
        }

        /**
         * Cleanups view elements.
         */
        function cleanup() {
            if (view !== null) {
                view.cleanup();
            }
        }

        /**
         * Starts gravity view.
         */
        function startGravity() {
            setInactiveButton(GRAVITY_BUTTON_ID);
            cleanup();
            view = gravity;
            view.start();
        }

        /**
         * Starts sky view.
         */
        function startSky() {
            setInactiveButton(SKY_BUTTON_ID);
            cleanup();
            view = sky;
            view.start();
        }

        /**
         * Starts space view.
         */
        function startSpace() {
            setInactiveButton(SPACE_BUTTON_ID);
            cleanup();
            view = space;
            view.start();
        }

        /**
         * Handles animation frame request.
         */
        function onRequestAnimationFrame() {
            view.drawFrame();
            window.webkitRequestAnimationFrame(onRequestAnimationFrame);
        }

        /**
         * Runs view animation.
         */
        function animate() {
            window.webkitRequestAnimationFrame(onRequestAnimationFrame);
        }

        /**
         * Starts application.
         */
        function start() {
            startGravity();
            animate();
        }

        /**
         * Exits application.
         */
        function exit() {
            try {
                app.exit();
            } catch (err) {
                console.error('Error: ', err);
            }
        }

        /**
         * Handles hardware key tap event.
         * @param {Event} event
         */
        function onHardwareKeysTap(event) {
            if (event.keyName === 'back') {
                exit();
            }
        }

        /**
         * Handles device motion event.
         * @param {DeviceMotionEvent} event
         */
        function onDeviceMotion(event) {
            ball.setMotionData(event);
        }

        /**
         * Handles webkit visibility change event.
         */
        function onVisibilityChange() {
            if (document.webkitVisibilityState === 'visible') {
                animate();
            }
        }

        /**
         * Binds events.
         */
        function bindEvents() {
            window.addEventListener('tizenhwkey', onHardwareKeysTap);
            window.addEventListener('devicemotion', onDeviceMotion);
            document.addEventListener(
                'webkitvisbilitychange',
                onVisibilityChange
            );

            $('#' + GRAVITY_BUTTON_ID).on('tap', function onBallTap() {
                startGravity();
            });

            $('#' + SKY_BUTTON_ID).on('tap', function onSkyTap() {
                startSky();
            });

            $('#' + SPACE_BUTTON_ID).on('tap', function onSpaceTap() {
                startSpace();
            });

        }

        /**
         * Initializes view.
         */
        function init() {
            bindEvents();
            start();
        }

        return {
            init: init,
            start: start
        };
    }
});
