import { h, Host } from "@stencil/core";
import { _t } from "../i18n/i18n";
import { getMap } from "../utils";
export class FeatureList {
  constructor() {
    this.data = undefined;
    this.limit = undefined;
    this.batchSize = 20;
    this.component = undefined;
    this.componentOptions = undefined;
    this.display = "visible";
    this.features = [];
    this.item = true;
    this.loadingSpinner = "bubbles";
    this.loadingText = _t("webmapgl.feature-list.loading");
    this.mapId = undefined;
    this.orderBy = undefined;
    this.order = "asc";
    this.styleId = undefined;
    this.sourceId = undefined;
  }
  async componentWillLoad() {
    await this.handleSourceId();
  }
  componentDidLoad() {
    const map = getMap(this.mapId).map;
    if (map != undefined)
      map.on("moveend", async () => await this.filter());
  }
  handleInfiniteScroll(e) {
    this.limit += this.batchSize;
    e.target.complete();
  }
  handleStyleUpdated(e) {
    if (e.detail.id === this.styleId)
      this.handleSourceId();
  }
  async handleSourceId() {
    const style = document.querySelector(`#${this.styleId}`);
    if (style == undefined || style.json.sources == undefined)
      return;
    const data = style.json.sources[this.sourceId].data;
    if (typeof data === "string") {
      let res = await fetch(data);
      this.data = (await res.json());
    }
    else {
      this.data = data;
    }
    this.filter();
  }
  async filter() {
    var _a;
    if (((_a = this.data) === null || _a === void 0 ? void 0 : _a.features) == undefined || this.data.features.length === 0)
      return;
    let features;
    if (this.display === "all") {
      features = this.data.features;
    }
    else {
      let bounds = getMap(this.mapId).map.getBounds();
      features = this.data.features.filter((feature) => {
        let [lng, lat] = feature.geometry.coordinates;
        return (lng >= bounds.getWest() &&
          lng <= bounds.getEast() &&
          lat >= bounds.getSouth() &&
          lat <= bounds.getNorth());
      });
    }
    this.limit = this.batchSize;
    this.features = this.sort(features);
  }
  sort(features) {
    if (this.order === "none" || this.orderBy == undefined)
      return features;
    features.sort((aFeature, bFeature) => {
      const a = aFeature.properties[this.orderBy];
      const b = bFeature.properties[this.orderBy];
      if (a < b)
        return this.order === "asc" ? -1 : 1;
      if (a > b)
        return this.order === "asc" ? 1 : -1;
      return 0;
    });
    return features;
  }
  render() {
    let ComponentTag = this.component;
    let features = this.limit !== 0 ? this.features.slice(0, this.limit) : this.features;
    let hasMore = features.length < this.features.length;
    let items = features.map((feature) => {
      let component = (h(ComponentTag, Object.assign({ feature: feature }, this.componentOptions)));
      return this.item ? h("ion-item", null, component) : component;
    });
    return (h(Host, null, h("ion-list", null, h("slot", { name: "start" }), items, h("slot", { name: "end" })), h("ion-infinite-scroll", { disabled: !hasMore }, h("ion-infinite-scroll-content", { "loading-spinner": this.loadingSpinner, "loading-text": this.loadingText }))));
  }
  static get is() { return "gl-feature-list"; }
  static get properties() {
    return {
      "batchSize": {
        "type": "number",
        "mutable": false,
        "complexType": {
          "original": "number",
          "resolved": "number",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "The number of features to render in each batch. Additional batches\nare added as needed using `ion-infinite-scroll`."
        },
        "attribute": "batch-size",
        "reflect": false,
        "defaultValue": "20"
      },
      "component": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "The component used to render the features in the list."
        },
        "attribute": "component",
        "reflect": false
      },
      "componentOptions": {
        "type": "unknown",
        "mutable": false,
        "complexType": {
          "original": "{ [key: string]: any }",
          "resolved": "{ [key: string]: any; }",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Options passed to the component as properties."
        }
      },
      "display": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "\"all\" | \"visible\"",
          "resolved": "\"all\" | \"visible\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Which features to display: all features from the source, or just those\ncurrently within the map extent."
        },
        "attribute": "display",
        "reflect": false,
        "defaultValue": "\"visible\""
      },
      "features": {
        "type": "unknown",
        "mutable": true,
        "complexType": {
          "original": "Array<Feature<limitedGeometry>>",
          "resolved": "Feature<limitedGeometry, { [name: string]: any; }>[]",
          "references": {
            "Array": {
              "location": "global",
              "id": "global::Array"
            },
            "Feature": {
              "location": "import",
              "path": "geojson",
              "id": ""
            },
            "limitedGeometry": {
              "location": "local",
              "path": "/var/home/fj44404@co.champaign.il.us/.local/code/webmapgl/src/components/feature-list/feature-list.tsx",
              "id": "src/components/feature-list/feature-list.tsx::limitedGeometry"
            }
          }
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "An array of GeoJSON features to display. Currently only point features\nare supported."
        },
        "defaultValue": "[]"
      },
      "item": {
        "type": "boolean",
        "mutable": false,
        "complexType": {
          "original": "boolean",
          "resolved": "boolean",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Wrap the component in an `ion-item`."
        },
        "attribute": "item",
        "reflect": false,
        "defaultValue": "true"
      },
      "loadingSpinner": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "The type of spinner used in the `ion-infinite-scroll-content`."
        },
        "attribute": "loading-spinner",
        "reflect": false,
        "defaultValue": "\"bubbles\""
      },
      "loadingText": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Text to display while features are loading in the\n`ion-infinite-scroll-content`."
        },
        "attribute": "loading-text",
        "reflect": false,
        "defaultValue": "_t(\"webmapgl.feature-list.loading\")"
      },
      "mapId": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "ID of the `gl-map`."
        },
        "attribute": "map-id",
        "reflect": false
      },
      "orderBy": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Property by which features should be sorted."
        },
        "attribute": "order-by",
        "reflect": false
      },
      "order": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "\"asc\" | \"desc\" | \"none\"",
          "resolved": "\"asc\" | \"desc\" | \"none\"",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "Order in which to sort features."
        },
        "attribute": "order",
        "reflect": false,
        "defaultValue": "\"asc\""
      },
      "styleId": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "ID of the `gl-style` element containing the feature source."
        },
        "attribute": "style-id",
        "reflect": false
      },
      "sourceId": {
        "type": "string",
        "mutable": false,
        "complexType": {
          "original": "string",
          "resolved": "string",
          "references": {}
        },
        "required": false,
        "optional": false,
        "docs": {
          "tags": [],
          "text": "ID of the source containing the features."
        },
        "attribute": "source-id",
        "reflect": false
      }
    };
  }
  static get states() {
    return {
      "data": {},
      "limit": {}
    };
  }
  static get watchers() {
    return [{
        "propName": "styleId",
        "methodName": "handleSourceId"
      }, {
        "propName": "sourceId",
        "methodName": "handleSourceId"
      }];
  }
  static get listeners() {
    return [{
        "name": "ionInfinite",
        "method": "handleInfiniteScroll",
        "target": undefined,
        "capture": false,
        "passive": false
      }, {
        "name": "glStyleElementModified",
        "method": "handleStyleUpdated",
        "target": "body",
        "capture": false,
        "passive": false
      }];
  }
}
//# sourceMappingURL=feature-list.js.map
