#!/usr/bin/env python
# -*- coding: utf-8 -*-
from gluon import *
from gluon.tools import prettydate

from plugin_geotip.tools import getUUID
# from plugin_geotip.widgets import GeoJsonCollector
from geojson import FeatureCollection
from gluon.contrib import simplejson as json
import datetime
from state import get_state

if current.T is None:
    T = lambda v: v
else:
    T = current.T

class nested(object):

    @classmethod
    def update(cls, d, u):
        """ Coutesy of: http://stackoverflow.com/questions/3232943/update-value-of-a-nested-dictionary-of-varying-depth """
        for k, v in u.iteritems():
            if isinstance(v, collections.Mapping):
                r = cls.update(d.get(k, {}), v)
                d[k] = r
            else:
                d[k] = u[k]
        return d

    @classmethod
    def compare(cls, d, u):
        for k, v in u.iteritems():
            if not k in d:
                return False
            elif isinstance(v, collections.Mapping):
                if isinstance(d[k], collections.Mapping):
                    rr = cls.compare(d[k], v)
                    if rr ==True:
                        continue
                    else:
                        return False
                else:
                    return False
            else:
                if not d[k] == v:
                    return False
                else:
                    continue
        return True

class GeoJsonCollector(object):
 
    feature_attributes = dict(
#         properties = dict(
#             id = lambda r: r.id,
#             label = '',
#             name = lambda r: 
#         ),
        style = dict(
#             externalGraphic = URL('static', plugin_folder+'/images/my-marker-blue.png'),
            graphicHeight = 25,
            graphicWidth = 21,
            graphicXOffset = -12,
            graphicYOffset = -25,
            labelYOffset = -7,
            fontColor = "#084F72",
            fontWeight = "bold",
            labelOutlineColor = '#d9edf7',
            labelOutlineWidth = 3
        )
    )
 
    @classmethod
    def extract_feature(cls, row, fieldname='the_geom', table=None, escape=True, cid=None, actions=True):
        """
        Warning! row must contain what required from table format.
        """
         
        if table is None or table._format is None:
            format = lambda r: '%(id)s' % r
        elif isinstance(table._format, basestring) and '%' in table._format:
            format = lambda r: table._format % r
        elif callable(table._format):
            format = table._format
        else:
            assert False, "WARNING! It should never happen. Why it happens?"
 
        ccid = current.request.cid or cid
 
        def _get_btngrp():
            """
            <div class="btn-group">
              <button class="btn">Left</button>
              <button class="btn">Middle</button>
              <button class="btn">Right</button>
            </div>
            """
             
            def _get_btn(label, icon_class, **attributes):

#                 defaults = dict(c="site", extension='html', args=(row.id, ), user_signature=True)
#                 _URL = dict(defaults, **(_url or {}))
# 
#                 url = URL(**_URL)
#                 url = URL('site', act, extension='html', args=(row.id, ), user_signature=True)
                 
                return A(I(_class=icon_class), ' ', T(label),
                    _title=T(label),
                    _class='button btn btn-default',
                    **attributes
                )

            def _get_info_btn(*a, **kw):
                if row.status:
                    return _get_btn(*a, **kw)
                else:
                    return ""

            return DIV(
                _get_btn("Note", "icon magnifier glyphicon glyphicon-edit",
                    _href = URL("site", "note", extension="html", args=(row.id, ), user_signature=True)
                ),
                _get_info_btn("Info", "icon magnifier glyphicon glyphicon-info-sign",
                    _onclick = '$( "#myModal" ).load("%s", function () {$("#myModal").modal()});' % URL("default", "call", args=("run", "get_site_infos", row.id, ), extension=""),
#                     _onclick = """$('#myModal').modal({'remote': '%s'});""" % URL("default", "call", args=("run", "get_site_infos", row.id, ), extension=""),
                    **{"_data-toggle": "modal", "_data-target": "#myModal"}
                ),
                
#                 _get_dvar_ttip(),
#                 _get_btn("logrid", "Log", "icon magnifier glyphicon glyphicon-info-sign"),
#                 _get_btn("edit", "Edit", "icon pen icon-pencil glyphicon glyphicon-pencil"),
#                 _get_btn("delete", "Delete", "icon-trash"),
                _class="btn-group", **{'_data-toggle': "buttons"}
            ).xml()
 
        def _get_infos():
            """ DEPRECATED """
            if not row.status is None:
                dvars = row.get("status", {}).get("dev", {}).get("idro", {}).get("dvar")
                def _sorted(*_):
                    for i in dvars:
                        yield i[0]
                if not dvars is None:
                    update_raw = row.status['timestamp']
                    update = datetime.datetime.strptime(update_raw, "%Y-%m-%dT%H:%M:%S.%f")
                    return str(DIV(
                        H5(I(_class="fa fa-info-circle"), " ", T("Info")),
                        SPAN("Updated: ", prettydate(update, T), _style="float:right;", _class="label label-info"),
                        BEAUTIFY(dict(dvars), sorted=_sorted), _class="well").xml()
                    )
            return ""
 
        def _extract():
            el = row[fieldname] # if tablename is None else row[tablename][fieldname]
            if el is None:
                return None
            else:
                feature = el['features'][0]
                feature['id'] = row.id
                feature['properties'] = dict(
                    id = row.id,
                    name = format(row),
                    label = format(row),
                    title = format(row),
                )
                feature['properties']['actions'] = _get_btngrp().replace('"', '\\"') if escape else _get_btngrp()
#                 feature['properties']['url'] = URL("default", "call", args=("run", "get_site_infos", row.id, ), extension="")
#                 feature['properties']['informations'] = _get_infos().replace('"', '\\"')if escape else _get_infos()
                feature['properties']["status"] = None if not row.status else get_state(row.status)
                feature['properties']["running"] = dict((row.status or {}).get("dev", {}).get("idro", {}).get("dvar", {})).get("N. pompe in marcia", 0) > 0
                for key,attrs in cls.feature_attributes.iteritems():
                    for attrname, attr in attrs.iteritems():
                        if not key in feature:
                            feature[key] = {}
                        if callable(attr):
                            feature[key][attrname] = attr(row)
                        else:
                            feature[key][attrname] = attr
            return feature
 
        return _extract()
 
    @classmethod
    def extract_features(cls, rows, fieldname='the_geom', table=None, actions=True, escape=True, **props):
        def _fiter():
            for row in rows:
                feat = cls.extract_feature(row, fieldname, table, escape=escape, actions=actions)
                if not feat is None:
                    yield feat
        return FeatureCollection([f for f in _fiter()], properties=props)

class Maprows(object):
    """ """
    
    map_defaults = {
        # Roma: lat: 41.9027835, lng: 12.4963655
#         '_data-map-center-lat': 41.9027835,
#         '_data-map-center-lng': 12.4963655,
        # Toscana lat: 43.7710513, lng: 11.2486208
        '_data-map-center-lat': 43.7710513,
        '_data-map-center-lng': 11.2486208,
        '_data-map-zoom': 10
    }

    @classmethod
    def draw(cls, rows, table=None, field_name="the_geom", map_type="DashboardMap", last_update=None):
        map_uuid = 'map_%s' % getUUID()
        features = json.dumps(GeoJsonCollector.extract_features(rows, table=table, actions=False, last_update=last_update or float(datetime.datetime.now().strftime("%s.%f"))))
        encoded = XML(features)
        script = SCRIPT("""window.%(map_uuid)s = '%(encoded)s'; MapLoader();""" % locals(), _type="text/javascript")
        defaults = cls.map_defaults.copy()
        defaults.update(**{
           '_data-map': map_type,
           '_data-map-source': map_uuid,
#            '_data-map-update-url': URL(extension='json', args=(current.request.cid, )),
           '_data-map-geom-field-name': field_name,
#            '_data-form-name': map_uuid
        })
        popup = DIV(
            A("", _href="#", _id="popup-closer", _class="ol-popup-closer"),
            DIV("", _id="popup-content"),
            _id="popup", _class="ol-popup", _style="width: 225px;"
        )
        return DIV(popup,
            DIV(
                DIV(
                    _id=map_uuid, _class="geotipmap", _style="width: 100%",
                    **defaults
                ),
            _class="mapcontainer"),
           script
        )

def define_map(js_map_creator, map_id=None, **kw):

    if map_id is None:
        map_id = 'map_%s' % getUUID()

    attributes = dict(
       {
            
            # Roma: lat: 41.9027835, lng: 12.4963655
            # '_data-map-center-lat': 41.9027835,
            # '_data-map-center-lng': 12.4963655,
            # Toscana lat: 43.7710513, lng: 11.2486208
            '_data-map-center-lat': 43.7710513,
            '_data-map-center-lng': 11.2486208,
            '_data-map-zoom': 10
        },
        **dict(
#             kw,
            [("_data-map-%s" % k.replace("_", "-"),v) for k,v in kw.iteritems()],
            **{"_data-map": js_map_creator}
        )
    )

    popup = DIV(
        A("", _href="#", _id="popup-closer", _class="ol-popup-closer"),
        DIV("", _id="popup-content"),
        _id="popup", _class="ol-popup", _style="width: 225px;"
    )
    container = DIV(popup,
        DIV(
            DIV(
                _id=map_id, _class="geotipmap", _style="width: 100%",
                **attributes
            ),
        _class="mapcontainer"),
       SCRIPT("MapLoader();", _type="text/javascript")
    )

    return container

