(function () {
    'use strict';
    angular
        .module('pr.longpress', [])
        .directive('onLongPress', ['$parse', '$timeout', function ($parse, $timeout) {
            return {
                restrict: 'A',
                link: function ($scope, $elm, $attrs) {
                    var timer;
                    var timerDuration = (!isNaN($attrs.longPressDuration) && parseInt($attrs.longPressDuration)) || 600;
                    // By default we prevent long press when user scrolls
                    var preventLongPressOnScroll = ($attrs.preventOnscrolling ? $attrs.preventOnscrolling === 'true' : true)
                    // Variable used to prevent long press while scrolling
                    var touchStartY;
                    var touchStartX;
                    var MAX_DELTA = 15;
                    // Bind touch, mouse and click event
                    $elm.bind('touchstart', onEnter);
                    $elm.bind('touchend', onExit);

                    $elm.bind('mousedown', onEnter);
                    $elm.bind('mouseup', onExit);

                    $elm.bind('click', onClick);
                    // For windows mobile browser
                    $elm.bind('pointerdown', onEnter);
                    $elm.bind('pointerup', onExit);
                    if (preventLongPressOnScroll) {
                        // Bind touchmove so that we prevent long press when user is scrolling
                        $elm.bind('touchmove', onMove);
                    }

                    function onEnter(evt) {
                        var functionHandler = $parse($attrs.onLongPress);
                        // For tracking scrolling
                        if ((evt.originalEvent || evt).touches) {
                            touchStartY = (evt.originalEvent || evt).touches[0].screenY;
                            touchStartX = (evt.originalEvent || evt).touches[0].screenX;
                        }
                        //Cancel existing timer
                        $timeout.cancel(timer);
                        //To handle click event properly
                        $scope.longPressSent = false;
                        // We'll set a timeout for 600 ms for a long press
                        timer = $timeout(function () {
                            $scope.longPressSent = true;
                            // If the touchend event hasn't fired,
                            // apply the function given in on the element's on-long-press attribute
                            $scope.$apply(function () {
                                functionHandler($scope, {
                                    $event: evt
                                });
                            });
                        }, timerDuration);

                    }

                    function onExit(evt) {
                        var functionHandler = $parse($attrs.onTouchEnd);
                        // Prevent the onLongPress event from firing
                        $timeout.cancel(timer);
                        // If there is an on-touch-end function attached to this element, apply it
                        if ($attrs.onTouchEnd) {
                            $scope.$apply(function () {
                                //hideTooltipsOnMac();
                                functionHandler($scope, {
                                    $event: evt
                                });
                            });
                        }

                    }

                    function onClick(evt) {
                        //If long press is handled then prevent click
                        if ($scope.longPressSent && (!$attrs.preventClick || $attrs.preventClick === "true")) {
                            evt.preventDefault();
                            evt.stopPropagation();
                            evt.stopImmediatePropagation();
                        }

                    }

                    function onMove(evt) {
                        var yPosition = (evt.originalEvent || evt).touches[0].screenY;
                        var xPosition = (evt.originalEvent || evt).touches[0].screenX;

                        // If we scrolled, prevent long presses
                        if (touchStartY !== undefined && touchStartX !== undefined &&
                            (Math.abs(yPosition - touchStartY) > MAX_DELTA) || Math.abs(xPosition - touchStartX) > MAX_DELTA) {
                            $timeout.cancel(timer);
                        }

                    }
                }
            };
        }]);
})();