<template>
    <div ref="drawControl" class="gba-control-draw btn-group-vertical map-control">
        <!-- <button type="button" class="button is-light is-small" (click)="locateUser()" [ngClass]="isToggled ? 'is-primary': 'is-active'">
      <fa-icon [icon]="faSearchLocation"></fa-icon>
    </button> -->
        <!--  -->
        <button
            ref="inputDraw"
            class="inline-flex cursor-pointer justify-center items-center whitespace-nowrap focus:outline-none transition-colors duration-150 border rounded ring-blue-700 text-black border-teal-50 hover:bg-gray-200 text-sm p-1"
            type="button"
            :class="[_enabled ? 'cursor-not-allowed bg-gray-200' : 'bg-teal-50 is-active']"
            @click.prevent="draw"
        >
            <BaseIcon v-if="mdiDrawPen" :path="mdiDrawPen" />
        </button>
    </div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from 'vue-facing-decorator';

import BaseIcon from '@/Components/BaseIcon.vue';
import { mdiDrawPen } from '@mdi/js';
import { MapService } from '@/Stores/map.service';
import { Map } from 'leaflet/src/map/index';
// import { LayerGroup } from 'leaflet/src/layer/LayerGroup';
// import { LatLngBounds, Rectangle } from 'leaflet';
import { on, off, preventDefault } from 'leaflet/src/dom/DomEvent';
import { Rectangle } from 'leaflet/src/layer/vector/Rectangle';
import { LatLngBounds } from 'leaflet/src/geo/LatLngBounds';

@Component({
    name: 'draw-control',
    components: {
        BaseIcon,
    },
})
export default class DrawControlComponent extends Vue {
    TYPE = 'rectangle';

    /**
     * class properties.
     */
    mdiDrawPen = mdiDrawPen;
    featuresLayer;
    // options = {
    //     zIndex: 1000,
    //     // markerClass: Marker, // CylinderGeometry,
    //     drawingCSSClass: 'gba-editable-drawing',
    //     drawingCursor: 'crosshair',
    // };

    options = {
        shapeOptions: {
            stroke: true,
            color: '#22C55E',
            weight: 4,
            opacity: 0.5,
            fill: true,
            fillColor: '#22C55E', //same as color by default
            fillOpacity: 0.2,
            clickable: true,
        },
        repeatMode: true,
        showArea: true, //Whether to show the area in the tooltip
        metric: true, // Whether to use the metric measurement system or imperial
    };

    /**
     * Connect map id.
     */
    @Prop() public mapId: string;
    // @Prop() public map: Map;
    @Prop public southWest;
    @Prop public northEast;


    mapService = MapService();
    // try:
    public _enabled;
    private _map: Map;
    private _isDrawing: boolean = false;
    private _startLatLng;
    private _mapDraggable;
    private _shape: Rectangle | undefined;

    // @method enable(): this
    // Enables the handler
    enable() {
        if (this._enabled) {
            return this;
        }

        this._enabled = true;
        this.addHooks();
        return this;
    }

    // @method disable(): this
    // Disables the handler
    disable() {
        if (!this._enabled) {
            return this;
        }

        this._enabled = false;
        this.removeHooks();
        return this;
    }

    // @method enabled(): Boolean
    // Returns `true` if the handler is enabled
    enabled() {
        return !!this._enabled;
    }

    // @Ref('inputDraw') private _inputDraw: HTMLElement;

    // SimpleShape
    // @method addHooks(): void
    // Add listener hooks to this handler.
    private addHooks() {
        // L.Draw.Feature.prototype.addHooks.call(this);
        this._map = this.mapService.getMap(this.mapId);
        if (this._map) {
            this._mapDraggable = this._map.dragging.enabled();
            if (this._mapDraggable) {
                this._map.dragging.disable();
            }
            //TODO refactor: move cursor to styles
            // this._map.domElement.style.cursor = 'crosshair';
            this._map._container.style.cursor = 'crosshair';
            // this._tooltip.updateContent({text: this._initialLabelText});
            this._map
                .on('mousedown', this._onMouseDown, this)
                .on('mousemove', this._onMouseMove, this)
                .on('touchstart', this._onMouseDown, this)
                .on('touchmove', this._onMouseMove, this);
            // we should prevent default, otherwise default behavior (scrolling) will fire,
            // and that will cause document.touchend to fire and will stop the drawing
            // (circle, rectangle) in touch mode.
            // (update): we have to send passive now to prevent scroll, because by default it is {passive: true} now, which means,
            // handler can't event.preventDefault
            // check the news https://developers.google.com/web/updates/2016/06/passive-event-listeners
            // document.addEventListener('touchstart', preventDefault, { passive: false });
        }
    }

    // SimpleShape
    // @method removeHooks(): void
    // Remove listener hooks from this handler.
    removeHooks() {
        // L.Draw.Feature.prototype.removeHooks.call(this);
        if (this._map) {
            if (this._mapDraggable) {
                this._map.dragging.enable();
            }

            //TODO refactor: move cursor to styles
            this._map._container.style.cursor = '';

            this._map
                .off('mousedown', this._onMouseDown, this)
                .off('mousemove', this._onMouseMove, this)
                .off('touchstart', this._onMouseDown, this)
                .off('touchmove', this._onMouseMove, this);

            off(document, 'mouseup', this._onMouseUp, this);
            off(document, 'touchend', this._onMouseUp, this);

            // document.removeEventListener('touchstart', preventDefault);

            // If the box element doesn't exist they must not have moved the mouse, so don't need to destroy/return
            // if (this._shape) {
            // 	this._map.removeLayer(this._shape);
            // 	// delete this._shape;
            //     this._shape = undefined;
            // }
        }
        this._isDrawing = false;
    }

    private _onMouseDown(e) {
        this._isDrawing = true;
        this._startLatLng = e.latlng;

        // DomEvent.on(document, 'mouseup', this._onMouseUp, this)
        //     .on(document, 'touchend', this._onMouseUp, this)
        //     .preventDefault(e.originalEvent);
        on(document, 'mouseup', this._onMouseUp, this);
        on(document, 'touchend', this._onMouseUp, this);
        preventDefault(e.originalEvent);
    }

    private _onMouseMove(e) {
        var latlng = e.latlng;

        // this._tooltip.updatePosition(latlng);
        if (this._isDrawing) {
            // this._tooltip.updateContent(this._getTooltipText());
            this._drawShape(latlng);
        }
    }

    private _onMouseUp() {
        if (this._shape) {
            this._fireCreatedEvent(this._shape);
        }

        // this.removeHooks();
        this.disable();
        if (this.options.repeatMode) {
            this.enable();
        }
    }

    private _fireCreatedEvent(shape) {
        var rectangle = new Rectangle(shape.getBounds(), this.options.shapeOptions);
        // L.Draw.SimpleShape.prototype._fireCreatedEvent.call(this, rectangle);
        this._map.fire('Daw.Event.CREATED', { layer: rectangle, type: this.TYPE });
    }

    public drawShape(southWest, northEast) {
        if (!this._shape) {
            const bounds = new LatLngBounds(southWest, northEast);
            this._shape = new Rectangle(bounds, this.options.shapeOptions);
            // this._map.addLayer(this._shape);
            this._map = this.mapService.getMap(this.mapId);
            this._shape.addTo(this._map);
        } else {
            this._shape.setBounds(new LatLngBounds(southWest, northEast));
        }
    }

    // from Draw Rectangle
    private _drawShape(latlng) {
        if (!this._shape) {
            const bounds = new LatLngBounds(this._startLatLng, latlng);
            this._shape = new Rectangle(bounds, this.options.shapeOptions);
            // this._map.addLayer(this._shape);
            this._shape.addTo(this._map);
        } else {
            this._shape.setBounds(new LatLngBounds(this._startLatLng, latlng));
        }
    }

    public draw() {
        // let map: Map = this.mapService.getMap(this.mapId);
        // const bounds: LatLngBoundsExpression = toLatLngBounds(this.southWest, this.northEast);
        // map.fitBounds(bounds);

        if (this._enabled == true) {
            this.disable();
        } else {
            this.enable();
        }
    }

    // private enable() {
    //     //if (this.map.mapTool) this.map.mapTool.on('editable:drawing:start', this.disable.bind(this));
    //     // dom.addClass(this.map.container, 'measure-enabled');
    //     //this.fireAndForward('showmeasure');
    //     this._startMarker(this.southWest, this.options);
    // }

    // private disable() {
    //     //if (this.map.mapTool) this.map.mapTool.off('editable:drawing:start', this.disable.bind(this));
    //     // dom.removeClass(this.map.container, 'measure-enabled');
    //     // this.featuresLayer.clearLayers();
    //     // //this.fireAndForward('hidemeasure');
    //     // if (this._drawingEditor) {
    //     //     this._drawingEditor.cancelDrawing();
    //     // }
    // }
}
</script>

<style lang="css">
.gba-control-draw {
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    cursor: pointer;
    border-radius: 4px;
    position: absolute;
    left: 10px;
    top: 100px;
    z-index: 39;
}

.btn-group-vertical button {
    display: block;

    margin-left: 0;
    margin-top: 0.5em;
}
</style>
