import { getAbsoluteUrl } from '../utils';
export class Map {
    constructor() {
        this.drawing = false;
        this.zoom = 10;
        this.minzoom = 0;
        this.maxzoom = 22;
    }
    componentWillLoad() {
        this._style = this.loadStyle();
        this.map = new mapboxgl.Map({
            container: this.el,
            center: [this.longitude, this.latitude],
            zoom: this.zoom,
            minZoom: this.minzoom,
            maxZoom: this.maxzoom,
            style: this._style
        });
        window.addEventListener('resize', this.resizeMap.bind(this));
        this.map.on('draw.create', (e) => this.glDrawCreate.emit({
            mapId: this.el.id,
            features: e.features
        }));
        this.map.on('draw.delete', (e) => this.glDrawDelete.emit({
            mapId: this.el.id,
            features: e.features
        }));
    }
    componentDidUpdate() {
        this.resizeMap();
    }
    async updateStyle() {
        if (this._updateStyleTimeout)
            return;
        this._updateStyleTimeout = window.setTimeout(async () => {
            this._updateStyleTimeout = null;
            this._style = await this.loadStyle();
            this.map.setStyle(this._style);
            this.glStyleUpdated.emit(this._style);
        }, 66);
    }
    async handleStyleAdded() {
        this.updateStyle();
    }
    async handleStyleModified() {
        this.updateStyle();
    }
    async handleStyleRemoved() {
        this.updateStyle();
    }
    async updateDrawing() {
        if (this.drawing) {
            this.draw = new MapboxDraw(this.drawOptions);
            this.map.addControl(this.draw);
            this.glDrawEnter.emit({
                mapId: this.el.id
            });
        }
        else {
            this.map.removeControl(this.draw);
            this.draw = null;
            this.glDrawExit.emit({
                mapId: this.el.id
            });
        }
    }
    async resizeMap() {
        if (this._resizeMapTimeout)
            return;
        this._resizeMapTimeout = window.setTimeout(async () => {
            this._resizeMapTimeout = null;
            if (this.map)
                this.map.resize();
        }, 66);
    }
    getStyleLayers(styleId, json) {
        if (!json.layers)
            return [];
        let results = [];
        for (let layer of json.layers) {
            let result = Object.assign({}, layer, { id: this.prefix(styleId, layer.id) });
            if (layer.source)
                result.source = this.prefix(styleId, layer.source);
            results.push(result);
        }
        return results;
    }
    getStyleSources(styleId, json) {
        if (!json.sources)
            return [];
        let sources = {};
        for (let sourceName in json.sources)
            sources[this.prefix(styleId, sourceName)] = json.sources[sourceName];
        return sources;
    }
    loadStyle() {
        let style = {
            version: 8,
            metadata: {},
            sources: {},
            layers: []
        };
        if (this.glyphs)
            style.glyphs = this.glyphs;
        if (this.sprite)
            style.sprite = this.sprite;
        Array.from(this.el.querySelectorAll('gl-style')).forEach((styleEl) => {
            if (!styleEl.enabled)
                return;
            let id = styleEl.id;
            let json = styleEl.json;
            if (!json)
                return;
            style.layers = this.getStyleLayers(id, json).concat(style.layers);
            style.sources = Object.assign({}, style.sources, this.getStyleSources(id, json));
            // TODO: Deal with multiple styles that each have their own glyphs
            // or sprites. For now, we use the explicitly set URL on gl-map,
            // or fall back to the first URL found in the child styles. See:
            // https://github.com/mapbox/mapbox-gl-js/issues/4086
            // https://github.com/mapbox/mapbox-gl-js/issues/4000
            if (json.glyphs && !style.glyphs)
                style.glyphs = json.glyphs;
            if (json.sprite && !style.sprite)
                style.sprite = json.sprite;
        });
        if (style.glyphs)
            style.glyphs = getAbsoluteUrl(style.glyphs)
                .replace('%7Bfontstack%7D', '{fontstack}')
                .replace('%7Brange%7D', '{range}');
        if (style.sprite)
            style.sprite = getAbsoluteUrl(style.sprite);
        return style;
    }
    prefix(styleId, value) {
        return `${styleId}:${value}`;
    }
    static get is() { return "gl-map"; }
    static get originalStyleUrls() { return {
        "$": ["map.css"]
    }; }
    static get styleUrls() { return {
        "$": ["map.css"]
    }; }
    static get properties() { return {
        "draw": {
            "type": "any",
            "mutable": true,
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "draw",
            "reflect": false
        },
        "drawOptions": {
            "type": "any",
            "mutable": false,
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            },
            "required": false,
            "optional": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "draw-options",
            "reflect": false
        },
        "drawing": {
            "type": "boolean",
            "mutable": false,
            "complexType": {
                "original": "boolean",
                "resolved": "boolean",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "drawing",
            "reflect": false,
            "defaultValue": "false"
        },
        "glyphs": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "glyphs",
            "reflect": false
        },
        "latitude": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "latitude",
            "reflect": false
        },
        "longitude": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "longitude",
            "reflect": false
        },
        "zoom": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "zoom",
            "reflect": false,
            "defaultValue": "10"
        },
        "minzoom": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "minzoom",
            "reflect": false,
            "defaultValue": "0"
        },
        "maxzoom": {
            "type": "number",
            "mutable": false,
            "complexType": {
                "original": "number",
                "resolved": "number",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "maxzoom",
            "reflect": false,
            "defaultValue": "22"
        },
        "sprite": {
            "type": "string",
            "mutable": false,
            "complexType": {
                "original": "string",
                "resolved": "string",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "sprite",
            "reflect": false
        },
        "map": {
            "type": "any",
            "mutable": true,
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            },
            "required": false,
            "optional": false,
            "docs": {
                "tags": [],
                "text": ""
            },
            "attribute": "map",
            "reflect": false
        }
    }; }
    static get events() { return [{
            "method": "glDrawCreate",
            "name": "glDrawCreate",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            }
        }, {
            "method": "glDrawDelete",
            "name": "glDrawDelete",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            }
        }, {
            "method": "glDrawEnter",
            "name": "glDrawEnter",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            }
        }, {
            "method": "glDrawExit",
            "name": "glDrawExit",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            }
        }, {
            "method": "glStyleUpdated",
            "name": "glStyleUpdated",
            "bubbles": true,
            "cancelable": true,
            "composed": true,
            "docs": {
                "tags": [],
                "text": ""
            },
            "complexType": {
                "original": "any",
                "resolved": "any",
                "references": {}
            }
        }]; }
    static get methods() { return {
        "resizeMap": {
            "complexType": {
                "signature": "() => Promise<void>",
                "parameters": [],
                "references": {
                    "Promise": {
                        "location": "global"
                    }
                },
                "return": "Promise<void>"
            },
            "docs": {
                "text": "",
                "tags": []
            }
        }
    }; }
    static get elementRef() { return "el"; }
    static get watchers() { return [{
            "propName": "drawing",
            "methodName": "updateDrawing"
        }]; }
    static get listeners() { return [{
            "name": "glStyleElementAdded",
            "method": "handleStyleAdded",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "glStyleElementModified",
            "method": "handleStyleModified",
            "target": undefined,
            "capture": false,
            "passive": false
        }, {
            "name": "glStyleElementRemoved",
            "method": "handleStyleRemoved",
            "target": undefined,
            "capture": false,
            "passive": false
        }]; }
}
