var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import { InputType } from "@openremote/or-mwc-components/or-mwc-input";
import { css, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators.js";
import { when } from "lit/directives/when.js";
import { showSnackbar } from "@openremote/or-mwc-components/or-mwc-snackbar";
import { i18next } from "@openremote/or-translate";
let OrConfMapGlobal = class OrConfMapGlobal extends LitElement {
    constructor() {
        super(...arguments);
        this.config = {};
        this.limit = 30e+6;
    }
    /* -------------- */
    render() {
        var _a, _b, _c, _d, _e;
        const isCustom = (_b = (_a = this.config.sources) === null || _a === void 0 ? void 0 : _a.vector_tiles) === null || _b === void 0 ? void 0 : _b.custom;
        const hasExternalSource = Object.keys(this.config.sources).length > 1;
        return html `
            <div class="map-tile-settings">
                <div class="map-tile-server-group">
                    <div class="subheader"><or-translate value="configuration.global.mapTileServer"></or-translate></div>
                    <span>
                        <or-translate value="configuration.global.mapTileServerDescription"></or-translate><br>
                        <or-translate class="note" value="configuration.global.mapTileServerNote"></or-translate>
                    </span>
                    <or-mwc-input class="input"
                        .value="${isCustom ? (_e = (_d = (_c = this.config.sources) === null || _c === void 0 ? void 0 : _c.vector_tiles) === null || _d === void 0 ? void 0 : _d.tiles) === null || _e === void 0 ? void 0 : _e[0] : undefined}"
                        .type="${InputType.URL}"
                        .label="${i18next.t("configuration.global.mapTileServerPlaceholder")}"
                        placeholder="https://api.example.com/tileset/{z}/{x}/{y}"
                        @or-mwc-input-changed="${(e) => {
            this.config.sources.vector_tiles.tiles = e.detail.value ? [e.detail.value] : undefined;
            this.config.sources.vector_tiles.custom = !!e.detail.value;
            this.notifyConfigChange(this.config);
        }}"
                    ></or-mwc-input>
                </div>
                <div class="map-tile-upload-group">
                    <div class="subheader"><or-translate value="configuration.global.mapTiles"></or-translate></div>
                    <span>
                        <or-translate value="configuration.global.uploadMapTiles"></or-translate><br>
                        <or-translate class="note" value="configuration.global.uploadMapTilesNote"
                            .options=${{ limit: this.humanReadableBytes(this.limit) }}
                        ></or-translate>
                    </span>
                    <div class="input d-inline-flex" style="height: 56px">
                        <div id="fileupload" style="display: flex; align-items: center">
                            <or-mwc-input outlined label="selectFile" style="width: fit-content; padding-right: 12px;" .type="${InputType.BUTTON}" @or-mwc-input-changed="${() => this.shadowRoot.getElementById('fileupload-elem').click()}">
                                <input id="fileupload-elem" name="configfile" type="file" accept=".mbtiles" @change="${this.notifyMapFileChange}"/>
                            </or-mwc-input>
                            <or-mwc-input id="filename-elem" style="width: unset" .value="${this.filename}" .label="${i18next.t("file")}" .type="${InputType.TEXT}" disabled>
                            </or-mwc-input>
                            ${when(this.filename, () => html `<or-mwc-input type="${InputType.BUTTON}" iconColor="black" icon="delete"
                                @or-mwc-input-changed="${this.notifyMapFileChange}"
                            ></or-mwc-input>`)}
                        </div>
                    </div>
                </div>
            </div>
            <div class="map-style-settings">
                <div class="map-style-server-group">
                    <span>
                        <div class="subheader"><or-translate value="configuration.global.mapStyleJsonUrl"></or-translate></div>
                        <or-translate value="configuration.global.mapStyleJsonUrlDescription"></or-translate><br>
                        <or-translate class="note" value="configuration.global.mapStyleJsonUrlNote"></or-translate>
                    </span>
                    <div style="display: flex; height: 56px; align-items: center">
                        <or-mwc-input class="input"
                            .value="${this.config.override}"
                            .type="${InputType.URL}"
                            .label="${i18next.t("configuration.global.mapStyleJsonUrlPlaceholder")}"
                            placeholder="https://api.example.com/tileset/style.json"
                            @or-mwc-input-changed="${(e) => {
            this.config.override = e.detail.value || undefined;
            this.notifyConfigChange(this.config);
            this.requestUpdate();
        }}"
                        ></or-mwc-input>
                    </div>
                </div>
                <div class="map-style-layers-group">
                    <span>
                        <div class="subheader"><or-translate value="configuration.global.mapLayers"></or-translate></div>
                        <or-translate value="configuration.global.mapImportStyle"></or-translate>
                        <or-translate class="note" value="configuration.global.mapImportStyleNote"></or-translate>
                    </span>
                    <div style="display: flex; gap: 12px; align-items: center">
                        <or-mwc-input class="input fit-content" type="button" outlined icon="import" 
                            .label="${i18next.t("configuration.global.import")}"
                            .disabled="${!this.config.override}" @or-mwc-input-changed="${this.importMapSettings}"
                        ></or-mwc-input>
                        <or-conf-json class="input fit-content hide-mobile" .heading="${i18next.t("configuration.global.mapLayers")}"
                            .config="${hasExternalSource ? this.config.layers.filter(({ id }) => !id.startsWith("or:")) : this.config.layers}"
                            @saveLocalConfig="${(ev) => {
            if (Array.isArray(ev.detail.value)) {
                if (hasExternalSource) {
                    // Set default layers
                    this.config.layers = this.config.layers.filter(({ id }) => id.startsWith("or:"));
                    // Push changed layers
                    this.config.layers.push(...ev.detail.value);
                }
                else {
                    this.config.layers = ev.detail.value;
                }
                this.notifyConfigChange(this.config);
                this.requestUpdate();
            }
        }}"
                        ></or-conf-json>
                        ${when(hasExternalSource, () => html `
                            <or-mwc-input class="input fit-content" outlined type="button" icon="undo"
                                .label="${i18next.t("configuration.global.reset")}"
                                @or-mwc-input-changed="${this.resetMapSettings}"
                            ></or-mwc-input>
                        `)}
                        </div>
                </div>
            </div>
        `;
    }
    notifyConfigChange(config) {
        this.dispatchEvent(new CustomEvent("change", { detail: config }));
    }
    notifyMapFileChange(e) {
        var _a, _b;
        const file = (_b = (_a = e.target) === null || _a === void 0 ? void 0 : _a.files) === null || _b === void 0 ? void 0 : _b[0];
        if (file) {
            if (file.size > this.limit) {
                showSnackbar(undefined, "configuration.global.uploadMapTilesError");
                return;
            }
            const filenameEl = this.shadowRoot.getElementById('filename-elem');
            if (filenameEl) {
                filenameEl.value = file.name;
            }
        }
        this.dispatchEvent(new CustomEvent("map-file-changed", { detail: file }));
    }
    resetMapSettings() {
        this.config.glyphs = undefined;
        this.config.sprite = undefined;
        this.config.sources = { vector_tiles: this.config.sources.vector_tiles };
        this.config.layers = this.config.layers
            .filter(({ id }) => id.startsWith("or:"))
            .map((_a) => {
            var { id } = _a, layer = __rest(_a, ["id"]);
            return (Object.assign(Object.assign({}, layer), { id: id.replace("or:", "") }));
        });
        this.notifyConfigChange(this.config);
        this.requestUpdate();
    }
    importMapSettings() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this.config.override) {
                const data = yield (yield fetch(this.config.override)).json();
                if (Object.keys(this.config.sources).length > 1) {
                    // Set default layers
                    this.config.layers = this.config.layers.filter(({ id }) => id.startsWith("or:"));
                    // Push new layers
                    this.config.layers.push(...data.layers);
                }
                else {
                    this.config.layers = this.config.layers.map((_a) => {
                        var { id } = _a, layer = __rest(_a, ["id"]);
                        return (Object.assign(Object.assign({}, layer), { id: "or:" + id }));
                    });
                    this.config.layers.push(...data.layers);
                }
                Object.assign(this.config.sources, data.sources);
                this.config.sprite = data.sprite;
                this.config.glyphs = data.glyphs;
                delete this.config.override;
                this.notifyConfigChange(this.config);
                this.requestUpdate();
            }
        });
    }
    humanReadableBytes(bytes) {
        const unit = ['bytes', 'kB', 'MB', 'GB', 'TB', 'PB'];
        const exponent = Math.floor(Math.log(bytes) / Math.log(1000));
        return (bytes / Math.pow(1000, exponent)).toFixed(2) + " " + unit[exponent];
    }
};
OrConfMapGlobal.styles = css `
        .subheader {
            padding: 10px 0 4px;
            font-weight: bolder;
        }

        .map-tile-settings {
            display: flex;
        }

        .map-tile-server-group {
            flex-direction: column;
            width: 50%;
        }

        .map-tile-upload-group {
            flex-direction: column;
            padding-left: 12px;
            width: 50%;
        }

        .map-style-settings {
            display: flex;
        }

        .map-style-server-group {
            flex-direction: column;
            width: 50%;
        }

        .map-style-layers-group {
            flex-direction: column;
            padding-left: 12px;
            width: 50%;
        }

        @media screen and (max-width: 768px) {
            .map-tile-server-group, .map-tile-upload-group,
            .map-style-server-group, .map-style-layers-group  {
                width: 100%;
                padding: unset;
            }
            .map-tile-settings, .map-style-settings {
                display: block;
            }
        }

        .input {
            width: 100%;
            max-width: 800px;
            padding: 10px 0;
        }

        .input or-mwc-input:not([icon]) {
            width: 80%;
        }

        .note {
            font-style: italic;
            color: rgba(0, 0, 0, 0.6);
        }

        or-file-uploader {
            width: 108px;
            height: 108px;
        }

        .d-inline-flex {
            display: inline-flex;
        }
        
        .fit-content {
            width: fit-content;
        }
    `;
__decorate([
    property()
], OrConfMapGlobal.prototype, "config", void 0);
__decorate([
    property()
], OrConfMapGlobal.prototype, "filename", void 0);
__decorate([
    property()
], OrConfMapGlobal.prototype, "limit", void 0);
OrConfMapGlobal = __decorate([
    customElement("or-conf-map-global")
], OrConfMapGlobal);
export { OrConfMapGlobal };
//# sourceMappingURL=or-conf-map-global.js.map