from ..layer import Layer
from ..icon import Icon
from ...core.Parser import Parser

from qtpy.QtCore import Slot, Signal, QJsonValue

from typing import List


class Marker(Layer):
    moveend = Signal(dict)
    move = Signal(dict)
    click = Signal(dict)

    def __init__(self, latLng: List[float], options=None):
        super().__init__()
        if isinstance(options, type(None)):
            options = {}
        self.latLng = latLng
        self.options = options
        self.opacity = options.get('opacity', 1)
        self.draggable = options.get('draggable', False)
        if self._map:
            self._initJs()

    @Slot(QJsonValue)
    def _onMove(self, event):
        self._logger.debug('marker moved. event: {event}'.format(event=event))
        event = self._qJsonValueToDict(event)
        self.latLng = [event["latlng"]["lat"], event["latlng"]["lng"]]
        self.move.emit({**self._qJsonValueToDict(event), "latLng": self.latLng, "sender": self})

    @Slot(QJsonValue)
    def _onMoveend(self, event):
        self._logger.debug('marker moved. event: {event}'.format(event=event))
        if self.opacity == 0:
            return
        self.moveend.emit({**self._qJsonValueToDict(event), "latLng": self.latLng, "sender": self})

    @Slot(QJsonValue)
    def _click(self, event):
        self._logger.debug('marker clicked. event: {event}'.format(event=event))
        if self.opacity == 0:
            return
        self.click.emit({**self._qJsonValueToDict(event), "sender": self})

    def _initJs(self):
        leafletJsObject = 'L.marker({latLng}'.format(latLng=self.latLng)
        if self.options:
            leafletJsObject += ', {options}'.format(options=Parser.dict_for_js(self.options))
        leafletJsObject += ')'
        self._createJsObject(leafletJsObject, self._map.mapWidgetIndex)
        self._connectEventToSignal('move', '_onMove', self._map.mapWidgetIndex)
        self._connectEventToSignal('moveend', '_onMoveend', self._map.mapWidgetIndex)
        self._connectEventToSignal('click', '_click', self._map.mapWidgetIndex)

    def setLatLng(self, latLng):
        self.latLng = latLng
        js = '{layerName}.setLatLng({latLng})'.format(
                layerName=self._layerName, latLng=latLng)
        self.runJavaScriptForMapIndex(js)
        return self

    def setOpacity(self, opacity):
        self.opacity = opacity
        js = '{layerName}.setOpacity({opacity})'.format(
                layerName=self._layerName, opacity=self.opacity)
        self.runJavaScriptForMapIndex(js)
        return self

    def setDragging(self, draggable):
        self.draggable = draggable
        option = 'enable' if self.draggable else 'disable'
        js = '{layerName}.dragging.{option}();'.format(layerName=self._layerName, option=option)
        self.runJavaScriptForMapIndex(js)
        return self

    def setIcon(self, icon: Icon):
        js = '{layerName}.setIcon({markerIcon});'.format(layerName=self._layerName, markerIcon=icon._layerName)
        self.runJavaScriptForMapIndex(js)
        return self

    def setRotationAngle(self, angle_deg: float):
        js = '{layerName}.setRotationAngle({angle_deg});'.format(layerName=self._layerName, angle_deg=angle_deg)
        self.runJavaScriptForMapIndex(js)
        return self

    def setRotationOrigin(self, origin: str):
        js = '{layerName}.setRotationOrigin({origin});'.format(layerName=self._layerName, origin=origin)
        self.runJavaScriptForMapIndex(js)
        return self
