import Plyr from 'plyr';
import CircleType from 'circletype';

// ----------------------------------------------------------------------------
// DATA
// ----------------------------------------------------------------------------

const root = document.documentElement;

// HOME NAVIGATION DISPLAY //

const navEl = document.querySelector('.home__nav');
const navLinks = document.querySelectorAll('.home__nav-link');
const navImage = document.querySelector('.home__nav-image');
const circleTypes = [];

// VIDEO PLAYERS //

const galleryVideos = document.querySelectorAll('.gallery__video');
let videoPlayers = [];

// HEADER BAR ANIMATION //

const headerBar = document.querySelector('.header-bar');
const headerLogo = document.querySelector('.header-bar__logo');
let scrollOffset = 0;

// NAVIGATION MENU ANIMATION //

const headerNavBtn = document.querySelector('.header-bar__nav-button');
const headerNavMenu = document.querySelector('.header-bar__nav-menu');
const headerNavMenuListEls = document.querySelectorAll('.header-bar__nav-menu li');
const headerNavOverlay = document.querySelector('.header-bar__nav-overlay');
const touchPosition = {
    initialX: null,
    initialY: null
};

// ----------------------------------------------------------------------------
// UTILS
// ----------------------------------------------------------------------------

// Convert rem to pixels by getting font-size CSS property
function convertRemToPixels(rem) {
    let fontSize = parseFloat(window.getComputedStyle(document.body).getPropertyValue('font-size'));
    return rem * fontSize;
}

// ----------------------------------------------------------------------------
// LOGIC
// ----------------------------------------------------------------------------

// HOME NAVIGATION DISPLAY //

// Calculate navigation grid inner width
function calculateNavGridInnerWidth() {
    if (root && navImage) {
        let navGridGapProperty = window.getComputedStyle(root).getPropertyValue('--home-nav-gap');
        let navGridGap = parseFloat(navGridGapProperty.slice(0, -3));
        return navImage.getBoundingClientRect().width + (convertRemToPixels(navGridGap) * 2);
    }
}

// Calculate navigation grid inner diagonal
function calculateNavGridInnerDiagonal() {
    return calculateNavGridInnerWidth() * Math.sqrt(2);
}

// Create new instance of CircleType for each navigation link, set radius and direction
function curveNavLinks() {
    if (navLinks.length !== 0 && circleTypes) {
        for (let i = 0; i < (navLinks.length - 2); i++) {
            circleTypes[i] = new CircleType(navLinks[i]);
            circleTypes[i].radius(calculateNavGridInnerWidth() / 2);
        }
        for (let i = (navLinks.length - 2); i < navLinks.length; i++) {
            circleTypes[i] = new CircleType(navLinks[i]);
            circleTypes[i].dir(-1);
            circleTypes[i].radius(calculateNavGridInnerWidth() / 2);
        }
    }
}

// Set --home-nav-item-translation CSS property
function setNavItemTranslationProperty() {
    let navItemTranslation = (calculateNavGridInnerDiagonal() - calculateNavGridInnerWidth()) / 2;
    if (root) {
        root.style.setProperty('--home-nav-item-translation', navItemTranslation + 'px');
    }
}

// Set navigation grid display depending on number of links
function setNavGridDisplay() {
    if (navEl && navLinks.length !== 0) {
        if (navLinks.length === 2) {
            navEl.classList.add('home__nav--2-items');
        } else if (navLinks.length === 3) {
            navEl.classList.add('home__nav--3-items');
        } else if (navLinks.length === 4) {
            navEl.classList.add('home__nav--4-items');
        }
        for (let i = 0; i < navLinks.length; i++) {
            navLinks[i].classList.add('home__nav-link--visible');
        }
    }
}

// Edit navigation links radius and translation on window resize event
function editNavLinksOnResize() {
    window.addEventListener('resize', function(e) {
        if (navLinks.length !== 0 && circleTypes) {
            for (let i = 0; i < navLinks.length; i++) {
                circleTypes[i].radius(calculateNavGridInnerWidth() / 2);
            }
        }
        setNavItemTranslationProperty();
    });
}

// Add wave up animation to a single letter and remove it on animationend event
function waveNavLetterUp(navLetter) {
    navLetter.classList.add('home__nav-letter--wave-up');
    navLetter.addEventListener('animationend', function(e) {
        navLetter.classList.remove('home__nav-letter--wave-up');
    });
}

// Add wave down animation to a single letter and remove it on animationend event
function waveNavLetterDown(navLetter) {
    navLetter.classList.add('home__nav-letter--wave-down');
    navLetter.addEventListener('animationend', function(e) {
        navLetter.classList.remove('home__nav-letter--wave-down');
    });
}

// Add wave up animation to every letters of a single link with a slight delay
function waveNavLinkUp(navLink) {
    let navLinkLetters = navLink.querySelectorAll('span');
    let animationDelay = 0;
    for (let i = 0; i < navLinkLetters.length; i++) {
        setTimeout(waveNavLetterUp, animationDelay, navLinkLetters[i]);
        animationDelay += 50;
    }
}

// Add wave down animation to every letters of a single link with a slight delay
function waveNavLinkDown(navLink) {
    let navLinkLetters = navLink.querySelectorAll('span');
    let animationDelay = 0;
    for (let i = 0; i < navLinkLetters.length; i++) {
        setTimeout(waveNavLetterDown, animationDelay, navLinkLetters[i]);
        animationDelay += 50;
    }
}

// Add wave (up or down) animation to every letters of each link on mouseover event
function waveNavLinksOnHover() {
    if (navLinks.length !== 0) {
        for (let i = 0; i < (navLinks.length - 2); i++) {
            navLinks[i].addEventListener('mouseover', function(e) {
                waveNavLinkUp(navLinks[i]);
            });
        }
        for (let i = (navLinks.length - 2); i < navLinks.length; i++) {
            navLinks[i].addEventListener('mouseover', function(e) {
                waveNavLinkDown(navLinks[i]);
            });
        }
    }
}

// VIDEO PLAYERS //

// Set up Plyr video players
function setUpVideoPlayers() {
    if (galleryVideos.length !== 0) {
        videoPlayers = Plyr.setup(galleryVideos, {
            controls: [
                'play-large',
                'play',
                'progress',
                'current-time',
                'duration',
                'mute',
                'volume',
                'fullscreen'
            ],
            i18n: {
                play: 'Lire',
                pause: 'Mettre sur pause',
                seek: 'Parcourir la piste audio',
                currentTime: 'Temps écoulé depuis le début de la piste audio',
                duration: 'Durée de la piste audio',
                volume: 'Ajuster le volume',
                mute: 'Couper le son',
                unmute: 'Activer le son',
                enterFullscreen: 'Activer le mode plein écran',
                exitFullscreen: 'Quitter le mode plein écran'
            }
        });
    }
}

// Toggle videos full screen mode on Plyr enterfullscreen and exitfullscreen media events
function toggleVideosFullScreen() {
    if (videoPlayers.length !== 0) {
        for (let i = 0; i < videoPlayers.length; i++) {
            videoPlayers[i].on('enterfullscreen', function(e) {
                galleryVideos[i].classList.add('gallery__video--full-screen');
            });
            videoPlayers[i].on('exitfullscreen', function(e) {
                galleryVideos[i].classList.remove('gallery__video--full-screen');
            });
        }
    }
}

// HEADER BAR ANIMATION //

// Toggle header bar depending on scroll offset
function toggleHeaderBar() {
    if (headerBar && headerLogo) {
        let headerBarHeight = headerBar.getBoundingClientRect().height;
        if (window.pageYOffset > headerBarHeight) { // Scroll down past header bar height
            headerBar.classList.add('header-bar--fixed');
            headerLogo.classList.add('header-bar__logo--small');
        } else if (window.pageYOffset <= 0) {
            headerBar.classList.remove('header-bar--fixed');
            headerLogo.classList.remove('header-bar__logo--small');
            headerBar.classList.remove('header-bar--visible');
        }
        if (headerBar.classList.contains('header-bar--fixed')) {
            if (scrollOffset < window.pageYOffset) { // Scroll down
                headerBar.classList.remove('header-bar--visible');
            } else if (scrollOffset > window.pageYOffset) { // Scroll up
                headerBar.classList.add('header-bar--visible');
            }
            scrollOffset = window.pageYOffset;
        }
    }
}

// NAVIGATION MENU ANIMATION //

// Toggle header navigation
function toggleHeaderNav() {
    if (headerNavBtn && headerNavMenu) {
        headerNavBtn.classList.toggle('header-bar__nav-button--custom-focus');
        headerNavMenu.classList.toggle('header-bar__nav-menu--visible');
        headerNavOverlay.classList.toggle('header-bar__nav-overlay--visible');
        document.body.classList.toggle('body--hidden-overflow-y');
    }
}

// Open header navigation
function openHeaderNav() {
    if (headerNavBtn && headerNavMenu) {
        headerNavBtn.classList.add('header-bar__nav-button--custom-focus');
        headerNavMenu.classList.add('header-bar__nav-menu--visible');
        headerNavOverlay.classList.add('header-bar__nav-overlay--visible');
        document.body.classList.add('body--hidden-overflow-y');
    }
}

// Close header navigation
function closeHeaderNav() {
    if (headerNavBtn && headerNavMenu) {
        headerNavBtn.classList.remove('header-bar__nav-button--custom-focus');
        headerNavMenu.classList.remove('header-bar__nav-menu--visible');
        headerNavOverlay.classList.remove('header-bar__nav-overlay--visible');
        document.body.classList.remove('body--hidden-overflow-y');
    }
}

// Toggle header navigation on button click event
function toggleHeaderNavOnClick() {
    headerNavBtn.addEventListener('click', toggleHeaderNav);
}

// Close header navigation on document click event
function closeHeaderNavOnClick() {
    document.addEventListener('click', function(e) {
        if (headerNavBtn.classList.contains('header-bar__nav-button--custom-focus') && headerNavMenu.classList.contains('header-bar__nav-menu--visible') && !headerNavBtn.contains(e.target) && !headerNavMenu.contains(e.target)) {
            closeHeaderNav(e);
            if (e.cancelable) {
                e.preventDefault();
            }
        }
    });
}

// Open header navigation on menu list focusin event
function openHeaderNavBeforeFocus() {
    if (headerNavMenuListEls) {
        for (let i = 0; i < headerNavMenuListEls.length; i++) {
            headerNavMenuListEls[i].addEventListener('focusin', openHeaderNav);
        }
    }
}

// Close header navigation on menu list focusout event
function closeHeaderNavAfterFocus() {
    if (headerNavMenuListEls) {
        for (let i = 0; i < headerNavMenuListEls.length; i++) {
            headerNavMenuListEls[i].addEventListener('focusout', closeHeaderNav);
        }
    }
}

// Close header navigation on touchstart and touchmove events (swipe right)
function closeHeaderNavOnSwipe() {
    headerNavMenu.addEventListener('touchstart', function(e) {
        if (headerNavBtn.classList.contains('header-bar__nav-button--custom-focus') && headerNavMenu.classList.contains('header-bar__nav-menu--visible') && touchPosition.initialX === null && touchPosition.initialY === null) {
            touchPosition.initialX = event.touches[0].clientX;
            touchPosition.initialY = event.touches[0].clientY;
        }
    }, {passive: true});
    headerNavMenu.addEventListener('touchmove', function(e) {
        if (headerNavBtn.classList.contains('header-bar__nav-button--custom-focus') && headerNavMenu.classList.contains('header-bar__nav-menu--visible') && touchPosition.initialX !== null && touchPosition.initialY !== null) {
            touchPosition.currentX = event.touches[0].clientX;
            touchPosition.currentY = event.touches[0].clientY;
            touchPosition.diffX = touchPosition.initialX - touchPosition.currentX;
            touchPosition.diffY = touchPosition.initialY - touchPosition.currentY;
            if (Math.abs(touchPosition.diffX) > Math.abs(touchPosition.diffY)) {
                if (touchPosition.diffX < 0) {
                    closeHeaderNav(e);
                }
            }
            touchPosition.initialX = null;
            touchPosition.initialY = null;
        }
    }, {passive: true});
}

// ----------------------------------------------------------------------------
// PROGRAM
// ----------------------------------------------------------------------------

// Enable CSS :active pseudo-class in Safari Mobile
document.addEventListener("touchstart", function() {},false);

// HOME NAVIGATION DISPLAY //

window.addEventListener('load', function() {
    curveNavLinks();
    setNavItemTranslationProperty();
    setNavGridDisplay();
    editNavLinksOnResize();
    waveNavLinksOnHover();
});

// VIDEO PLAYERS //

setUpVideoPlayers();
toggleVideosFullScreen();

// HEADER BAR ANIMATION //

document.addEventListener('scroll', function() {
    toggleHeaderBar();
});

// NAVIGATION MENU ANIMATION //

toggleHeaderNavOnClick();
closeHeaderNavOnClick();
openHeaderNavBeforeFocus();
closeHeaderNavAfterFocus();
closeHeaderNavOnSwipe();
