import { Container } from "pixi.js";

let maxZIndex = 100; // heretic method to bring dragged sprite to the front,
// will technically overflow if you play long enough,
// it is also shitty because if you externally use zIndex on the sprites in the same container, it may not bring to front
// clean solution would be to make a draggable container class

function onDragMove(node, event, shift = { x: 0, y: 0 }) {
    // shift is a tuple representing the shift between the coords of the node and the pointer
    const dragPoint = event.global;

    dragPoint.x -= shift.x;
    dragPoint.y -= shift.y;
    const parent = node.parent;
    const newPos = parent.toLocal(dragPoint);
    if (newPos.x < 0) {
        newPos.x = 0;
    } else {
        const right =
            parent.layout?.computedLayout.width -
            node.layout?.computedLayout.width;
        if (newPos.x > right) {
            newPos.x = right;
        }
    }
    if (newPos.y < 0) {
        newPos.y = 0;
    } else {
        const bottom =
            parent.layout?.computedLayout.height -
            node.layout?.computedLayout.height;
        if (newPos.y > bottom) {
            newPos.y = bottom;
        }
    }

    node.position = newPos;
}

function onDragEnd(node, onDrop) {
    node.off("pointerup");
    node.off("pointerupoutside");
    node.off("globalpointermove");
    onDrop(node);
}

function onDragStart(node, onDrop, event) {
    console.log("start drag");
    node.on("pointerup", () => onDragEnd(node, onDrop));
    node.on("pointerupoutside", () => onDragEnd(node, onDrop));
    node.parent.eventMode =
        node.parent.eventMode == "dynamic" ? "dynamic" : "static";
    node.zIndex = ++maxZIndex;
    const dragShift = node.parent.toLocal(event.global.clone(), null);
    dragShift.x -= node.x;
    dragShift.y -= node.y;
    node.on("globalpointermove", (event) => {
        onDragMove(node, event, dragShift);
    });
}

function makeDragable(node, onDrop = () => {}) {
    node.eventMode = "static";
    node.on("pointerdown", (event) => {
        onDragStart(node, onDrop, event);
    });
}

function makeUnDragable(node, onDrop = () => {}) {
    node.off("pointerdown");
}

export { makeDragable, makeUnDragable };
