# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from distutils.version import LooseVersion

from django import get_version
from django import forms
from django.core import validators
from django.core.exceptions import ImproperlyConfigured
from django.template.defaultfilters import slugify
try:
    from django.contrib.gis.forms.widgets import BaseGeometryWidget
except (ImportError, ImproperlyConfigured):
    from .backport import BaseGeometryWidget

from leaflet import app_settings, PLUGINS, PLUGIN_FORMS


class LeafletWidget(BaseGeometryWidget):
    template_name = 'leaflet/widget.html'
    map_srid = 4326
    map_width = None
    map_height = None
    modifiable = True
    supports_3d = False
    include_media = False
    settings_overrides = {}

    @property
    def media(self):
        if not self.include_media:
            return forms.Media()

        # We assume that including media for widget means there is
        # no Leaflet at all in the page.
        js = ['leaflet/leaflet.js'] + PLUGINS[PLUGIN_FORMS]['js']
        css = ['leaflet/leaflet.css'] + PLUGINS[PLUGIN_FORMS]['css']
        return forms.Media(js=js, css={'screen': css})

    def serialize(self, value):
        return value.geojson if value else ''

    def _get_attrs(self, name, attrs=None):
        assert self.map_srid == 4326, 'Leaflet vectors should be decimal degrees.'

        # Retrieve params from Field init (if any)
        self.geom_type = self.attrs.get('geom_type', self.geom_type)
        self.settings_overrides = self.attrs.get('settings_overrides', self.settings_overrides)

        # Setting 'loadevent' added in the widget constructor
        loadevent = self.attrs.get('loadevent', app_settings.get('LOADEVENT'))

        attrs = attrs or {}

        # In BaseGeometryWidget, geom_type is set using gdal, and fails with generic.
        # See https://code.djangoproject.com/ticket/21021
        if self.geom_type == 'GEOMETRY':
            attrs['geom_type'] = 'Geometry'

        map_id_css = slugify(attrs.get('id', name))  # id need to have - for the inline formset to replace the prefix
        map_id = map_id_css.replace('-', '_')  # JS-safe
        attrs.update(id=map_id,
                     id_css=map_id_css,
                     module='geodjango_%s' % map_id,
                     id_map=map_id_css + '-map',
                     id_map_callback=map_id + '_map_callback',
                     loadevent=loadevent,
                     modifiable=self.modifiable,
                     target_map=attrs.get('target_map', getattr(self, 'target_map', None)),
                     settings_overrides=attrs.get('settings_overrides', getattr(self, 'settings_overrides', None)),
                     geometry_field_class=attrs.get('geometry_field_class', getattr(self, 'geometry_field_class', 'L.GeometryField')),
                     field_store_class=attrs.get('field_store_class', getattr(self, 'field_store_class', 'L.FieldStore')))
        return attrs

    # Django 1.11 changed how the widgets are rendered
    if LooseVersion(get_version()) >= LooseVersion('1.11'):
        def get_context(self, name, value, attrs):
            value = None if value in validators.EMPTY_VALUES else value
            context = super(LeafletWidget, self).get_context(name, value, attrs)
            context.update(self._get_attrs(name, attrs))
            return context
    else:
        def render(self, name, value, attrs=None):
            attrs = self._get_attrs(name, attrs)
            value = None if value in validators.EMPTY_VALUES else value
            return super(LeafletWidget, self).render(name, value, attrs)
