from django.contrib.gis.gdal import OGRException
from django.contrib.gis.geos import GEOSGeometry, GEOSException
from django.forms.widgets import Textarea
from django.template.loader import render_to_string

class OpenLayersWidget(Textarea):
    """
    Renders an OpenLayers map using the WKT of the geometry.
    """
    def render(self, name, value, attrs=None):
        # Update the template parameters with any attributes passed in.
        if attrs: self.params.update(attrs)

        # Defaulting the WKT value to a blank string -- this
        # will be tested in the JavaScript and the appropriate
        # interfaace will be constructed.
        self.params['wkt'] = ''

        # If a string reaches here (via a validation error on another
        # field) then just reconstruct the Geometry.
        if isinstance(value, basestring):
            try:
                value = GEOSGeometry(value)
            except (GEOSException, ValueError):
                value = None

        if value and value.geom_type.upper() != self.geom_type:
            value = None

        # Constructing the dictionary of the map options.
        self.params['map_options'] = self.map_options()

        # Constructing the JavaScript module name using the ID of
        # the GeometryField (passed in via the `attrs` keyword).
        self.params['module'] = 'geodjango_%s' % self.params['field_name']

        if value:
            # Transforming the geometry to the projection used on the
            # OpenLayers map.
            srid = self.params['srid']
            if value.srid != srid: 
                try:
                    value.transform(srid)
                    wkt = value.wkt
                except OGRException:
                    wkt = ''
            else:
                wkt = value.wkt
               
            # Setting the parameter WKT with that of the transformed
            # geometry.
            self.params['wkt'] = wkt

        return render_to_string(self.template, self.params)
    
    def map_options(self):
        "Builds the map options hash for the OpenLayers template."

        # JavaScript construction utilities for the Bounds and Projection.
        def ol_bounds(extent):
            return 'new OpenLayers.Bounds(%s)' % str(extent)
        def ol_projection(srid):
            return 'new OpenLayers.Projection("EPSG:%s")' % srid

        # An array of the parameter name, the name of their OpenLayers
        # counterpart, and the type of variable they are.
        map_types = [('srid', 'projection', 'srid'), 
                     ('display_srid', 'displayProjection', 'srid'), 
                     ('units', 'units', str),
                     ('max_resolution', 'maxResolution', float),
                     ('max_extent', 'maxExtent', 'bounds'),
                     ('num_zoom', 'numZoomLevels', int),
                     ('max_zoom', 'maxZoomLevels', int),
                     ('min_zoom', 'minZoomLevel', int),
                     ]

        # Building the map options hash.
        map_options = {}
        for param_name, js_name, option_type in map_types:
            if self.params.get(param_name, False):
                if option_type == 'srid':
                    value = ol_projection(self.params[param_name])
                elif option_type == 'bounds':
                    value = ol_bounds(self.params[param_name])
                elif option_type in (float, int):
                    value = self.params[param_name]
                elif option_type in (str,):
                    value = '"%s"' % self.params[param_name]
                else:
                    raise TypeError
                map_options[js_name] = value
        return map_options
