Index: includes/behaviors/openlayers_behavior_legend.inc
===================================================================
RCS file: includes/behaviors/openlayers_behavior_legend.inc
diff -N includes/behaviors/openlayers_behavior_legend.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/behaviors/openlayers_behavior_legend.inc	25 Aug 2010 10:06:50 -0000
@@ -0,0 +1,63 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Implementation of OpenLayers behavior.
+ */
+
+/**
+ * Legend Behavior
+ */
+class openlayers_behavior_legend extends openlayers_behavior {
+  /**
+   * Provide initial values for options.
+   */
+  function options_init() {
+    return array(
+    );
+  }
+
+  /**
+   * Provide form for configurations per map.
+   */
+  function options_form($defaults) {
+
+    // Build a list of supported layers
+    // We support: WMS 
+    $supported_layers = array();
+    foreach ($this->map['layers'] as $id => $name) {
+      $layer = openlayers_layer_load($id);
+      if ( isset( $layer->data['layer_handler'] )
+                && $layer->data['layer_handler'] == 'wms'
+                && $layer->data['hasLegend'] ) {
+        $supported_layers[$id] = $name;
+      }
+    }
+
+    return array(
+      'layers' => array(
+        '#title' => t('Layers'),
+        '#type' => 'checkboxes',
+        '#options' => $supported_layers,
+        '#description' => t('Select layers to show legend of. Selecting NO layers will show legend of ALL layers having one.'),
+        '#default_value' => isset($defaults['layers']) ? 
+          $defaults['layers'] : array(),
+      ),
+    );
+  }
+
+  /**
+   * Render.
+   */
+  function render(&$map) {
+/*
+    drupal_add_css(drupal_get_path('module', 'openlayers') .
+      '/includes/behaviors/js/openlayers_behavior_legend.css');
+*/
+    drupal_add_js(drupal_get_path('module', 'openlayers') .
+      '/includes/behaviors/js/openlayers_behavior_legend.js');
+    return $this->options;
+  }
+}
+
Index: includes/behaviors/js/openlayers_behavior_legend.js
===================================================================
RCS file: includes/behaviors/js/openlayers_behavior_legend.js
diff -N includes/behaviors/js/openlayers_behavior_legend.js
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ includes/behaviors/js/openlayers_behavior_legend.js	25 Aug 2010 10:06:50 -0000
@@ -0,0 +1,148 @@
+// $Id$
+
+/**
+ * @file
+ * Legend Behavior
+ */
+
+/*
+ * OpenLayers Legend Control class
+ */
+Drupal.openlayers.LegendControl = OpenLayers.Class(OpenLayers.Control, {
+
+  /**
+   * Method: getCandidateLayers
+   * Internal method for lazy candidate layers extraction
+   *
+   * Returns:
+   * {Array} list of layer references found on map with given id
+   */
+  getCandidateLayers: function() {
+
+    if ( ! this.candidateLayers ) {
+      if ( this.qlayers.length ) {
+        this.candidateLayers = [];
+        for (var i=0, len=this.qlayers.length; i<len; ++i) {
+          var layer_id = this.qlayers[i];
+          var selectedLayer = this.map.getLayersBy(this.qlayers_id_field,
+                                                   layer_id);
+          if (typeof selectedLayer[0] != 'undefined') {
+            this.candidateLayers.push(selectedLayer[0]);
+          }
+        }
+      } else {
+        this.candidateLayers = this.map.layers;
+      }
+    }
+
+    //console.log("Candidate layers:"); console.dir(this.candidateLayers);
+
+    return this.candidateLayers;
+  },
+
+  writeLayerLegend: function(layer, text)
+  {
+    var divID = this.div.id + "-"+layer.drupalID;
+    var div = document.getElementById(divID);
+    if ( div ) div.innerHTML = layer.name + '<br>' + text;
+  },
+
+  toggleLayerLegendVisibility: function(evt)
+  {
+    var layer = evt.object;
+    if ( layer.getVisibility() ) {
+        var handler = OpenLayers.Function.bind(this.writeLayerLegend, this);
+        layer.enableLegend(handler);
+    } else {
+      var divID = this.div.id + "-"+layer.drupalID;
+      var div = document.getElementById(divID);
+      div.innerHTML = '';
+      if ( layer.disableLegend ) layer.disableLegend();
+    }
+  },
+
+  setupLayerLegend: function(layer)
+  {
+    if ( layer.enableLegend ) {
+
+      // Create layer legend div
+      var divID = this.div.id + "-"+layer.drupalID;
+      var div = document.createElement("div");
+      OpenLayers.Element.addClass(this.legendDiv, "openlayers-legend-layer"); 
+      div.id = divID;
+      this.legendDiv.appendChild(div);
+
+      if ( layer.getVisibility() ) {
+        var handler = OpenLayers.Function.bind(this.writeLayerLegend, this);
+        layer.enableLegend(handler);
+      }
+
+      var visibilityToggler = OpenLayers.Function.bind(
+          this.toggleLayerLegendVisibility, this);
+      layer.events.register('visibilitychanged', layer, visibilityToggler);
+    }
+  },
+
+  setupLegend: function()
+  {
+    this.legendDiv.innerHTML = '';
+    //this.legendDiv.innerHTML += '- LEGEND -';
+    var candidateLayers = this.getCandidateLayers();
+    for (var i=0, len=candidateLayers.length; i<len; ++i) {
+      var layer = candidateLayers[i];
+      this.setupLayerLegend(layer);
+    }
+  },
+
+  activate: function()
+  {
+    //console.log('Activate!, this div:'); console.dir(this.div);
+
+    // Create legend div
+    this.legendDiv = document.createElement("div");
+
+    this.legendDiv.id = this.div.id + "-legend";
+    //this.legendDiv.style.color = '#ffffff';
+    OpenLayers.Element.addClass(this.legendDiv, "openlayers-legend"); 
+    this.div.appendChild(this.legendDiv);
+
+    // Build legend once at start
+    this.setupLegend();
+
+    return OpenLayers.Control.prototype.activate.apply(
+        this, arguments
+    );
+  },
+
+
+});
+
+/**
+ * Behavior for Legend 
+ */
+Drupal.behaviors.openlayers_behavior_legend = function(context) {
+
+  var data = $(context).data('openlayers');
+  if (data && data.map.behaviors['openlayers_behavior_legend']) {
+
+    var options = data.map.behaviors['openlayers_behavior_legend'];
+
+    var layer_ids = [];
+    for (var i in options.layers) {
+      var layer_id = options.layers[i];
+      if ( layer_id !== 0 ) layer_ids.push(layer_id);
+    }
+
+    var legendControl = new Drupal.openlayers.LegendControl({
+      qlayers_id_field: 'drupalID',
+      qlayers: layer_ids,
+      div: context.parentNode, /* this will be outside of the map */
+      autoActivate: true
+    });
+    var map = data.openlayers;
+    map.addControl(legendControl);
+
+  }
+
+};
+
Index: includes/layer_types/wms.inc
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/openlayers/includes/layer_types/Attic/wms.inc,v
retrieving revision 1.1.2.17
diff -u -p -r1.1.2.17 wms.inc
--- includes/layer_types/wms.inc	16 Aug 2010 20:21:58 -0000	1.1.2.17
+++ includes/layer_types/wms.inc	25 Aug 2010 10:06:50 -0000
@@ -49,7 +49,7 @@ class openlayers_layer_type_wms extends 
         '#default_value' => isset($this->data['base_url']) ?
           $this->data['base_url'] : ''
       ),
-      
+
       // TODO: swap terms
       'params' => array(
         'isBaseLayer' => array(
@@ -129,7 +129,16 @@ class openlayers_layer_type_wms extends 
       'layer_type' => array(
         '#type' => 'hidden',
         '#value' => 'openlayers_layer_type_wms'
-      )
+      ),
+      'hasLegend' => array(
+          '#type' => 'checkbox',
+          '#default_value' => isset($this->data['hasLegend']) ? 
+            $this->data['hasLegend'] : FALSE,
+          '#title' => t('Has Legend'),
+          '#return_value' => 'true',
+          '#description' => t('Check if this layer supports legend')
+      ),
+      
     );
   }
 
Index: includes/layer_types/js/wms.js
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/openlayers/includes/layer_types/js/Attic/wms.js,v
retrieving revision 1.1.2.2
diff -u -p -r1.1.2.2 wms.js
--- includes/layer_types/js/wms.js	9 Jun 2010 12:57:17 -0000	1.1.2.2
+++ includes/layer_types/js/wms.js	25 Aug 2010 10:06:50 -0000
@@ -20,8 +20,48 @@ Drupal.openlayers.layer.wms = function (
   }
 
   options.params.drupalID = options.drupalID;
+
   var layer = new OpenLayers.Layer.WMS(title, 
     options.base_url, options.options, options.params);
   layer.styleMap = styleMap;
+
+  if ( options.hasLegend ) {
+
+    layer.enableLegend = function(handler)
+    {
+      this.legendHandler = handler;
+      this.updateLegend();
+  
+      // Scale-dependent legend (TODO: make use of this configurable)
+      this.map.events.register("zoomend", this, this.updateLegend);
+    };
+  
+    layer.updateLegend = function()
+    {
+      // TODO: if there are multiple WMS layers, we might need 
+      //       to have an image tag for each one of them
+  
+      var url = this.getFullRequestString({
+        REQUEST: "GetLegendGraphic",
+        EXCEPTIONS: "application/vnd.ogc.se_inimage",
+        FORMAT: 'image/png',
+        LAYER: this.params.LAYERS
+      });
+  
+      // Scale-dependent legend (TODO: make use of this configurable)
+      var scale = this.map.getScale();
+      url = OpenLayers.Util.urlAppend(url, "SCALE=" + scale);
+  
+      this.legendHandler(this, '<img src="' + url + '">');
+    };
+  
+    layer.disableLegend = function()
+    {
+      // Scale-dependent legend (TODO: make use of this configurable)
+      this.map.events.unregister("zoomend", this, this.updateLegend);
+    };
+
+  }
+
   return layer;
 };
