(function ($) {

    "use strict";

    function widgetScrollNavigation( $scope ) {

        var $target     = $scope.find( '.jet-scroll-navigation' ),
        instance        = null,
        settings        = $target.data( 'settings' );

        instance = new jetScrollNavigation( $scope, $target, settings );
        instance.init();
    }

    /**
	 * Jet Scroll Navigation Class
	 *
	 * @return {void}
	 */

    class jetScrollNavigation {

        constructor( $scope, $selector, settings ) {
    
            var self        = this,
                $window     = $( window ),
                $document   = $( document ),
                $body       = $( 'body' ),
                $instance   = $selector,
                $htmlBody   = $( 'html, body' ),
                $itemsList  = $( '.jet-scroll-navigation__item', $instance ),
                sectionList = [],
                defaultSettings = {
                    speed: 500,
                    blockSpeed: 500,
                    offset: 0,
                    sectionSwitch: false,
                    sectionSwitchOnMobile: true
                },
                settings       = $.extend( {}, defaultSettings, settings ),
                sections       = {},
                currentSection = null,
                isScrolling    = false,
                isSwipe        = false,
                hash           = window.location.hash.slice( 1 ),
                timeout        = null,
                timeStamp      = 0,
                platform       = navigator.platform;
    
            jQuery.extend( jQuery.easing, {
                easeInOutCirc: function ( x, t, b, c, d ) {
                    if ( ( t /= d / 2 ) < 1 ) {
                        return -c / 2 * ( Math.sqrt( 1 - t * t ) - 1 ) + b;
                    }
    
                    return c / 2 * ( Math.sqrt( 1 - ( t -= 2 ) * t ) + 1 ) + b;
                }
            } );
    
            /**
             * Init
             */
            self.init = function () {
    
                self.setSectionsData();
    
                if ( hash && sections.hasOwnProperty( hash ) ) {
                    $itemsList.addClass( 'invert' );
                }
    
                $itemsList.on( 'click.jetScrollNavigation', function () {
                    var sectionId = $( this ).data( 'anchor' );
                    self.onAnchorChange( sectionId );
                } );
    
                $window.on(
                    'resize.jetScrollNavigation orientationchange.jetScrollNavigation',
                    JetElementsTools.debounce( 50, self.onResize )
                );
    
                $window.on( 'load', function () {
                    self.setSectionsData();
                } );
    
                $document.keydown( function ( event ) {
    
                    if ( ! self.isEnabled() ) {
                        return;
                    }
    
                    if ( 38 === event.keyCode ) {
                        self.directionSwitch( event, 'up' );
                    }
    
                    if ( 40 === event.keyCode ) {
                        self.directionSwitch( event, 'down' );
                    }
                } );
    
                self.waypointHandler();
                self.hijakingHandler();
    
                if ( 'undefined' !== typeof ResizeSensor ) {
                    new ResizeSensor(
                        $( '.jet-scroll-navigation-section' ),
                        JetElementsTools.debounce( 50, function () {
                            self.setSectionsData();
                            self.waypointHandler();
                        } )
                    );
                }
            };
    
            /**
             * Sections data
             */
            self.setSectionsData = function () {
    
                var editMode = Boolean( elementorFrontend.isEditMode() );
    
                $itemsList.each( function () {
    
                    var $item        = $( this ),
                        sectionId    = $item.data( 'anchor' ),
                        sectionInvert = 'yes' === $item.data( 'invert' ),
                        $section     = $( '#' + sectionId );
    
                    if ( $section[ 0 ] ) {
    
                        $section.addClass( 'jet-scroll-navigation-section' );
                        $section[ 0 ].dataset.sectionName = sectionId;
    
                        sections[ sectionId ] = {
                            selector: $section,
                            offset: Math.round( $section.offset().top ),
                            height: $section.outerHeight(),
                            invert: sectionInvert
                        };
    
                    } else if ( ! editMode ) {
                        $item.css( 'display', 'none' );
                    }
                } );
            };
    
            /**
             * Waypoints
             */
            self.waypointHandler = function () {
    
                $window.on( 'resize scroll', function () {
    
                    if ( settings.sectionSwitch ) {
                        return;
                    }
    
                    for ( var section in sections ) {
    
                        var $section  = sections[ section ].selector,
                            sectionId = $section.attr( 'id' );
    
                        if ( ! $( '#' + sectionId ).isInViewport() ) {
                            $( '[data-anchor=' + sectionId + ']', $instance ).removeClass( 'active' );
                        }
                    }
                } );
    
                for ( var section in sections ) {
    
                    let $section = sections[ section ].selector;
    
                    JetElements.observer(
                        $section,
                        function () {
                            self.activateSection( $( this ).attr( 'id' ) );
                        },
                        { offset: '70%', triggerOnce: false }
                    );
    
                    JetElements.observer(
                        $section,
                        function () {
                            self.activateSection( $( this ).attr( 'id' ) );
                        },
                        { offset: '0%', triggerOnce: false }
                    );
                }
            };
    
            /**
             * Activate section
             */
            self.activateSection = function ( sectionId ) {
    
                if ( isScrolling ) {
                    return;
                }
    
                if ( false === settings.sectionIdVisibility ) {
                    window.history.pushState( null, null, '#' + sectionId );
                }
    
                currentSection = sectionId;
    
                $itemsList.removeClass( 'active invert' );
                $( '[data-anchor=' + sectionId + ']', $instance ).addClass( 'active' );
    
                if ( sections[ sectionId ].invert ) {
                    $itemsList.addClass( 'invert' );
                }
            };
    
            /**
             * Anchor click
             */
            self.onAnchorChange = function ( sectionId ) {
    
                if ( ! sections.hasOwnProperty( sectionId ) ) {
                    return;
                }
    
                if ( settings.sectionSwitch && isScrolling ) {
                    return;
                }
    
                var offset = sections[ sectionId ].offset - settings.offset;
    
                if ( settings.sectionSwitch ) {
                    isScrolling = true;
                }
    
                self.activateSection( sectionId );
    
                window.scrollTo( {
                    top: offset,
                    behavior: 'smooth'
                } );
    
                if ( settings.sectionSwitch ) {
                    let checkScroll = setInterval( function () {
    
                        if ( Math.abs( window.scrollY - offset ) < 2 ) {
                            clearInterval( checkScroll );
                            isScrolling = false;
                        }
    
                    }, 100 );
                }
            };
    
            /**
             * Direction switch
             */
            self.directionSwitch = function ( event, direction ) {
    
                if ( isScrolling ) {
                    return;
                }
    
                var $current = $( '[data-anchor=' + currentSection + ']', $instance ),
                    $target  = direction === 'up'
                        ? $current.prev()
                        : $current.next();
    
                if ( $target[ 0 ] ) {
                    $target.trigger( 'click.jetScrollNavigation' );
                }
            };
    
            /**
             * Hijaking handler
             */
            self.hijakingHandler = function () {
    
                var isMobile   = JetElementsTools.mobileAndTabletcheck(),
                    touchStart = 0;
    
                if ( ! settings.sectionSwitch ) {
                    return;
                }
    
                if ( ! isMobile ) {
                    document.addEventListener( 'wheel', self.onWheel, { passive: false } );
                }
    
                if ( isMobile && settings.sectionSwitchOnMobile ) {
    
                    document.addEventListener( 'touchstart', function ( event ) {
                        touchStart = event.changedTouches[ 0 ].clientY;
                    }, { passive: true } );
    
                    document.addEventListener( 'touchend', function ( event ) {
    
                        var delta     = event.changedTouches[ 0 ].clientY - touchStart,
                            direction = delta > 0 ? 'up' : 'down';
    
                        if ( Math.abs( delta ) < settings.scroll_threshold ) {
                            return;
                        }
    
                        self.directionSwitch( event, direction );
    
                    }, { passive: true } );
                }
            };
    
            /**
             * Wheel handler
             */
            self.onWheel = function ( event ) {
    
                if ( ! self.isEnabled() || isScrolling ) {
                    event.preventDefault();
                    return;
                }
    
                var direction = event.deltaY < 0 ? 'up' : 'down';
                self.directionSwitch( event, direction );
            };
    
            /**
             * Resize
             */
            self.onResize = function () {
                self.setSectionsData();
            };
    
            /**
             * Enabled
             */
            self.isEnabled = function () {
                return $scope.is( ':visible' );
            };
    
            /**
             * Viewport helper
             */
            $.fn.isInViewport = function () {
    
                var elementTop    = $( this ).offset().top,
                    elementBottom = elementTop + $( this ).outerHeight(),
                    viewportTop   = $window.scrollTop(),
                    viewportBottom = viewportTop + $window.height();
    
                return elementBottom > viewportTop && elementTop < viewportBottom;
            };
        }
    }
    

    window.widgetScrollNavigation = widgetScrollNavigation;

})( jQuery );