import pointOnFeature from "@turf/point-on-feature";
import { featureCollection as makeFeatureCollection } from "@turf/helpers";
import { toArray } from "../utils";
import { Popup as MaplibrePopup } from "maplibre-gl";
const openPopups = [];
export class Popup {
  constructor() {
    this.clickEventDelay = 50;
    this.closeKey = "Escape";
    this.closeMode = "self";
    this.component = undefined;
    this.componentOptions = undefined;
    this.layers = undefined;
    this.maxWidth = "none";
  }
  componentWillLoad() {
    this.parseLayersString();
  }
  getOptions() {
    if (typeof this.componentOptions === "string") {
      return JSON.parse(this.componentOptions);
    }
    return this.componentOptions || {};
  }
  doOpenPopup(e) {
    let features = e.detail.features.filter((feature) => {
      let [styleId, layerId] = feature.layer.id.split(":");
      return (this._layers.indexOf(layerId) != -1 &&
        this.el.closest("gl-style").id === styleId);
    });
    if (features.length)
      this.openPopup(features);
  }
  handleKeyup(e) {
    if (e.key === this.closeKey)
      this.removePopup();
  }
  /**
   * Returns a boolean indicating whether the popup is currently open.
   */
  async isOpen() {
    return this.popup != undefined ? this.popup.isOpen() : false;
  }
  /**
   * Removes the popup from the map.
   */
  async removePopup() {
    if (this.popup != undefined) {
      this.popup.remove();
      let popupIdx = openPopups.indexOf(this.popup);
      if (popupIdx > -1)
        openPopups.splice(popupIdx, 1);
      this.popup = null;
    }
  }
  removeAll() {
    while (openPopups.length > 0)
      openPopups.pop().remove();
    this.popup = null;
  }
  async openPopup(features) {
    let featureCollection = makeFeatureCollection(features);
    let point = pointOnFeature(featureCollection);
    let component = document.createElement(this.component);
    component["features"] = features;
    let options = this.getOptions();
    for (let propName in this.getOptions())
      component[propName] = options[propName];
    if (this.closeMode === "self")
      await this.removePopup();
    if (this.closeMode === "all")
      this.removeAll();
    this.popup = new MaplibrePopup({ maxWidth: this.maxWidth })
      .setLngLat(point.geometry.coordinates)
      .setDOMContent(component)
      .addTo(this.el.closest("gl-map").map);
    openPopups.push(this.popup);
  }
  parseLayersString() {
    if (typeof this.layers === "string") {
      this._layers = toArray(this.layers);
    }
    else {
      this._layers = this.layers;
    }
  }
  static get is() { return "gl-popup"; }
  static get originalStyleUrls() {
    return {
      "$": ["popup.css"]
    };
  }
  static get styleUrls() {
    return {
      "$": ["popup.css"]
    };
  }
  static get properties() {
    return {
      "clickEventDelay": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Milliseconds to wait before opening the popup. This delay allows for\nhandling multiple feature click events in a single popup. Multiple events\ncan be fired in quick succession when the user clicks on multiple\noverlapping features."
        },
        "attribute": "click-event-delay",
        "reflect": false,
        "defaultValue": "50"
      },
      "closeKey": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Key code of the key used to close the popup. By default, it is the `Esc`\nkey."
        },
        "attribute": "close-key",
        "reflect": false,
        "defaultValue": "\"Escape\""
      },
      "closeMode": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "\"none\" | \"self\" | \"all\"",
          "resolved": "\"all\" | \"none\" | \"self\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Which popups to close when a new popup is opened. `self` removes popups\nopened by this `gl-popup` element, and `all` closes all open popups."
        },
        "attribute": "close-mode",
        "reflect": false,
        "defaultValue": "\"self\""
      },
      "component": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Name of the component containing the content for the popup\n(e.g., `gl-attribute-values`). If the popup content is dynamic, the\ncomponent should accept a `features` property, which will be set to the\nGeoJSON features clicked by the user."
        },
        "attribute": "component",
        "reflect": false
      },
      "componentOptions": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string | { [key: string]: any }",
          "resolved": "string | { [key: string]: any; }",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Additional options, which are passed to the content component as\nproperties."
        },
        "attribute": "component-options",
        "reflect": false
      },
      "layers": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string[] | string",
          "resolved": "string | string[]",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "IDs of the layers that can activate this popup when clicked. These\nlayer IDs should also be included in the `clickableLayers` property of\nthe parent style."
        },
        "attribute": "layers",
        "reflect": false
      },
      "maxWidth": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Maximum width of the popup element. It can be any valid CSS width value."
        },
        "attribute": "max-width",
        "reflect": false,
        "defaultValue": "\"none\""
      }
    };
  }
  static get methods() {
    return {
      "isOpen": {
        "complexType": {
          "signature": "() => Promise<boolean>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global",
              "id": "global::Promise"
            }
          },
          "return": "Promise<boolean>"
        },
        "docs": {
          "text": "Returns a boolean indicating whether the popup is currently open.",
          "tags": []
        }
      },
      "removePopup": {
        "complexType": {
          "signature": "() => Promise<void>",
          "parameters": [],
          "references": {
            "Promise": {
              "location": "global",
              "id": "global::Promise"
            }
          },
          "return": "Promise<void>"
        },
        "docs": {
          "text": "Removes the popup from the map.",
          "tags": []
        }
      }
    };
  }
  static get elementRef() { return "el"; }
  static get watchers() {
    return [{
        "propName": "layers",
        "methodName": "parseLayersString"
      }];
  }
  static get listeners() {
    return [{
        "name": "glClickedFeaturesGathered",
        "method": "doOpenPopup",
        "target": "body",
        "capture": false,
        "passive": false
      }, {
        "name": "keyup",
        "method": "handleKeyup",
        "target": "body",
        "capture": false,
        "passive": false
      }];
  }
}
//# sourceMappingURL=popup.js.map
