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

/**
 * Module swipe view.
 * @namespace MiniGallery/views/swipe
 * @memberof MiniGallery/views
 * @author Kamil Stepczuk <k.stepczuk@samsung.com>
 */

define({
    name: 'views/swipe',
    requires: [],
    def: function swipe() {
        'use strict';

        /**
         * Position x of touch.
         * @type {number}
         */
        var touchedX = 0,

            /**
             * Position y of touch.
             * @type {number}
             */
            touchedY = 0,

            /**
             * Start position x of touch.
             * @type {number}
             */
            startTouchX = 0,

            /**
             * Start position y of touch.
             * @type {number}
             */
            startTouchY = 0,

            /**
             * Dimensional factor to find swipe.
             * @type {number}
             */
            swipeDetectionThreshold = window.innerHeight * 0.25;

        /**
         * Handles touch start event.
         * Sets start and touch positions.
         * @param {Event} event
         */
        function onTouchStart(event) {
            startTouchX = event.changedTouches[0].clientX;
            startTouchY = event.changedTouches[0].clientY;
            touchedX = event.changedTouches[0].clientX;
            touchedY = event.changedTouches[0].clientY;
        }

        /**
         * Handles touch move event.
         * Sets start and touch positions.
         * @param {Event} event
         */
        function onTouchMove(event) {
            touchedX = event.changedTouches[0].clientX;
            touchedY = event.changedTouches[0].clientY;
        }

        /**
        * Handles touch end event.
        * Finds swipe events and dispatch it on target element.
        * @param {Event} event
        */
        function onTouchEnd(event) {
            var deltaX = startTouchX - touchedX,
                deltaY = startTouchY - touchedY,
                target = event.target,
                customEvent = null,
                eventName = '';

            touchedX = 0;
            touchedY = 0;
            startTouchX = 0;
            startTouchY = 0;

            if ((Math.abs(deltaX) >= swipeDetectionThreshold &&
                    Math.abs(deltaY) >= swipeDetectionThreshold) ||
                    (Math.abs(deltaX) < swipeDetectionThreshold &&
                        Math.abs(deltaY) < swipeDetectionThreshold)) {
                return false;
            }

            event.stopPropagation();
            if (Math.abs(deltaX) >= swipeDetectionThreshold) {
                if (deltaX < 0) {
                    eventName = 'swiperight';
                } else {
                    eventName = 'swipeleft';
                }
            } else if (Math.abs(deltaY) >= swipeDetectionThreshold) {
                if (deltaY > 0) {
                    eventName = 'swipeup';
                } else {
                    eventName = 'swipedown';
                }
            }
            customEvent = new window.CustomEvent(eventName, {
                cancelable: true
            });
            return target.dispatchEvent(customEvent);
        }

        /**
         * Registers module event listeners.
         */
        function bindEvents() {
            window.addEventListener('touchstart', onTouchStart, true);
            window.addEventListener('touchmove', onTouchMove, true);
            window.addEventListener('touchend', onTouchEnd, true);
        }

        /**
         * Initializes module.
         * @memberof MiniGallery/views/swipe
         */
        function init() {
            bindEvents();
        }

        return {
            init: init
        };
    }
});
