<style lang="scss">
    /* always applicable */
    :global(body) {
        counter-reset: sidenote;
    }

    .counter {
        counter-increment: sidenote;
        color: #444;

        &:after {
            font-size: 0.75rem;
            position: relative;
            bottom: 0.3rem;
        }
    }

    .sidenote {
        font-size: 0.8rem;

        &:before {
            content: counter(sidenote) " ";
            position: relative;
            font-size: 0.75rem;
            bottom: 0.2rem;
        }
    }

    .sidenote-toggle {
        display: none;
    }

    /* desktop display */
    @media(min-width: 70em) {
        .counter:after {
            content: counter(sidenote);
        }

        .sidenote {
            position: absolute;
            left: calc(50vw + var(--content-width) / 2 + 1rem);
            max-width: 12rem;
            hyphens: auto;
        }
    }

    /* mobile display */
    @media (max-width: 70em) {
        .counter:after {
            content: "[" counter(sidenote) "]";
        }

        .counter:hover:after {
            color: #000;
            cursor: pointer;
        }

        .sidenote {
            box-sizing: border-box;
            position: fixed;
            left: 0;
            bottom: 0;
            width: 100vw;
            padding-top: 1rem;
            padding-bottom: 1rem;
            padding-right: 2rem;
            background-color: #fff;
            box-shadow: 0 -2px 4px -1px rgba(0, 0, 0, 0.06), 0 -2px 12px -2px rgba(0, 0, 0, 0.1);
            display: none;
        }

        .sidenote-toggle:checked + .sidenote {
            display: block;
        }
    }

    /* slight tweaks for in between state */
    @media (min-width: 52.5em) and (max-width: 70em) {
        .sidenote {
            padding-left: calc(50vw - 19rem);
        }
    }
    @media (max-width: 52.5em) {
        .sidenote {
            padding-left: 2rem;
        }
    }
</style>

<script context="module">
    import { browser } from '$app/env';
    var sidenotes = {};

    function tileNotes() {
        // find and fix collisions between sidenotes
        const minNoteGap = 15;
        var prevBottom = 0;
        Object.values(sidenotes).forEach(s => {
            if (window.getComputedStyle(s.note).position === 'fixed') {
                // fixed position means we are in mobile territory,
                // so get rid of the overflow stuff
                s.note.style.top = '';
                return;
            }

            let labelTop = s.label.getBoundingClientRect().y + window.scrollY;
            let noteHeight = s.note.getBoundingClientRect().height;
            if (labelTop < prevBottom + minNoteGap) {
                // there is a collision
                s.note.style.top = `${prevBottom + minNoteGap}px`;
                prevBottom = prevBottom + minNoteGap + noteHeight;
            }
            else {
                // no collision, but these don't quite match otherwise
                s.note.style.top = `${labelTop}px`;
                prevBottom = labelTop + noteHeight;
            }
        })
    }

    if (browser) {
        window.addEventListener('resize', tileNotes);
    }
</script>

<script>
    import { onMount } from 'svelte';

    const id = Math.random().toString().slice(2);
    sidenotes[id] = {mounted: false};
    let label;
    let note;

    onMount(async () => {
        sidenotes[id] = {mounted: true, label, note};
        if (Object.values(sidenotes).every(n => n.mounted)) {
            // all sidenotes have been mounted, now we can fix the collisions
            tileNotes();
        }

        return () => sidenotes[id].mounted = false;
    });
</script>

<label bind:this={label} for={id} class="counter"></label>
<input type="checkbox" class="sidenote-toggle" {id}/>
<span bind:this={note} class="sidenote">
    <slot></slot>
</span>