<script>
  // @ts-nocheck

  import { afterUpdate, createEventDispatcher } from 'svelte';
  import { fade } from 'svelte/transition';
  import HeaderImage from './HeaderImage.svelte';

  export let nofocus = false;
  export let size = ''; // small, mediumlarge, medium, large
  let className = '';

  const dispatch = createEventDispatcher();
  /**
   * @type {HTMLDivElement}
   */
  let container;
  /**
   * @type {HTMLDivElement}
   */
  let background;

  export { className as class };

  /**
   * @param {{ target: HTMLDivElement; }} event
   */
  export function close(event) {
    if (!event || event.target === container) {
      dispatch('close');
    }
  }

  /**
   * @param {{ addEventListener: (arg0: any, arg1: any) => void; removeEventListener: (arg0: any, arg1: any) => any; }} node
   * @param {string} event
   * @param {{ (event: any): void; (event: any): void; }} handler
   */
  function add(node, event, handler) {
    node.addEventListener(event, handler);
    return () => node.removeEventListener(event, handler);
  }

  /**
   * @param {{ dispatchEvent: (arg0: CustomEvent<{ x: any; y: any; }>) => void; }} node
   * @param {any} x
   * @param {any} y
   */
  function dispatch_tap(node, x, y) {
    node.dispatchEvent(
      new CustomEvent('tap', {
        detail: { x, y },
      })
    );
  }

  /**
   * @param {HTMLDivElement} node
   */
  function tapThis(node) {
    /**
     * @param {{ clientX: any; clientY: any; }} event
     */
    function handle_pointerdown(event) {
      // @ts-ignore
      if (node.disabled) return;
      const { clientX, clientY } = event;

      const remove_pointerup_handler = add(node, 'pointerup', event => {
        if (event.target !== node) return;
        if (Math.abs(event.clientX - clientX) > 5) return;
        if (Math.abs(event.clientY - clientY) > 5) return;

        dispatch_tap(node, event.clientX, event.clientY);
        remove_pointerup_handler();
      });

      setTimeout(remove_pointerup_handler, 300);
    }

    const remove_pointerdown_handler = add(node, 'pointerdown', handle_pointerdown);

    return {
      destroy() {
        remove_pointerdown_handler();
      },
    };
  }

  afterUpdate(() => {
    if (container && container.parentNode !== document.body) {
      document.body.appendChild(background);
      document.body.appendChild(container);
      if (!nofocus) container.focus();
    }
  });
</script>

<div bind:this={background} class="modal-background" transition:fade|local={{ duration: 300 }}></div>
<div
  bind:this={container}
  class="modal-container{size ? ' ' + size : ''} {className}"
  tabindex="-1"
  role="dialog"
  use:tapThis
  on:tap={close}
>
  <HeaderImage type="modal" />
  <slot />
</div>

<style>
  .modal-container {
    position: fixed;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1040;
    overflow-x: hidden;
    overflow-y: auto;
    outline: 0;
    -webkit-overflow-scrolling: touch;
  }

  .modal-container.small {
    max-width: 400px;
    margin: 80px auto;
  }
  .modal-container.mediumlarge {
    max-width: 732px;
    margin: 80px auto;
  }
  .modal-container.medium {
    max-width: 480px;
    margin: 80px auto;
  }
  .modal-container.large {
    max-width: 900px;
    margin: 80px auto;
  }
  .modal-background {
    position: fixed;
    width: 100%;
    height: 100%;
    left: 0;
    top: 0;
    z-index: 950;
    background: var(--modal-background);
  }

  :root {
    --modal-background: rgba(0, 0, 0, 0.5);
    --modal-shadow: 0 2px 8px rgba(0, 0, 0, 0.5);
    --modal-shadow-large: 0 5px 15px rgba(0, 0, 0, 0.5);
    --page-background: #fff;
  }
</style>
