<script>
    import { onMount, createEventDispatcher } from 'svelte'
    import { stores } from '@sapper/app'
    import { currentLocation, fullscreen } from 'utils/store'
    import { getThumbnail, formatDate } from 'utils/functions'

    // Dependencies
    import SwipeListener from 'swipe-listener'

    // Animations
    import { animateIn } from 'animations/Carousel'

    // Components
    import IconArrow from 'atoms/IconArrow'
    import Counter from 'atoms/Counter'
    import PaginationDots from 'molecules/PaginationDots'

    // Props
    export let photos
    export let viewer = false

    // Variables
    const dispatch = createEventDispatcher()
    const { page } = stores()
    let scope
    let swiped
    let currentIndex = 0

    // Reactive variables from currentIndex
    $: currentPhoto = photos[currentIndex] || null
    $: prevPhoto = photos[currentIndex - 1] || photos[photos.length - 1]
    $: nextPhoto = photos[currentIndex + 1] || photos[0]


    /*
    ** Navigate to a photo
    */
    // Change current index from param
    const goToPhoto = to => {
        if (to === 'prev') {
            currentIndex--
            currentIndex = (currentIndex < 0) ? photos.length - 1 : currentIndex
        } else if (to === 'next') {
            currentIndex++
            currentIndex = (currentIndex >= photos.length) ? 0 : currentIndex
        } else {
            currentIndex = to
        }

        // Dispatch current photo
        dispatch('photoChange', photos[currentIndex])
        // Reset fullscreen value if open
        if ($fullscreen) fullscreen.set()
    }

    // Hover on controls
    const hoverPhoto = event => {
        const button = event.currentTarget.querySelector('button')
        const photoActive = scope.querySelector('.gallery__photo--active')

        let photoToHover
        if (event.currentTarget.dataset.to === 'prev') {
            photoToHover = (photoActive.previousSibling != null) ? photoActive.previousSibling : photoActive.parentNode.lastChild
        } else {
            photoToHover = (photoActive.nextSibling != null) ? photoActive.nextSibling : photoActive.parentNode.firstChild
        }

        // Toggle class and focus of the button
        if (event.type === 'mouseenter') {
            photoToHover.classList.add('hover')
            button.classList.add('hover')
        } else if (event.type === 'mouseleave') {
            photoToHover.classList.remove('hover')
            button.classList.remove('hover')
        }
    }

    // Open fullscreen
    const openFullscreen = event => {
        if (!swiped) {
            fullscreen.set(currentPhoto)
        }
        // Reset swiped event if fired
        swiped = false
    }


    /*
    ** Navigation
    */
    // Drag and swipe
    const swipe = directions => {
        swiped = true

        if (directions.right) {
            goToPhoto('prev')
        } else if (directions.left) {
            goToPhoto('next')
        }
    }

    // Keyboard navigation
    const keyboardNav = event => {
        if ([37,80,74].includes(event.keyCode)) {
            goToPhoto('prev')
        } else if ([39,78,75].includes(event.keyCode)) {
            goToPhoto('next')
        }
    }


    /*
    ** Run code when mounted
    */
    onMount(() => {
        // Entering transition
        if (photos.length) {
            animateIn(scope)
        }

        // Enable gestures
        const touch = SwipeListener(scope)

        // Viewer: Navigate to photo on init and URL change
        if (viewer) {
            page.subscribe(page => {
                if (page.path.includes('/viewer/')) {
                    goToPhoto(photos.findIndex(photo => photo.slug === page.params.photo))
                }
            })
        }
    })
</script>

<svelte:window on:keydown={keyboardNav} />

{#if photos.length}
<div class="carousel"
    bind:this={scope}
    on:swipe={event => swipe(event.detail.directions)}
>
    <div class="wrap">
        <div class="gallery">
            <div class="gallery__images">
                {#each photos as { id, name, location, image }, index}
                <picture class="gallery__photo"
                    class:gallery__photo--prev={id === prevPhoto.id}
                    class:gallery__photo--active={id === currentPhoto.id}
                    class:gallery__photo--next={id === nextPhoto.id}
                    on:click={openFullscreen}
                >
                    <source media="(min-width: 968px)" srcset={getThumbnail(image.private_hash, 1400)}>
                    <source media="(min-width: 800px)" srcset={getThumbnail(image.private_hash, 900)}>
                    <source media="(min-width: 500px)" srcset={getThumbnail(image.private_hash, 600)}>
                    <source media="(min-width: 300px)" srcset={getThumbnail(image.private_hash, 400)}>
                    <img src="{getThumbnail(image.private_hash, 900)}" alt="{name}, {location.name}, {location.country.name}">
                </picture>
                {/each}
            </div>

            <div class="carousel__controls">
                <div class="carousel__area carousel__area--prev" data-to="prev" rel="prev"
                    on:mouseenter={hoverPhoto} on:mouseleave={hoverPhoto}
                    on:click={() => goToPhoto('prev')}
                >
                    <button class="button-control button-control--white dir-left" aria-label="Previous">
                        <IconArrow direction="left" color="#ff6c89" class="icon" />
                        <IconArrow direction="left" color="#fff" class="icon" hidden="true" />
                    </button>
                </div>

                <div class="carousel__area carousel__area--next" data-to="next" rel="next"
                    on:mouseenter={hoverPhoto} on:mouseleave={hoverPhoto}
                    on:click={() => goToPhoto('next')}
                >
                    <button class="button-control button-control--white dir-right" aria-label="Next">
                        <IconArrow direction="right" color="#ff6c89" class="icon" />
                        <IconArrow direction="right" color="#fff" class="icon" hidden="true" />
                    </button>
                </div>
            </div>

            {#if viewer}
            <Counter {currentIndex} className="carousel__number" />
            {/if}
        </div>

        <div class="carousel__infos">
            <div class="carousel__locations">
                {#each photos as { id, name, location }, index}
                <div class="carousel__location style-location"
                    class:carousel__location--prev={id === prevPhoto.id}
                    class:carousel__location--active={id === currentPhoto.id}
                    class:carousel__location--next={id === nextPhoto.id}
                >
                    <p class="street">{name}</p>
                    <p class="state style-caps style-caps--transparent">
                        {location.name}, {location.country.name}
                    </p>
                </div>
                {/each}
            </div>
            {#if viewer}
            <p class="carousel__date">{formatDate(currentPhoto.date, 'FULL')}</p>
            {/if}
        </div>
    </div>

    <PaginationDots className="carousel__dots" {photos} {currentIndex}
        on:goToIndex={event => currentIndex = event.detail}
    />
</div>
{/if}
