window.ElementSetAttribute = (element, attr, value) => {
    if (element && element.setAttribute) element.setAttribute(attr, value);
}

window.SetImageAttribute = (element, width, height, originX, originY, href) => {
    if (element && element.nodeName && element.nodeName.toLowerCase() === "image") {
        element.setAttribute("width", width);
        element.setAttribute("height", height);
        element.setAttribute("x", originX);
        element.setAttribute("y", originY);
        element.setAttribute("href", href);
    }
};

window.SetRobotPosition = (robotRef, nameRef, x, y, theta, originX, originY) => {
    if (robotRef && robotRef.setAttribute) {
        robotRef.setAttribute("x", x + originX);
        robotRef.setAttribute("y", y + originY);
        robotRef.setAttribute("transform", `rotate(${theta} ${x} ${y})`);
    }
    if (nameRef && nameRef.setAttribute) {
        nameRef.setAttribute("x", x);
        nameRef.setAttribute("y", -y);
    }
}

window.SetNodePosition = (circleRef, textRef, x, y) => {
    if (circleRef && circleRef.setAttribute) {
        circleRef.setAttribute("cx", x);
        circleRef.setAttribute("cy", y);
    }
    if (textRef && textRef.setAttribute) {
        const radius = parseFloat(localStorage.getItem('--node-r'));
        if (!radius) {
            radius = 0.1;
        }
        textRef.setAttribute("x", x);
        textRef.setAttribute("y", - y - radius - 0.08);
    }
};

window.UpdateViewContainerRect = async (dotnetRef, divElement, funcName) => {
    var rect = divElement.getBoundingClientRect();
    await dotnetRef.invokeMethodAsync(funcName, rect.x, rect.y, rect.width, rect.height, rect.top, rect.right, rect.bottom, rect.left);
};

window.ResizeObserverRegister = (dotnetRef, divElement, funcName) => {
    const resizeObserver = new ResizeObserver(async (entries) => {
        await window.UpdateViewContainerRect(dotnetRef, divElement, funcName);
    });

    resizeObserver.observe(divElement);
};

window.AddEventListener = (dotnetRef, element, eventName, funcName, stopPropagation = true) => {
    element.addEventListener(eventName, async (ev) => {
        ev.preventDefault();
        if (stopPropagation) ev.stopPropagation();
        await dotnetRef.invokeMethodAsync(funcName);
    })
};

window.AddMouseMoveEventListener = (dotnetRef, element, funcName, stopPropagation = true) => {
    element.addEventListener("mousemove", async (ev) => {
        ev.preventDefault();
        if (stopPropagation) ev.stopPropagation();
        await dotnetRef.invokeMethodAsync(funcName, ev.clientX, ev.clientY, ev.buttons, ev.ctrlKey, ev.movementX, ev.movementY);
    })
};

window.AddMouseWheelEventListener = (dotnetRef, element, funcName, stopPropagation = true) => {
    element.addEventListener("mousewheel", async (ev) => {
        if (stopPropagation) ev.stopPropagation();
        await dotnetRef.invokeMethodAsync(funcName, ev.deltaY, ev.offsetX, ev.offsetY);
    }, { passive: true })
};

window.AddTouchMoveEventListener = (dotnetRef, element, funcName, stopPropagation = true) => {
    let lastX = 0, lastY = 0;
    element.addEventListener("touchmove", async (ev) => {
        ev.preventDefault();
        if (stopPropagation) ev.stopPropagation();

        const touch = ev.touches[0];
        const movementX = touch.clientX - lastX;
        const movementY = touch.clientY - lastY;

        lastX = touch.clientX;
        lastY = touch.clientY;
        await dotnetRef.invokeMethodAsync(funcName, touch.clientX, touch.clientY, ev.touches.length, movementX, movementY);
    });

    element.addEventListener("touchstart", (ev) => {
        const touch = ev.touches[0];
        lastX = touch.clientX;
        lastY = touch.clientY;
    });
};

window.SetMapSvgConfig = (element, width, height, originX, originY) => {
    if (element && element.nodeName && element.nodeName.toLowerCase() === "svg") {
        element.setAttribute("width", width);
        element.setAttribute("height", height);
        element.setAttribute("viewBox", `${originX} ${originY} ${width} ${height}`);
    }
};

window.SetMapMovement = (element, top, left) => {
    if (element && element.nodeName && element.nodeName.toLowerCase() === "div") {
        element.setAttribute("style", `top: ${top}px; left: ${left}px;`);
    }
};

window.SetMapSvgRect = (element, width, height) => {
    if (element && element.nodeName && element.nodeName.toLowerCase() === "svg") {
        element.setAttribute("width", width);
        element.setAttribute("height", height);
    }
};