<template>
    <div style="position: relative">
        <!-- <Map className="h-36" :center="state.center" :zoom="state.zoom"> // map component content </Map> -->
        <div :id="mapId" class="map-container mapDesktop rounded">
            <ZoomControlComponent :mapId="mapId"></ZoomControlComponent>
            <DrawControlComponent :mapId="mapId"></DrawControlComponent>
        </div>
    </div>
</template>

<script lang="ts">
import { EventEmitter } from './EventEmitter';
import { Component, Vue, Prop } from 'vue-facing-decorator';
// import type { Coverage } from '@/Dataset';
// import { Map, Control, MapOptions, LatLngBoundsExpression, tileLayer, latLng, latLngBounds, FeatureGroup } from 'leaflet';
import { Map } from 'leaflet/src/map/index';
import { Control } from 'leaflet/src/control/Control';
import { LatLngBoundsExpression, toLatLngBounds } from 'leaflet/src/geo/LatLngBounds';
import { toLatLng } from 'leaflet/src/geo/LatLng';
import { tileLayerWMS } from 'leaflet/src/layer/tile/TileLayer.WMS';
import { Attribution } from 'leaflet/src/control/Control.Attribution';
// import { Attribution } from 'leaflet';
// import { FeatureGroup } from 'leaflet/src/layer/FeatureGroup';

import { MapOptions } from './MapOptions';
import { LayerOptions, LayerMap } from './LayerOptions';
import { MapService } from '@/Stores/map.service';
import ZoomControlComponent from './zoom.component.vue';
import DrawControlComponent from './draw.component.vue';

const DEFAULT_BASE_LAYER_NAME = 'BaseLayer';
// const DEFAULT_BASE_LAYER_URL = 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png';
const DEFAULT_BASE_LAYER_ATTRIBUTION = '&copy; <a target="_blank" href="http://osm.org/copyright">OpenStreetMap</a> contributors';

@Component({
    name: 'MapComponent',
    components: {
        ZoomControlComponent,
        DrawControlComponent
    },
})
export default class MapComponent extends Vue {
    /**
     * A map with the given ID is created inside this component.
     * This ID can be used the get the map instance over the map cache service.
     */
    @Prop()
    public mapId: string;

    /**
     * The corresponding leaflet map options (see: https://leafletjs.com/reference-1.3.4.html#map-option)
     */
    @Prop()
    public mapOptions: MapOptions;

    // markerService: MarkerService
    /**
     * Bounds for the map
     */
    @Prop({ default: null })
    public fitBounds: LatLngBoundsExpression;

    /**
     * Describes the the zoom control options (see: https://leafletjs.com/reference-1.3.4.html#control-zoom)
     */
    @Prop()
    public zoomControlOptions: Control.ZoomOptions;

    @Prop()
    public baseMaps: LayerMap;

    mapService = MapService();

    /**
     * Informs when initialization is done with map id.
     */
    public onMapInitializedEvent: EventEmitter<string> = new EventEmitter<string>();

    protected map!: Map;
    // protected drawnItems!: FeatureGroup<any>;

    // @Prop({ type: Object })
    // geolocation: Coverage;

    mounted(): void {
        this.initMap();
    }

    public deleteTest(): void {
        this.onMapInitializedEvent.emit(this.mapId);
    }

    // @Emit(this.onMapInitializedEvent)
    protected initMap(): void {
        let map: Map = (this.map = new Map(this.mapId, this.mapOptions));
        this.mapService.setMap(this.mapId, map);
        map.scrollWheelZoom.disable();

        // return this.mapId;
        //    this.$emit("onMapInitializedEvent", this.mapId);
        this.onMapInitializedEvent.emit(this.mapId);
        this.addBaseMap();

        // if (this.fitBounds) {
        //     this.map.fitBounds(this.fitBounds);
        // }
        const southWest = toLatLng(46.5, 9.9);
        const northEast = toLatLng(48.9, 16.9);
        const bounds = toLatLngBounds(southWest, northEast);
        map.fitBounds(bounds);

        const attributionControl = new Attribution().addTo(this.map);
        attributionControl.setPrefix(false);

        // Initialise the FeatureGroup to store editable layers
        // let drawnItems = (this.drawnItems = new FeatureGroup());
        // map.addLayer(drawnItems);
    }

    private addBaseMap(layerOptions?: LayerOptions): void {
        if (this.map) {
            if (!this.baseMaps || this.baseMaps.size === 0) {
                // let bmapgrau = tileLayer('https://{s}.wien.gv.at/basemap/bmapgrau/normal/google3857/{z}/{y}/{x}.png', {
                //         subdomains: ['maps', 'maps1', 'maps2', 'maps3', 'maps4'],
                //         attribution: 'Datenquelle: <a href="http://www.basemap.at/">basemap.at</a>',
                // });
                let osmGgray = tileLayerWMS('https://ows.terrestris.de/osm-gray/service', {
                    format: 'image/png',
                    attribution: DEFAULT_BASE_LAYER_ATTRIBUTION,
                    layers: 'OSM-WMS',
                });
                layerOptions = {
                    label: DEFAULT_BASE_LAYER_NAME,
                    visible: true,
                    layer: osmGgray,
                };
                layerOptions.layer.addTo(this.map);
            }
        }
    }
}
</script>

<style lang="css">
.leaflet-container {
    height: 600px; /* <-- map height */
    width: 100%;
}
</style>
