/**
 * @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
 */

var assignment;

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()
    console.log("dropHandler", event)

    const data = event.dataTransfer.getData("application/json")
    //const data = event.dataTransfer.getData("text/plain")
    console.log(`Dropped data: '${event.dataTransfer.types}'`, event.dataTransfer.types)

    /** @type {Fact} */
    const fact = JSON.parse(data)
    console.warn(`Dropped 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
}

/** @param {MouseEvent} event  */
function clickHandler(event) {
    event.preventDefault()
    console.log("clickHandler")
    console.log("clickHandler", event)
    switch (event.button) {
    case 0:
        console.log("Left button clicked")
        event.target.fact = null
        event.target.dataset.factId = null
        break
    case 1:
        console.log("Middle button clicked")
        break
    case 2:
        console.log("Right button clicked")
        getHint(event.target.dataset.slotId)
        break
    default:
        console.log("Unknown button clicked")
    }
}

/*
* 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")) )

/** select all dropzones and add drop event listeners */
function addDropZoneEventListeners() {
    console.log("addDropZoneEventListeners")
    document.querySelectorAll('[dropzone="copy"]')
    .forEach( dropZone => {
        dropZone.removeEventListener("drop", dropHandler)
        dropZone.removeEventListener("click", clickHandler)
        dropZone.removeEventListener("contextmenu", clickHandler)
        //dropZone.addEventListener("dragover", ev => ev.preventDefault())
        dropZone.addEventListener("drop", dropHandler)
        dropZone.addEventListener("click", clickHandler)
        dropZone.addEventListener("contextmenu", clickHandler)
    })
}
//addDropZoneEventListeners()