import { h } from '@stencil/core';
import { _t } from '../i18n/i18n';
export class AddressSearchBox {
    constructor() {
        this.hasFocus = false;
        this.hasValue = false;
        this.results = [];
        this.jobId = 'gl-address-search';
        this.limit = 10;
        this.maxZoom = 18;
        this.placeholder = _t('webmapgl.address-search.prompt');
        this.zoomPadding = 20;
    }
    async componentWillLoad() {
        this.parseBbox();
        this.geocodeCtrl = await this.lazyGeocodeCtrl.componentOnReady();
    }
    async handleGeocode(e) {
        if (e.detail.options.jobId === this.jobId)
            this.results = e.detail.response;
    }
    handleBodyClick() {
        this.hasFocus = false;
    }
    handleKey(e) {
        if (e.keyCode === 38)
            this.handleUp(e);
        if (e.keyCode === 40)
            this.handleDown(e);
    }
    handleDown(e) {
        let nextItem;
        if (document.activeElement.tagName === 'ION-ITEM') {
            this.unsetFocus();
            nextItem = document.activeElement.nextElementSibling;
        }
        if (!nextItem)
            nextItem = this.el.querySelector('ion-item');
        if (nextItem) {
            e.preventDefault();
            this.setFocus(nextItem);
        }
    }
    handleUp(e) {
        if (document.activeElement.tagName === 'ION-ITEM') {
            e.preventDefault();
            this.unsetFocus();
            let prevItem = document.activeElement.previousElementSibling;
            if (prevItem) {
                this.setFocus(prevItem);
            }
            else if (this.input) {
                this.input.querySelector('input').focus();
            }
        }
    }
    parseBbox() {
        this.bboxArray = (typeof this.bbox === 'string') ?
            this.bbox.split(',').map((c) => parseFloat(c)) : this.bbox;
    }
    setFocus(el) {
        let button = el.shadowRoot.querySelector('button');
        button.focus();
        button.style.color = '#3880ff';
    }
    unsetFocus() {
        let button = document.activeElement.shadowRoot.querySelector('button');
        button.style.color = null;
    }
    formatAddress(address) {
        let parts = [];
        if (address.name &&
            address.name != address.city)
            parts.push(address.name);
        if (address.street) {
            let part = address.street;
            if (address.housenumber)
                part = address.housenumber + ' ' + part;
            parts.push(part);
        }
        if (address.city)
            parts.push(address.city);
        if (!parts.length && address.county)
            parts.push(address.county);
        if (parts.length)
            return parts.join(', ');
        return address.display;
    }
    async selectResult(result) {
        let mapEl = this.el.closest('gl-map');
        mapEl.map.fitBounds(result.bbox, {
            maxZoom: this.maxZoom,
            padding: this.zoomPadding
        });
        this.hasFocus = false;
    }
    async geocode() {
        this.geocodeCtrl.forward({
            address: this.input.value,
            url: this.url,
            bbox: this.bboxArray,
            bounded: true,
            jobId: this.jobId,
            limit: this.limit
        });
    }
    renderResults() {
        if (!this.results.length || !this.hasValue || !this.hasFocus)
            return null;
        let items = this.results.map((result) => (h("ion-item", { button: true, onClick: () => this.selectResult(result) },
            h("ion-icon", { name: "pin", slot: "start" }),
            h("ion-label", null, this.formatAddress(result.address)))));
        return (h("ion-list", { lines: "full" }, items));
    }
    handleChange() {
        if (this.input && this.input.value) {
            this.hasValue = true;
            this.geocode();
        }
        else {
            this.hasValue = false;
            if (this.results.length)
                this.results = [];
        }
    }
    handleFocus() {
        this.hasFocus = true;
    }
    handleClick(e) {
        // Prevent propagation of click events from the searchbar so that
        // it does not lose focus.
        e.stopPropagation();
    }
    render() {
        return ([
            h("ion-searchbar", { ref: (r) => this.input = r, placeholder: this.placeholder, onIonChange: () => this.handleChange(), onIonFocus: () => this.handleFocus(), onClick: (e) => this.handleClick(e) }),
            this.renderResults()
        ]);
    }
    static get is() { return "gl-address-search"; }
    static get originalStyleUrls() { return {
        "ios": ["address-search.ios.css"],
        "md": ["address-search.md.css"]
    }; }
    static get styleUrls() { return {
        "ios": ["address-search.ios.css"],
        "md": ["address-search.md.css"]
    }; }
    static get properties() { return {
        "bbox": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "[number, number, number, number] | string",
                "resolved": "[number, number, number, number] | string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "bbox",
            "reflect": false
        },
        "jobId": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "job-id",
            "reflect": false,
            "defaultValue": "'gl-address-search'"
        },
        "limit": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "limit",
            "reflect": false,
            "defaultValue": "10"
        },
        "maxZoom": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "max-zoom",
            "reflect": false,
            "defaultValue": "18"
        },
        "placeholder": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "placeholder",
            "reflect": false,
            "defaultValue": "_t('webmapgl.address-search.prompt')"
        },
        "url": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "url",
            "reflect": false
        },
        "zoomPadding": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "zoom-padding",
            "reflect": false,
            "defaultValue": "20"
        }
    }; }
    static get connectProps() { return [{
            "name": "lazyGeocodeCtrl",
            "connect": "gl-geocode-controller"
        }]; }
    static get states() { return {
        "bboxArray": {},
        "hasFocus": {},
        "hasValue": {},
        "results": {}
    }; }
    static get elementRef() { return "el"; }
    static get watchers() { return [{
            "propName": "bbox",
            "methodName": "parseBbox"
        }]; }
    static get listeners() { return [{
            "name": "glForwardGeocode",
            "method": "handleGeocode",
            "target": "body",
            "capture": false,
            "passive": false
        }, {
            "name": "click",
            "method": "handleBodyClick",
            "target": "body",
            "capture": false,
            "passive": false
        }, {
            "name": "keydown",
            "method": "handleKey",
            "target": undefined,
            "capture": false,
            "passive": false
        }]; }
}
