import { toArray } from "../utils";
let _nextId = 0;
export class Style {
  constructor() {
    this.handlers = {
      click: (e) => this.handleClick(e),
      mouseenter: () => this.handleMouseenter(),
      mouseleave: () => this.handleMouseleave(),
    };
    this.basemap = false;
    this.clickableLayers = [];
    this.enabled = true;
    this.name = undefined;
    this.thumbnail = undefined;
    this.token = undefined;
    this.url = undefined;
    this.json = {
      version: 8,
      sources: undefined,
      layers: undefined,
    };
    this.insertIntoStyle = undefined;
    this.insertBeneathLayer = undefined;
  }
  componentWillLoad() {
    if (this.el.id == undefined) {
      this.el.id = "style-" + _nextId.toString();
      _nextId += 1;
    }
    if (this.url != undefined)
      this.fetchJSON();
  }
  componentDidLoad() {
    if (this.clickableLayers != undefined && this.clickableLayers.length !== 0)
      this.updateClickable(this.clickableLayers);
    this.glStyleElementAdded.emit(this.eventDetail());
  }
  componentDidUpdate() {
    this.glStyleElementModified.emit(this.eventDetail());
  }
  disconnectedCallback() {
    this.glStyleElementRemoved.emit(this.eventDetail());
  }
  eventDetail() {
    return {
      id: this.el.id,
      style: this,
    };
  }
  getMap() {
    return this.el.closest("gl-map").map;
  }
  async fetchJSON() {
    let res = await fetch(this.url);
    this.json = (await res.json());
    if (this.token && this.json.sources != undefined) {
      for (let srcName in this.json.sources) {
        let src = this.json.sources[srcName];
        if (src.data != undefined)
          src.data = src.data.replace(/\$\{TOKEN\}/g, this.token);
      }
    }
  }
  updateClickable(newLayers, oldLayers) {
    const map = this.getMap();
    newLayers = toArray(newLayers);
    oldLayers = toArray(oldLayers);
    for (let layer of newLayers) {
      const layerIdx = oldLayers.indexOf(layer);
      if (layerIdx === -1) {
        let layerName = `${this.el.id}:${layer}`;
        map.on("click", layerName, this.handlers.click);
        map.on("mouseenter", layerName, this.handlers.mouseenter);
        map.on("mouseleave", layerName, this.handlers.mouseleave);
      }
      else {
        oldLayers.splice(layerIdx, 1);
      }
    }
    for (let layer of oldLayers) {
      let layerName = `${this.el.id}:${layer}`;
      map.off("click", layerName, this.handlers.click);
      map.off("mouseenter", layerName, this.handlers.mouseenter);
      map.off("mouseleave", layerName, this.handlers.mouseleave);
    }
  }
  handleClick(e) {
    this.glFeatureClick.emit({ features: e.features });
  }
  handleMouseenter() {
    this.getMap().getCanvas().style.cursor = "pointer";
  }
  handleMouseleave() {
    this.getMap().getCanvas().style.cursor = "";
  }
  static get is() { return "gl-style"; }
  static get properties() {
    return {
      "basemap": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "This style represents a basemap and should be included in\n`gl-basemap-switcher`."
        },
        "attribute": "basemap",
        "reflect": false,
        "defaultValue": "false"
      },
      "clickableLayers": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string | string[]",
          "resolved": "string | string[]",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Array of layers that should be clickable."
        },
        "attribute": "clickable-layers",
        "reflect": false,
        "defaultValue": "[]"
      },
      "enabled": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Include this style in the combined style for the parent `gl-map`."
        },
        "attribute": "enabled",
        "reflect": false,
        "defaultValue": "true"
      },
      "name": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Human readable name. It is used by `gl-basemap-switcher`."
        },
        "attribute": "name",
        "reflect": false
      },
      "thumbnail": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "URL of the thumbnail image. It is used by `gl-basemap-switcher`."
        },
        "attribute": "thumbnail",
        "reflect": false
      },
      "token": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Access token for sources GeoJSON sources. If set, it is used to replace\nthe `${TOKEN}` placeholder in the style's `data` property."
        },
        "attribute": "token",
        "reflect": false
      },
      "url": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "URL of the style JSON."
        },
        "attribute": "url",
        "reflect": false
      },
      "json": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "StyleSpecification",
          "resolved": "{ version: 8; name?: string; metadata?: unknown; center?: number[]; zoom?: number; bearing?: number; pitch?: number; light?: LightSpecification; terrain?: TerrainSpecification; sources: { [_: string]: SourceSpecification; }; sprite?: SpriteSpecification; glyphs?: string; transition?: TransitionSpecification; layers: LayerSpecification[]; }",
          "references": {
            "StyleSpecification": {
              "location": "import",
              "path": "maplibre-gl",
              "id": ""
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Style JSON object. If `url` is set, it is loaded from that URL."
        },
        "defaultValue": "{\n    version: 8,\n    sources: undefined,\n    layers: undefined,\n  }"
      },
      "insertIntoStyle": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "ID of the style in which to insert this style's layers\nNote: The style you are inserting into must precede this style in the DOM."
        },
        "attribute": "insert-into-style",
        "reflect": false
      },
      "insertBeneathLayer": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": true,
        "docs": {
          "tags": [],
          "text": "Name of the specific layer under which to insert this style's layers."
        },
        "attribute": "insert-beneath-layer",
        "reflect": false
      }
    };
  }
  static get events() {
    return [{
        "method": "glFeatureClick",
        "name": "glFeatureClick",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitted when a feature is clicked. Only features in layers listed in\n`clickableLayers` trigger this event when clicked."
        },
        "complexType": {
          "original": "{\n    features: MapGeoJSONFeature[];\n  }",
          "resolved": "{ features: MapGeoJSONFeature[]; }",
          "references": {
            "MapGeoJSONFeature": {
              "location": "import",
              "path": "maplibre-gl",
              "id": ""
            }
          }
        }
      }, {
        "method": "glStyleElementAdded",
        "name": "glStyleElementAdded",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitted when a style component is initialized."
        },
        "complexType": {
          "original": "styleEvent",
          "resolved": "styleEvent",
          "references": {
            "styleEvent": {
              "location": "local",
              "path": "/var/home/fj44404@co.champaign.il.us/.local/code/webmapgl/src/components/style/style.tsx",
              "id": "src/components/style/style.tsx::styleEvent"
            }
          }
        }
      }, {
        "method": "glStyleElementModified",
        "name": "glStyleElementModified",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitted when the style JSON changes."
        },
        "complexType": {
          "original": "styleEvent",
          "resolved": "styleEvent",
          "references": {
            "styleEvent": {
              "location": "local",
              "path": "/var/home/fj44404@co.champaign.il.us/.local/code/webmapgl/src/components/style/style.tsx",
              "id": "src/components/style/style.tsx::styleEvent"
            }
          }
        }
      }, {
        "method": "glStyleElementRemoved",
        "name": "glStyleElementRemoved",
        "bubbles": true,
        "cancelable": true,
        "composed": true,
        "docs": {
          "tags": [],
          "text": "Emitted when a style component unloads."
        },
        "complexType": {
          "original": "styleEvent",
          "resolved": "styleEvent",
          "references": {
            "styleEvent": {
              "location": "local",
              "path": "/var/home/fj44404@co.champaign.il.us/.local/code/webmapgl/src/components/style/style.tsx",
              "id": "src/components/style/style.tsx::styleEvent"
            }
          }
        }
      }];
  }
  static get elementRef() { return "el"; }
  static get watchers() {
    return [{
        "propName": "clickableLayers",
        "methodName": "updateClickable"
      }];
  }
}
//# sourceMappingURL=style.js.map
