Source: utils/template/functions/custom/staOverview.js

import "./staOverview.css";
import { displayImage } from '../media.js';
import { timeseries } from '../timeseries.js';


function filterDatastreams(datastreams, sensor, observedProperty) {
    const result = {
        sensors: {},
        observedProperties: {},
        datastreams: {},
        selectedSensor: sensor,
        selectedObservedProperty: observedProperty
    }

    datastreams.forEach(ds => {
        if ("Sensor" in ds) result.sensors[ds.Sensor["@iot.id"]] = ds.Sensor;

        if ((sensor.length == 0) && (observedProperty.length == 0)) {
            if ("ObservedProperty" in ds) result.observedProperties[ds.ObservedProperty["@iot.id"]] = ds.ObservedProperty;
            result.datastreams[ds["@iot.id"]] = ds;
        } else if ((sensor.length > 0) && (observedProperty.length == 0)) {
            if (ds.Sensor["@iot.id"] == sensor) {
                if ("ObservedProperty" in ds) result.observedProperties[ds.ObservedProperty["@iot.id"]] = ds.ObservedProperty;
                result.datastreams[ds["@iot.id"]] = ds;
            }
        } else if ((sensor.length > 0) && (observedProperty.length > 0)) {
            if (ds.Sensor["@iot.id"] == sensor) {
                result.observedProperties[ds.ObservedProperty["@iot.id"]] = ds.ObservedProperty;
                if (ds.ObservedProperty["@iot.id"] == observedProperty) result.datastreams[ds["@iot.id"]] = ds;
            }
        } else if ((sensor.length == 0) && (observedProperty.length > 0)) {
            result.observedProperties[ds.ObservedProperty["@iot.id"]] = ds.ObservedProperty;
            if (ds.ObservedProperty["@iot.id"] == observedProperty) result.datastreams[ds["@iot.id"]] = ds;
            if ("Sensor" in ds) result.selectedSensor = ds.Sensor["@iot.id"];
        }
    });

    if (Object.keys(result.observedProperties).length == 1) {
        result.selectedObservedProperty = result.observedProperties[Object.keys(result.observedProperties)[0]]["@iot.id"];
    }

    return result;
}

function load(layer, datastream = null, filters = null) {
    timeseries.load('sta', layer.config.url, [datastream], filters, {
        layer: layer
    });
}

/**
 * 
 * @param {object} datastreams
 * @param {Layer} layer
 * @returns {string} div placeholder
 */
export function staOverview(datastreams, layer) {
    if (!datastreams) return undefined;

    const div = document.createElement("div");
    div.classList.add("sta-overview");

    let filtered = filterDatastreams(datastreams, "", "");

    const create = () => {
        const sensors = filtered.sensors;
        const observedProperties = filtered.observedProperties;

        div.innerHTML = "";

        const sensorSelect = document.createElement("select");
        let option = document.createElement("option");
        option.value = "";
        option.innerText = "-- select a sensor --";
        sensorSelect.appendChild(option);
        for (let id in sensors) {
            option = document.createElement("option");
            option.value = id;
            option.innerText = sensors[id].name;
            sensorSelect.appendChild(option);
        }
        sensorSelect.value = filtered.selectedSensor;
        sensorSelect.addEventListener("change", () => {
            filtered = filterDatastreams(datastreams, sensorSelect.value, "");
            create();
        });

        div.appendChild(sensorSelect);

        const observedPropertySelect = document.createElement("select");
        option = document.createElement("option");
        option.value = "";
        option.innerText = "-- select an observed property --";
        observedPropertySelect.appendChild(option);
        for (let id in observedProperties) {
            option = document.createElement("option");
            option.value = id;
            option.innerText = observedProperties[id].name;
            observedPropertySelect.appendChild(option);
        }
        observedPropertySelect.value = filtered.selectedObservedProperty;
        observedPropertySelect.addEventListener("change", () => {
            filtered = filterDatastreams(datastreams, sensorSelect.value, observedPropertySelect.value);
            create();
        });
        div.appendChild(observedPropertySelect);

        const dsKeys = Object.keys(filtered.datastreams);
        if (dsKeys.length == 1) {
            const button = document.createElement("button");
            button.innerText = "Visualize Time Series";
            button.addEventListener("click", () => {
                const id = dsKeys[0];
                const datastream = filtered.datastreams[id];
                load(layer, datastream, null);
            });
            div.appendChild(button);

        } else {
            const datastreamPropertySelect = document.createElement("select");
            option = document.createElement("option");
            option.value = "";
            option.innerText = "-- select a datastream --";
            datastreamPropertySelect.appendChild(option);

            for (let id in filtered.datastreams) {
                option = document.createElement("option");
                option.value = id;
                option.innerText = filtered.datastreams[id].name;
                datastreamPropertySelect.appendChild(option);
            }

            datastreamPropertySelect.value = "";

            const button = document.createElement("button");
            button.innerText = "Visualize Time Series";
            button.addEventListener("click", () => {
                const id = datastreamPropertySelect.value;
                const datastream = filtered.datastreams[id];
                load(layer, datastream);
            });

            datastreamPropertySelect.addEventListener("change", () => {
                const value = datastreamPropertySelect.value;
                if (value.length == 0) {
                    button.remove()
                } else {
                    div.appendChild(button);
                }
            });
            div.appendChild(datastreamPropertySelect);
        }
    };

    create();

    return div;
}

/**
 * Generates a div element containing images and their captions.
 * 
 * @param {Array} images - An array of image objects.
 * @param {string} images[].url - The URL of the image.
 * @param {string} images[].caption - The caption for the image.
 * @returns {HTMLDivElement|undefined} A div element containing the images and captions, or undefined if no images are provided.
 */
export function staThingImages(images) {
    if (!images) return undefined;

    const div = document.createElement("div");

    for (let i = 0; i < images.length; ++i) {
        const caption = document.createElement("div");
        caption.innerText = images[i].caption;
        div.appendChild(caption);
        const img = displayImage(images[i].url);
        img.style.marginBottom = "5px";
        div.appendChild(img);
    }

    return div;
}