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	24 Aug 2010 16:11:08 -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') {
+        // TODO: for WMS check queriability
+        $supported_layers[$id] = $name;
+      }
+    }
+
+    return array(
+      'layers' => array(
+        '#title' => t('Layers'),
+        '#type' => 'checkboxes',
+        '#options' => $supported_layers,
+        '#description' => t('Select layers to show legend for.'),
+        '#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	24 Aug 2010 16:11:08 -0000
@@ -0,0 +1,145 @@
+// $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 ) {
+      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]);
+        }
+      }
+    }
+
+    //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/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	24 Aug 2010 16:11:08 -0000
@@ -20,6 +20,39 @@ Drupal.openlayers.layer.wms = function (
   }
 
   options.params.drupalID = options.drupalID;
+
+  options.params.enableLegend = function(handler)
+  {
+    this.legendHandler = handler;
+    this.updateLegend();
+
+    // TODO: if WMS allows scale-dependent legend
+    //       we should:
+    //        - register a map callback to invoke updateLegend()
+    //          on scale change
+    //        - unregister the callback in the disableLegend function
+  };
+
+  options.params.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
+    });
+
+    this.legendHandler(this, '<img src="' + url + '">');
+  };
+
+  options.params.disableLegend = function()
+  {
+    // nothing to do here, see TODO in enableLegend
+  };
+
   var layer = new OpenLayers.Layer.WMS(title, 
     options.base_url, options.options, options.params);
   layer.styleMap = styleMap;
