<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Scroll View</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <style>
    body {
      font-size: 100px;
    }
    [dropzone] {
      background-color: yellow;
    }
    #rectangle {
      width: 10px;
      height: 10px;
      position: absolute;
      background-color: red;
    }
    .demoFact {
      font-size: initial;
      margin-top: 20px;
    }
  </style>
</head>
<body>
  <math>
    <mi>E</mi>
    <mo>=</mo>
    <mfenced>
    <mtable>
      <mtr>
        <mtd>
          <mi dropzone="copy" data-allowed-types="PointFact,AngleFact" data-slot-id="http://mathhub.info/FrameIT/frameworld?Example?A">a</mi>
        </mtd>
        <mtd>
            <mi dropzone="copy" data-slot-id="http://mathhub.info/FrameIT/frameworld?Example?B">b</mi>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>1</mn>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
      </mtr>
      <mtr>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>0</mn>
        </mtd>
        <mtd>
          <mn>1</mn>
        </mtd>
      </mtr>
    </mtable>
  </math>
  <div class="demoFact">{
    "s_type": "PointFact",
    "label": "A",
    "_CustomLabel": null,
    "hasCustomLabel": false,
    "labelId": 0,
    "point": {"x": -1.66086578, "y": -0.00494432449, "z": -2.17682648},
    "normal": {"x": 0.1, "y": 1.2, "z": 0.3}
  }</div>
  <div class="demoFact">{
    "pid1": "http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact252",
    "pid2": "http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact254",
    "pid3": "http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256",
    "s_type": "AngleFact",
    "label": "∠BDF",
    "_CustomLabel": null,
    "is_right_angle": false,
    "hasCustomLabel": false,
    "labelId": 0
  }</div>
  <div class="demoFact">{
    "s_type": "LineFact",
    "pid1": "http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact255",
    "pid2": "http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256",
    "dir": {"x": 0.1, "y": 1.2, "z": 0.3},
    "label": "[EF]",
    "_CustomLabel": null,
    "hasCustomLabel": false,
    "labelId": 0
  }</div>
  <div class="demoFact">{
    "s_type": "RayFact",
    "pid1": "http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256",
    "pid2": "http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact252",
    "dir": {"x": 0.1, "y": 1.2, "z": 0.3},
    "label": "FB",
    "_CustomLabel": null,
    "hasCustomLabel": false,
    "labelId": 0
  }</div>
</body>
  <script>
    /**
   * @typedef Point
   * @type {object}
   * @property {number} x
   * @property {number} y
   * @property {number} z
   */
  
  /**
   * @property {Point} point
   * @property {Point} normal
   * @property {string} s_type
   * @property {string} label
   * @property {string|null} _CustomLabel
   * @property {boolean} hasCustomLabel
   * @property {number} labelId
   */
  
  class Fact {
      /** @property {string} id Fact id */
      id = ""
      /** @property {string} s_type Fact type */
      s_type = ""
      /** @property {string} label used in unity */
      label = ""
      /** @property {string | null} _CustomLabel Custom label */
      _CustomLabel = null
      /** @property {boolean} hasCustomLabel */
      hasCustomLabel = false
      /** @property {number} labelId */
      labelId = 0
  }
  
  class Point {
      /** @property {number} x */
      x = 0
      /** @property {number} y */
      y = 0
      /** @property {number} z */
      z = 0
  }
  /**
  s_type: PointFact,
  label: A,
  _CustomLabel: null,
  hasCustomLabel: false,
  labelId: 0,
  point: {x: -1.66086578, y: -0.00494432449, z: -2.17682648},
  normal: {x: 0, y: 1, z: 0}
   */
  class PointFact extends Fact {
      s_type = "PointFact";
      /** @property {Point} point */
      point = new Point()
      /** @property {Point} normal */
      normal = new Point()
  }
  
  /**
   * pid1: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact252,
  pid2: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact254,
  pid3: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256,
  s_type: AngleFact,
  label: ∠BDF,
  _CustomLabel: null,
  is_right_angle: false,
  hasCustomLabel: false,
  labelId: 0
   */
  class AngleFact extends Fact {
      s_type = "AngleFact";
      pid1 = "";
      pid2 = "";
      pid3 = "";
      is_right_angle = false;
  }
  
  /**
   * s_type: LineFact,
  pid1: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact255,
  pid2: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256,
  dir: [object Object],
  label: [EF],
  _CustomLabel: null,
  hasCustomLabel: false,
  labelId: 0
   */
  class LineFact extends Fact {
      s_type = "LineFact";
      pid1 = "";
      pid2 = "";
      dir = new Point();
  }
  
  /**
   * s_type: RayFact,
  pid1: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact256,
  pid2: http://mathhub.info/FrameIT/frameworld?DefaultSituationSpace/SituationTheory1?fact252,
  dir: [object Object],
  label: FB,
  _CustomLabel: null,
  hasCustomLabel: false,
  labelId: 0
   */
  class RayFact extends Fact {
      s_type = "RayFact";
      pid1 = "";
      pid2 = "";
      dir = new Point();
  }
  
  
  
  /** @param {DragEvent} event  */
  function dropHandler(event) {
      event.preventDefault()
  
      const data = event.dataTransfer.getData("application/json")
      //const data = event.dataTransfer.getData("text/plain")
      console.log(`Droped data: '${event.dataTransfer.types}'`, event.dataTransfer.types)
  
      /** @type {Fact} */
      const fact = JSON.parse(data)
      console.warn(`Droped Fact '${fact.label}':`, fact)
  
      /** @type {HTMLElement} */
      const element = event.target
  
      if (element.hasAttribute("data-allowed-types")) {
          //const allowedTypesStr = element.dataset["allowed-types"]
          const allowedTypesStr = element.getAttribute("data-allowed-types")
          const allowedTypes = allowedTypesStr.split(",")
  
          if (!allowedTypes.includes(fact.s_type)) {
              console.warn(`The drop target data-type '${fact.s_type}' is not a member of the allowed types '${allowedTypesStr}'`)
              return
          }
      }
  
      element.innerHTML = fact.label
      element.fact = fact
      element.dataset.factId = fact.id
  }
  
  
  /*
  * debug functions
  */
  
  /** @param {DragEvent} event  */
  function printHandler(event, evName) {
      let items = event.dataTransfer.types
      console.log(`${evName} getData: '${event.dataTransfer.getData("application/json")}'`, items)
      console.log(`${evName} getData: '${event.dataTransfer.types}'`, items)
  }
  /** @param {DragEvent} event  */
  function printPreventDefaultHandler(event, evName) {
      printHandler(event, evName)
      event.preventDefault()
  }
  
  /*
  * register the drag event listeners
  */
  //document.addEventListener("dragstart", ev => printHandler(ev, "DragStartEvent"))
  //document.addEventListener("dragenter", ev => printHandler(ev, "DragEnterEvent"))
  //document.addEventListener("drag", ev => printHandler(ev, "DragEvent"))
  document.addEventListener("dragover", ev => ev.preventDefault())
  //document.addEventListener("dragover", ev => printPreventDefaultHandler(ev, "DragOverEvent"))
  //document.addEventListener("dragleave", ev => printHandler(ev, "DragLeaveEvent"))
  //document.addEventListener("dragend", ev => printHandler(ev, "DragEndEvent"))
  
  // select all dropzones and add drop event listeners
  let dropZones = document.querySelectorAll('[dropzone="copy"]')
  dropZones.forEach( dropZone => dropZone.addEventListener("drop", ev => dropHandler(ev, "DropEvent")) )
  </script>

  <!--<script src="visualiseCursor.mjs" defer type="module"></script>-->
  <!--<script>
  /* mouse and pointer event handling */
  const rectangle = document.createElement("div");
  rectangle.id = "rectangle";
  
  console.log("appendChild to", document.body)
  document.body.appendChild(rectangle);
  
  function followCursor(event) {
  const cursorX = event.clientX;
  const cursorY = event.clientY +5;
  //console.log(`MouseEvent X: ${cursorX}, Y: ${cursorY}, Event type: ${event.type}`, event);
  rectangle.style.left = `${cursorX}px`;
  rectangle.style.top = `${cursorY}px`;
  }
  
  document.addEventListener("mousemove", followCursor);
  document.addEventListener("pointermove", followCursor);
  
  document.addEventListener("mouseover", followCursor);
  document.addEventListener("pointerover", followCursor);
  
  document.addEventListener("mouseout", followCursor);
  document.addEventListener("pointerout", followCursor);
  </script>-->
</html>