Index: mapclient/mapclient.admin.inc
===================================================================
--- mapclient/mapclient.admin.inc	(revision 112)
+++ mapclient/mapclient.admin.inc	(working copy)
@@ -33,6 +33,21 @@
     , '#description' => t('Path to proxy script. This script is used to fetch feature info, legends, etc.')
     , '#default_value' => variable_get('mapclient_proxy', DEFAULT_MAPCLIENT_PROXY)
     );
+  $form['mapclient']['mapclient_baselayers_separator'] = array('#type' => 'textfield'
+    , '#title' => t('Baselayers separator')
+    , '#description' => t('Separator for baselayers attribute.')
+    , '#default_value' => variable_get('mapclient_baselayers_separator', ',')
+    );
+  $form['mapclient']['mapclient_baselayer_options_separator'] = array('#type' => 'textfield'
+    , '#title' => t('Baselayer options separator')
+    , '#description' => t('Separator for baselayer options. Must be different from the baselayers separator!')
+    , '#default_value' => variable_get('mapclient_baselayer_options_separator', '|')
+    );
+  $form['mapclient']['mapclient_layers_separator'] = array('#type' => 'textfield'
+    , '#title' => t('Layers separator')
+    , '#description' => t('Separator for layers attribute.')
+    , '#default_value' => variable_get('mapclient_layers_separator', ',')
+    );
   
   $form['locations'] = array(
     '#type' => 'fieldset'
Index: openlayers/openlayers.mapclient.inc
===================================================================
--- openlayers/openlayers.mapclient.inc	(revision 142)
+++ openlayers/openlayers.mapclient.inc	(working copy)
@@ -1,7 +1,15 @@
 <?php
 // $Id: openlayers.mapclient.inc,v 1.1.2.25 2008/07/04 14:01:02 openwereld Exp $
 
+global $baselayers_separator, $baselayer_options_separator;
+
 /**
+ * Following parameters are configurable via the map client admin page.
+ */
+$baselayers_separator = variable_get('mapclient_baselayers_separator', ','); //;
+$baselayer_options_separator = variable_get('mapclient_baselayer_options_separator', '|'); //,
+
+/**
  * Initialize header.
  */
 function openlayers_init_header() {
@@ -129,22 +137,41 @@
   
   if (isset($attrs['baselayers'])) {
     // include scripts for base layers
-    $baselayers = explode(',', $attrs['baselayers']);
+    $google_src_set = FALSE;
+    $multimap_src_set = FALSE;
+    $ve_src_set = FALSE;
+    $yahoo_src_set = FALSE;
+    $baselayers = get_baselayers($attrs['baselayers']);
     foreach ($baselayers as $baselayer) {
       $src = NULL;
-      switch ($baselayer) {
+      $baselayer_vendor = $baselayer['baselayer_vendor'];
+      //$variant = $baselayer['variant'];
+      //$baselayer_options = $baselayer['baselayer_options'];
+      switch ($baselayer_vendor) {
       case 'google':
-        $google_maps_key = variable_get('google_maps_key', DEFAULT_GOOGLE_MAPS_KEY);
-        $src = "http://maps.google.com/maps?file=api&amp;v=2&amp;key=$google_maps_key";
+        if($google_src_set == FALSE) {
+          $google_maps_key = variable_get('google_maps_key', DEFAULT_GOOGLE_MAPS_KEY);
+          $src = "http://maps.google.com/maps?file=api&amp;v=2&amp;key=$google_maps_key";
+          $google_src_set = TRUE;
+        }
         break;
       case 'multimap':
-        $src = 'http://clients.multimap.com/API/maps/1.1/metacarta_04';
+        if($multimap_src_set == FALSE) {
+          $src = 'http://clients.multimap.com/API/maps/1.1/metacarta_04';
+          $multimap_src_set = TRUE;
+        }
         break;
       case 've':
-        $src = 'http://dev.virtualearth.net/mapcontrol/v3/mapcontrol.js';
+        if($ve_src_set == FALSE) {
+          $src = 'http://dev.virtualearth.net/mapcontrol/v3/mapcontrol.js';
+          $ve_src_set = TRUE;
+        }
         break;
       case 'yahoo':
-        $src = 'http://api.maps.yahoo.com/ajaxymap?v=3.0&appid=euzuro-openlayers';
+        if($yahoo_src_set == FALSE) {
+          $src = 'http://api.maps.yahoo.com/ajaxymap?v=3.0&appid=euzuro-openlayers';
+          $yahoo_src_set = TRUE;
+        }
         break;
       }
       if (!is_null($src)) {
@@ -282,7 +309,10 @@
       }
     }
     
-    if (isset($map['extent'])) {
+    if (isset($map['restrictedextent'])) {
+      $map['maxextent'] = $map['restrictedextent'];
+    }
+    elseif (isset($map['extent'])) {
       $initial_extent = $map['extent'];
       
       if (!isset($map['maxextent'])) {
@@ -298,7 +328,18 @@
       $maxResolution = NULL;
     }
     
-    if (isset($map['maxextent'])) {
+    if (isset($map['restrictedextent'])) {
+      $restrictedextent = explode(',', $map['restrictedextent']);
+      if (!$maxResolution) {
+        $maxResolution = max(($restrictedextent[2] - $restrictedextent[0])/$map['width']
+          , ($restrictedextent[3] - $restrictedextent[1])/$map['height']);
+      }
+
+      $js .= "var extent = new OpenLayers.Bounds({$map['restrictedextent']});\n";
+      $js .= "map_options.restrictedExtent = extent;\n";
+      $js .= "map_options.maxExtent = extent;\n";
+    }
+    elseif (isset($map['maxextent'])) {
       $maxextent = explode(',', $map['maxextent']);
       if (!$maxResolution) {
         $maxResolution = max(($maxextent[2] - $maxextent[0])/$map['width']
@@ -339,20 +380,23 @@
     
     // (2) add the baselayers
     if (isset($map['baselayers'])) {
-      $baselayers = explode(',', $map['baselayers']);
-      foreach ($baselayers as $baselayer_variant) {
-        $tmp = explode('-', $baselayer_variant);
-        $baselayer = $tmp[0];
-        $variant = count($tmp) > 1 ? strtolower($tmp[1]) : 'default';
-        switch ($baselayer) {
+      $baselayers = get_baselayers($map['baselayers']);
+      foreach ($baselayers as $baselayer) {
+        $baselayer_vendor = $baselayer['baselayer_vendor'];
+        $variant = $baselayer['variant'];
+        $baselayer_options = $baselayer['baselayer_options'];
+        switch ($baselayer_vendor) {
         case 'google':
           // 20 zoom levels works fine
           // alternatives: Streets=(), Satellite=G_SATELLITE_MAP, Hybrid=G_HYBRID_MAP
-          $variants = array('default' => 'G_HYBRID_MAP', 'streets' => 'G_HYBRID_MAP', 'satellite' => 'G_SATELLITE_MAP', 'hybrid' => 'G_HYBRID_MAP');
+          $variants = array('default' => 'G_HYBRID_MAP', 'streets' => 'G_NORMAL_MAP', 'satellite' => 'G_SATELLITE_MAP', 'hybrid' => 'G_HYBRID_MAP', 'physical' => 'G_PHYSICAL_MAP');
           $type = isset($variants[$variant]) ? $variants[$variant] : $variants['default'];
           $js .= "if (typeof $type != 'undefined') {\n";
-          $js .= "  client.google = new OpenLayers.Layer.Google('Google - $variant', {type: $type, 'sphericalMercator': $sphericalMercator, 'numZoomLevels': 20, opacity: 0.8});\n";
-          $js .= "  client.baselayers[client.baselayers.length] = client.google;\n";
+          $js .= get_baselayer_options_js($baselayer_options);
+          $js .= "layer_options.type = {$type};\n";
+          $js .= "layer_options.sphericalMercator = {$sphericalMercator};\n";
+          $js .= "client.google = new OpenLayers.Layer.Google('Google - $variant', layer_options);\n";
+          $js .= "client.baselayers[client.baselayers.length] = client.google;\n";
           $js .= "}\n";
           break;
         case 've':
@@ -360,8 +404,11 @@
           $variants = array('default' => 'Hybrid', 'streets' => 'Road', 'satellite' => 'Aerial', 'hybrid' => 'Hybrid');
           $type = isset($variants[$variant]) ? $variants[$variant] : $variants['default'];
           $js .= "if (typeof VEMapStyle != 'undefined') {\n";
-          $js .= "  client.ve = new OpenLayers.Layer.VirtualEarth('Virtual Earth - $variant', {'type': VEMapStyle.$type, 'sphericalMercator': $sphericalMercator, 'numZoomLevels': 20, opacity: 0.8});\n";
-          $js .= "  client.baselayers[client.baselayers.length] = client.ve;\n";
+          $js .= get_baselayer_options_js($baselayer_options);
+          $js .= "layer_options.type = VEMapStyle.$type;\n";
+          $js .= "layer_options.sphericalMercator = {$sphericalMercator};\n";
+          $js .= "client.ve = new OpenLayers.Layer.VirtualEarth('Virtual Earth - $variant', layer_options);\n";
+          $js .= "client.baselayers[client.baselayers.length] = client.ve;\n";
           $js .= "}\n";
           break;
         case 'yahoo':
@@ -369,8 +416,11 @@
           $variants = array('default' => 'YAHOO_MAP_HYB', 'satellite' => 'YAHOO_MAP_SAT', 'hybrid' => 'YAHOO_MAP_HYB');
           $type = isset($variants[$variant]) ? $variants[$variant] : $variants['default'];
           $js .= "if (typeof $type != 'undefined') {\n";
-          $js .= "  client.yahoo = new OpenLayers.Layer.Yahoo('Yahoo - $variant', {'type': $type, 'sphericalMercator': $sphericalMercator});\n";
-          $js .= "  client.baselayers[client.baselayers.length] = client.yahoo;\n";
+          $js .= get_baselayer_options_js($baselayer_options);
+          $js .= "layer_options.type = {$type};\n";
+          $js .= "layer_options.sphericalMercator = {$sphericalMercator};\n";
+          $js .= "client.yahoo = new OpenLayers.Layer.Yahoo('Yahoo - $variant', layer_options);\n";
+          $js .= "client.baselayers[client.baselayers.length] = client.yahoo;\n";
           $js .= "}\n";
           break;
         case 'none':
@@ -790,3 +840,62 @@
   return str_replace("'", "\\'", $str);
 }
 
+/**
+ *
+ */
+function get_baselayers($baselayers_str) {
+  global $baselayers_separator, $baselayer_options_separator;
+  
+  $baselayers = array();
+  $baselayers_arr = explode($baselayers_separator, $baselayers_str);
+  $i = 0;
+  foreach($baselayers_arr as $baselayer_info) {
+    $tmp = explode($baselayer_options_separator, $baselayer_info);
+    $baselayer_variant = $tmp[0];
+    $baselayer_options = (count($tmp) > 1) ? array_splice($tmp, 1) : array();
+    $tmp = explode('-', $baselayer_variant);
+    $baselayer_vendor = $tmp[0];
+    $variant = (count($tmp) > 1) ? strtolower($tmp[1]) : 'default';
+    $baselayers[$i]['baselayer_vendor'] = $baselayer_vendor;
+    $baselayers[$i]['variant'] = $variant;
+    $baselayers[$i]['baselayer_options'] = get_baselayer_options($baselayer_options);
+    $i++;
+  }
+  return $baselayers;
+}
+
+/**
+ *
+ */
+function get_baselayer_options($options) {
+  $baselayer_options = array();
+  foreach($options as $option) {
+    $tmp = explode('=', $option);
+    $baselayer_options[$tmp[0]] = $tmp[1];
+  }
+  return $baselayer_options;
+}
+
+/**
+ * @return javascript for baselayer options
+ */
+function get_baselayer_options_js($baselayer_options) {
+  $js = "var layer_options = {};\n";
+  foreach($baselayer_options as $option => $value) {
+    switch($option) {
+      case 'opacity':
+        $js .= "layer_options.opacity = $value;\n";
+        break;
+      case 'minzoomlevel':
+        $js .= "layer_options.MIN_ZOOM_LEVEL = $value;\n";
+        break;
+      case 'numzoomlevels':
+        $js .= "layer_options.numZoomLevels = $value;\n";
+        break;
+      default:
+        $js .= "layer_options.$option = $value;\n";
+        break;
+    }
+  }
+  return $js;
+}
