Source: utils/template/functions/geojson.js

import { Window } from '../../../ui/Window.js';
import { openColorPicker as openColorPicker_ } from "../../openColorPicker.js";
import { computeSize as computeSize_ } from '../../../map/utils/computeSize.js';
import { generateTable } from "./common.js";

import "./geojson.css";

let labelSelector = null;

/**
 * Opens a label selection window for a given layer and updates the label based on user input.
 *
 * 
 * 
 * @param {Object} layer - The layer object to update.
 * @param {Object} properties - The properties object containing the label key.
 * @param {string} key - The key in the properties object for the label.
 * @returns {HTMLElement} The span element containing the label link.
 */
export function openLabelSelection(layer, properties, key) {
    if (!properties[key]) properties[key] = null;

    const label = properties[key];
    const span = document.createElement("span");
    span.dataset.configRemoveEmptyColumn = "false";
    span.innerHTML = `<i><a title="${label || "set label"}" href='#'>${label || "<i>set label</i>"}</a></i>`;

    const updateLayer_ = () => {
        span.querySelector("a").title = properties[key] || "set label";
        span.querySelector("a").innerText = properties[key] || "set label";
        layer?.activeLayer_.updateTooltips();
    }

    const openLabelSelection_ = e => {
        e.preventDefault();
        e.stopPropagation();

        if (labelSelector) labelSelector.dispose();
        labelSelector = new Window(null, {
            title: "SET LABEL",
            width: "340px",
            open: true,
            center: true,
            draggable: true,
            content: `
                <input spellcheck="false" style="width: 100%; padding: 5px" placeholder="input label text ..." class="label-input"/>
                <div style="text-align:right; margin-top:10px;">
                    <button class="btn-remove-label">Remove Label</button>
                    <button class="btn-apply-label">Apply</button>
                </div>
            `
        });
        const element = labelSelector.getElement();
        const input = element.querySelector("input");
        const remove = element.querySelector(".btn-remove-label");
        const apply = element.querySelector(".btn-apply-label");

        input.value = label || "";

        remove.onclick = e => {
            labelSelector.close();
            properties[key] = null;
            updateLayer_();
        };

        const save = () => {
            labelSelector.close();
            properties[key] = input.value.trim();
            updateLayer_();
        }

        apply.onclick = save;
        input.onkeypress = e => {
            // save on pressing enter
            if (e.keyCode === 13) save();
        };

        input.focus();
    }

    span.addEventListener("append", e => {
        if ((span.parentNode.nodeName == "TD") && (span.parentNode.parentNode.nodeName == "TR")) {
            span.parentNode.parentNode.addEventListener("click", openLabelSelection_);
        } else {
            span.addEventListener("click", openLabelSelection_);
        }
    });

    return span;
}


/**
 * Creates a color picker element for a given layer and properties.
 *
 * 
 * 
 * @param {Object} layer - The layer object that contains the active layer.
 * @param {Object} properties - The properties object where the color key is stored.
 * @param {string} key - The key in the properties object that holds the color value.
 * @returns {HTMLElement} The span element containing the color picker.
 */
export function openColorPicker(layer, properties, key) {
    if (!properties[key]) properties[key] = null;

    const color = properties[key];
    const span = document.createElement("span");
    span.classList.add("popup-color-cell");
    span.dataset.configRemoveEmptyColumn = "false";
    span.innerHTML = `<a title="${color || "set color"}" href='#'>${color || "<i>set color</i>"}</a><div style="background-color:${color || ""};" class='popup-color-indicator'></div>`;

    const colorValueCellLink = span.querySelector("a");
    const colorIndicator = span.querySelector(".popup-color-indicator");

    const open = e => {
        e.preventDefault();
        e.stopPropagation();
        openColorPicker_(color => {
            properties[key] = color;
            layer?.activeLayer_.updateStyle();
            colorIndicator.style.backgroundColor = properties.color;
            colorValueCellLink.innerText = color;
            colorValueCellLink.title = color;
        });
    }

    span.addEventListener("append", e => {
        if ((span.parentNode.nodeName == "TD") && (span.parentNode.parentNode.nodeName == "TR")) {
            span.parentNode.parentNode.addEventListener("click", open);
        } else {
            span.addEventListener("click", open);
        }
    });

    return span;
}

/**
 * Computes the size of a given geometry and generates a table with the properties.
 *
 * 
 * 
 * @param {Object} geometry - The geometry object to compute the size for.
 * @returns {Object} - A table with the computed properties.
 */
export function computeSize(geometry) {
    const properties = computeSize_({
        type: "Feature",
        geometry: geometry
    });
    return generateTable(properties);
}