<!--  -->
<script lang="ts">
  import type { Link } from "$lib/util/types";
  import LinkText from "./LinkText.svelte";

  export let items: Link[] = [];
  export let suffix: string | undefined = undefined;
  export let nodrag = false;

  let container: HTMLElement;
  let ribbon: HTMLElement;
  let timer: number | null = null;
  // Ribbon position in pixels
  let position = 0;
  // Direction in which the ribbon moves (true: positive, false: negative)
  let moveDirection = true;
  // Maximum ribbon position in pixels
  let moveLimit = 0;
  // Pause the motion of the ribbon
  let brake = false;

  const DELAY = 50;

  // Reset marquee when items change
  $: if (items) reset();

  function onMouseEnter() {
    // If the mouse re-enters when the marquee is running, pause it
    if (timer !== null) {
      brake = true;
      return;
    }

    const ribbonWidth = ribbon.getBoundingClientRect().width;
    const containerWidth = container.getBoundingClientRect().width;

    if (ribbonWidth > containerWidth) {
      moveLimit = ribbonWidth - containerWidth;
      moveDirection = true;
      timer = window.setTimeout(onTimer, DELAY);
    }
  }

  function onTimer() {
    if (!brake) {
      if (moveDirection) {
        if (position < moveLimit) position++;
        else moveDirection = false;
      } else {
        if (position > 0) {
          position--;
        } else {
          reset();
          return;
        }
      }
    }
    timer = window.setTimeout(onTimer, DELAY);
  }

  function reset() {
    position = 0;
    if (timer !== null) {
      window.clearTimeout(timer);
      timer = null;
    }
  }
</script>

<!-- When the window size changes, the pixel counts dont match anymore,
so the marquee is reset -->
<svelte:window on:resize={reset} />

<div class="marquee" bind:this={container}>
  <div class="overflow-hidden">
    <!-- svelte-ignore a11y-no-static-element-interactions -->
    <div
      class="marquee-ribbon"
      style={`--trans-x:${-position}px;`}
      bind:this={ribbon}
      on:mouseenter={onMouseEnter}
      on:mouseleave={() => {
        brake = false;
      }}
    >
      {#each items as item, i}
        {#if i !== 0}
          ,&nbsp;
        {/if}
        <LinkText {item} {nodrag} />
      {/each}
      {#if suffix}
        {suffix}
      {/if}
    </div>
  </div>
</div>

<style lang="postcss">
  .marquee {
    width: 100%;
    margin-left: -6px;
    margin-right: -6px;
    mask-image: linear-gradient(
      90deg,
      transparent 0,
      #000 6px,
      #000 calc(100% - 12px),
      transparent
    );
    overflow: hidden;
    position: relative;
  }

  .marquee-ribbon {
    --trans-x: 0px;
    display: flex;
    padding-inline-start: 6px;
    padding-inline-end: 12px;
    transform: translateX(var(--trans-x));
    white-space: nowrap;
    width: fit-content;
  }
</style>
