/*
 *      Copyright (c) 2015 Samsung Electronics Co., Ltd
 *
 *      Licensed under the Flora License, Version 1.1 (the "License");
 *      you may not use this file except in compliance with the License.
 *      You may obtain a copy of the License at
 *
 *              http://floralicense.org/license/
 *
 *      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*/

/**
 * Long press helper module.
 *
 * @module helpers/longPress
 * @namespace helpers/longPress
 */

define({
    name: 'helpers/longPress',
    requires: [],
    def: function helpersLongPress() {
        'use strict';

        /**
         * Long press wait time.
         *
         * @memberof helpers/longPress
         * @private
         * @const {number}
         */
        var LONG_PRESS_TIME = 1000,

            /**
             * List of long press timeout id's.
             *
             * @memberof helpers/longPress
             * @private
             * @type {object}
             */
            timeouts = {};

        /**
         * Start press event handler.
         *
         * @memberof helpers/longPress
         * @private
         * @param {HTMLElement} element Target element.
         * @param {function} longPressCallback Long press event handler.
         * @param {Event} event Start press event.
         * @returns {boolean|undefined}
         */
        function startPress(element, longPressCallback, event) {
            var id = element.id || element.src;

            if (event.type === 'click' && event.button !== 0) {
                return;
            }

            if (!timeouts[id]) {
                timeouts[id] = window.setTimeout(
                    function onTimeout() {
                        longPressCallback(event);
                    },
                    LONG_PRESS_TIME
                );
            }

            return false;
        }

        /**
         * End press event handler.
         *
         * @memberof helpers/longPress
         * @private
         * @param {HTMLElement} element Target element.
         */
        function endPress(element) {
            var id = element.id || element.src,
                timeoutId = timeouts[id];

            if (timeoutId) {
                window.clearTimeout(timeoutId);
                timeouts[id] = null;
            }
        }

        /**
         * Adds handler to given element.
         *
         * @memberof helpers/longPress
         * @public
         * @param {HTMLElement} element Target element.
         * @param {function} longPressCallback Long press event handler.
         */
        function addHandler(element, longPressCallback) {
            element.addEventListener(
                'mousedown',
                startPress.bind(null, element, longPressCallback)
            );
            element.addEventListener(
                'touchstart',
                startPress.bind(null, element, longPressCallback)
            );
            element.addEventListener(
                'mouseup',
                endPress.bind(null, element)
            );
            element.addEventListener(
                'mouseout',
                endPress.bind(null, element)
            );
            element.addEventListener(
                'touchend',
                endPress.bind(null, element)
            );
            element.addEventListener(
                'touchleave',
                endPress.bind(null, element)
            );
            element.addEventListener(
                'touchcancel',
                endPress.bind(null, element)
            );
        }

        /**
         * Removes handler from element.
         *
         * @memberof helpers/longPress
         * @public
         * @param {HTMLElement} element Target element.
         */
        function removeHandler(element) {
            element.removeEventListener('mousedown', startPress);
            element.removeEventListener('touchstart', startPress);
            element.removeEventListener('mouseout', endPress);
            element.removeEventListener('touchend', endPress);
            element.removeEventListener('touchleave', endPress);
            element.removeEventListener('touchcancel', endPress);
        }

        return {
            addHandler: addHandler,
            removeHandler: removeHandler
        };
    }
});
