# This patch file was generated by NetBeans IDE
# This patch can be applied using context Tools: Apply Diff Patch action on respective folder.
# It uses platform neutral UTF-8 encoding.
# Above lines and this line are ignored by the patching process.
Index: contributions/modules/mapstraction/mapstraction.drupal.js
--- contributions/modules/mapstraction/mapstraction.drupal.js Base (1.1.2.9.2.9)
+++ contributions/modules/mapstraction/mapstraction.drupal.js Locally Modified (Based On 1.1.2.9.2.9)
@@ -1,46 +1,83 @@
 // $Id: mapstraction.drupal.js,v 1.1.2.9.2.9 2010/05/18 18:36:10 loubabe Exp $
 Drupal.behaviors.mapstraction = function (context) {
   Drupal.mapstraction = [];
-  $(Drupal.settings.mapstraction).each(function() {
-    Drupal.mapstraction[this.mapId] = new mxn.Mapstraction(this.mapId, this.apiName);
 
-    // Set up hover behaviour.
-    if (this.behaviours) {
-      var hover = this.behaviours.hover;      
+  function preparePoint(row) {
+    return new mxn.LatLonPoint(Number(row.latitude), Number(row.longitude));
     }
 
-    // Set up markers and info bubbles.
-    for (var i in this.markers) {
-      var markerPoint = new mxn.LatLonPoint(Number(this.markers[i].latitude), Number(this.markers[i].longitude));
-      marker = new mxn.Marker(markerPoint);
+  /*
+   * Initialize marker object from a point data
+   */
+  function prepareMarker(row, hover) {
+    var markerPoint = preparePoint(row);
+    var marker = new mxn.Marker(markerPoint);
       
       // set info bubble if we have a title
-      if (this.markers[i].title) {
-        marker.setInfoBubble('<div class="mapstraction-info-window">'+ this.markers[i].title +'</div>');
+    if (row.text) {
+      marker.setInfoBubble('<div class="mapstraction-info-window">'+ row.text +'</div>');
       }
       
       // override default icon if provided
-      if (this.markers[i].icon) {
-        marker.setIcon(this.markers[i].icon.url, [this.markers[i].icon.width,this.markers[i].icon.height]);
+    if (row.icon) {
+      marker.setIcon(row.icon.url, [row.icon.width, row.icon.height]);
       }
 
       // set all attributes
-      if (this.markers[i].attributes){
-        for (var attr in this.markers[i].attributes) {
-          marker.setAttribute( attr, this.markers[i].attributes[attr] );
+    if (row.attributes){
+      $.each(row.attributes, marker.setAttribute);
         }        
-      }
 
       marker.setHover(hover);
-      Drupal.mapstraction[this.mapId].addMarker(marker);
+    return marker;
     }
 
+  function preparePolyline(row, points) {
+    var poly = new mxn.Polyline(points);
+
+      //Shuffle colors
+      var color = '#';
+      while(color.length < 7) {
+	color = color.concat((Math.round(Math.random() * 15)).toString(16));
+      }
+
+      poly.color = color;
+      poly.width = 2;
+      poly.opacity = 1;
+      poly.closed = false;
+      return poly;
+  }
+
+  function getGroupRenderer(map, behaviours, overlays) {
+    return function(row) {
+      var points = $.map(row.markers,
+        overlays.markers
+	  ? function(point) {
+	      var marker = prepareMarker(point, behaviours.hover);
+	      map.addMarker(marker);
+	      return marker.location;
+          }
+          : preparePoint);
+
+      if(overlays.polylines) {
+        var poly = preparePolyline(row, points);
+        map.addPolyline(poly);
+      }
+    };
+  }
+
+  $(Drupal.settings.mapstraction).each(function() {
+    var map = Drupal.mapstraction[this.mapId] = new mxn.Mapstraction(this.mapId, this.apiName);
+
+    // Set up markers and info bubbles.
+    $.map(this.markers, getGroupRenderer(map, this.behaviours, this.overlays));
+
     // Set up controls.
-    Drupal.mapstraction[this.mapId].addControls(this.controls);
+    map.addControls(this.controls);
     
     // add terrain option if dealing with Google
-    if (this.controls.map_type && G_PHYSICAL_MAP) {
-      Drupal.mapstraction[this.mapId].getMap().addMapType(G_PHYSICAL_MAP);
+    if (this.controls.map_type && typeof G_PHYSICAL_MAP != 'undefined') {
+      map.getMap().addMapType(G_PHYSICAL_MAP);
     }
 
     // default map type
@@ -49,21 +86,23 @@
       if(typeof(maptype) == 'string'){
         maptype = eval(maptype);
       }
-      Drupal.mapstraction[this.mapId].setMapType(maptype);
+      try {//OpenLayers throw 'Not implemented'
+        map.setMapType(maptype);
+      } catch(err) {}
     }
 
     // declutter markers
     if (this.behaviours && this.behaviours.declutter) {
-      Drupal.mapstraction[this.mapId].declutterMarkers();
+      map.declutterMarkers();
     }
 
     // Set auto center and zoom.
     if (this.initialPoint.auto) {
-      Drupal.mapstraction[this.mapId].autoCenterAndZoom();
+      map.autoCenterAndZoom();
     }
     else {
       var startPoint = new mxn.LatLonPoint(Number(this.initialPoint.latitude), Number(this.initialPoint.longitude));
-      Drupal.mapstraction[this.mapId].setCenterAndZoom(startPoint, Number(this.initialPoint.zoom));
+      map.setCenterAndZoom(startPoint, Number(this.initialPoint.zoom));
\ No newline at end of file
     }
   });
 };
Index: contributions/modules/mapstraction/mapstraction.module
--- contributions/modules/mapstraction/mapstraction.module Base (1.1.2.7.2.8)
+++ contributions/modules/mapstraction/mapstraction.module Locally Modified (Based On 1.1.2.7.2.8)
@@ -90,6 +90,7 @@
         'theme file' => 'mapstraction.module',
         'uses fields' => TRUE,
         'uses options' => TRUE,
+        'uses row plugin' => TRUE,
         'type' => 'normal',
       ),
     ),
@@ -205,10 +206,15 @@
     $api_script = call_user_func_array($api['render'], array($settings, $provider, $mapid));
   }
     
+  $library_path =
+    module_exists('libraries')
+      ? libraries_get_path('mapstraction') . '/source'
+      : drupal_get_path('module', 'mapstraction') . '/mapstraction/source';
+
   // load mxn core and provivder specific JS. Not using parameter approach due to drupal_add_js()
-  drupal_add_js(drupal_get_path('module', 'mapstraction') . '/mapstraction/source/mxn.js');
-  drupal_add_js(drupal_get_path('module', 'mapstraction') . '/mapstraction/source/mxn.core.js');
-  drupal_add_js(drupal_get_path('module', 'mapstraction') . '/mapstraction/source/mxn.'. $provider .'.core.js');
+  drupal_add_js($library_path . '/mxn.js');
+  drupal_add_js($library_path . '/mxn.core.js');
+  drupal_add_js($library_path . '/mxn.'. $provider .'.core.js');
   drupal_add_js(drupal_get_path('module', 'mapstraction') . '/mapstraction.drupal.js');
 
   $map = array(
@@ -218,6 +224,7 @@
     'controls' => $settings['controls'],
     'initialPoint' => $settings['initial_point'],
     'behaviours' => $settings['behaviours'],
+    'overlays' => $settings['overlays'],
\ No newline at end of file
   );
 
   // Add the map to Drupal.settings object in JS.
Index: contributions/modules/mapstraction/mapstraction_style_map.inc
--- contributions/modules/mapstraction/mapstraction_style_map.inc Base (1.1.2.13.2.8)
+++ contributions/modules/mapstraction/mapstraction_style_map.inc Locally Modified (Based On 1.1.2.13.2.8)
@@ -14,22 +14,31 @@
    * @author Lev Tsypin
    */
   function option_definition() {
-    $options['api'] = array();
+    $options = parent::option_definition();
+    
+    $options['api'] = array('default' => array());
     $options['width'] = array('default' => 'auto');
     $options['height'] = array('default' => '400px');
 
     $options['initial_point'] = array(
-      'auto' => TRUE,
-      'latitude' => '',
-      'longitude' => '',
-      'zoom' => 10,
+      'contains' => array(
+        'auto' => array('default' => TRUE),
+        'latitude' => array('default' => ''),
+        'longitude' => array('default' => ''),
+        'zoom' => array('default' => 10),
+      ),
     );
-    $options['controls'] = array();
-    $options['behaviours'] = array();
-    $options['zoon_control'] = array();
-    $options['default_maptype'] = array();
-    $options['fields'] = array();
     
+    $options['controls'] = array(
+      'contains' => array(
+        'zoom' => array('default' => 0),
+        'default_maptype' => array('default' => 1),
+      )
+    );
+    $options['behaviours'] = array('default' => array());
+    $options['overlays'] = array('default' => array('markers' => 'markers'));
+    $options['fields'] = array('default' => array());
+    
     return $options;
   }
 
@@ -40,6 +49,8 @@
    * @param string $form_state 
    */
   function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+
     $form['api'] = array(
       '#type' => 'select',
       '#title' => t('Mapping API'),
@@ -130,6 +141,16 @@
       '#default_value' => $this->options['behaviours'],
     );
 
+    $form['overlays'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Display following overlays types'),
+      '#options' => array(
+        'markers' => t('Markers'),
+        'polylines' => t('Polyines'),
+      ),
+      '#default_value' => $this->options['overlays'],
+    );
+
     $form['controls'] = array(
       '#type' => 'checkboxes',
       '#title' => t('Controls'),
@@ -237,7 +258,7 @@
    * Validate the options form.
    */
   function validate() {
-    $errors = array();
+    $errors = parent::validate();
 
     // Validate the field style for location.module's lat/lon fields. They
     // must be set to decimal degress.
@@ -258,8 +279,8 @@
    * Return output that will render the view as a map
    */
   function render() {
-    if ($this->view->preview == TRUE) {
-      return '<div class="messages error">Preview is disabled for the Mapstraction style plugin.</div>';
+    if ($this->view->preview == TRUE && $this->view->live_preview) {
+      return '<div class="messages error">Preview is disabled for the Mapstraction style plugin.</div>' . parent::render();
     }
     else {
       // Would like to use parent::render() here but there seems to be problem
@@ -273,65 +294,98 @@
       // Group the rows according to the grouping field, if specified.
       $sets = $this->render_grouping($this->view->result, $this->options['grouping']);
 
-      // Render each group separately and concatenate.  Plugins may override this
-      // method if they wish some other way of handling grouping.
-      $output = '';
+      $point_groups = array();
       foreach ($sets as $title => $records) {
-        if ($this->uses_row_plugin()) {
-          $rows = array();
-          foreach ($records as $label => $row) {
-            $rows[] = $this->row_plugin->render($row);
+        $point_groups[] = array(
+          'title' => $title,
+          'markers' => $this->map_points($records),
+        );
           }
-        }
-        else {
-          $rows = $records;
-        }
 
         if (is_string($this->options['dimensions'])) {
           list($this->options['width'], $this->options['height']) = explode('x', $this->options['dimensions']);
         }
 
-        $output .= mapstraction_render_map($this->view->name . '-' . $this->view->current_display, $this->view->style_plugin->options['api'], $this->options, $this->map_points());
+      return mapstraction_render_map(
+          $this->view->name . '-' . $this->view->current_display,
+          $this->view->style_plugin->options['api'],
+          $this->options,
+          $point_groups);
       }
-      return $output;
     }
-  }
 
   /**
-   * Convert views results into array of points to render on the map
+   * Convert views results into array of points to render on the map.
    */
-  function map_points() {
+  protected function map_points($rows = array()) {
+    //Calculate names once for all rows
+    $field_names = $this->map_fields($this->options['fields']);
     $points = array();
-    foreach ($this->rendered_fields as $field) {
+    $uses_row_plugin = $this->uses_row_plugin();
+    
+    foreach($rows as $row_index => $row) {
+      //an essential to use row_plugin->render()
+      $this->view->row_index = $row_index;
+      $point = self::map_point($row, $field_names);
+
+      if($uses_row_plugin) {
+        $point['text'] = $this->row_plugin->render($row);
+      }
+
+      $points[] = $point;
+    }
+    unset($this->view->row_index);
+    return $points;
+  }
+
+  /*
+   * Translate given fields of a single row into point data
+   */
+   static function map_point($row, $field_map) {
       $point = array();
-      foreach ($this->options['fields'] as $key => $value) {
-        // handle fields with more than one value
-        if (is_array($value)){
-          foreach($value as $item){
-            if (!empty($item)) {
-              $values[$item] = $field[$item];              
+    foreach ($field_map as $field_key => $field_name) {
+      if ($field_key == 'icon'){
+        $point[$field_key] = self::get_icon_field_value($row->{$field_name});
+      } else {
+        $point[$field_key] =
+          is_array($field_name)
+            ? self::map_point($row, $field_name)
+            : $row->{$field_name};
             }
           }
-          $point[$key] = $values;          
-        } elseif ($key == 'icon'){
-        // special case for icons as we want to get the image size  
-          $path = $field[$value];
-          if (!empty($path)){
-            if (is_file($path)){
-              list($width, $height) = getimagesize($path);
-              $point['icon']['width'] = $width;
-              $point['icon']['height'] = $height;            
-              $url = (url($path) == $path) ? $path : (base_path() . $path);
+    return $point;
             }
-            $point['icon']['url'] = $url;
+
+  /*
+   * Translate (recursively) fields' UI names into real names
+   */
+  protected function map_fields($fields) {
+    $field_names = array();
+    foreach($fields as $field_key => $field_name) {
+      if(!empty($field_name)) {
+        $name =
+          is_array($field_name)
+            ? $this->map_fields($field_name)
+            : $this->view->display_handler->get_handler('field', $field_name)->field_alias;
+
+        if(!empty($name)) {
+          $field_names[$field_key] = $name;
           }
-        } else {
-          $point[$key] = $field[$value];
         }
       } 
-      $points[] = $point;
+    return $field_names;
     }
 
-    return $points;
+  // special case for icons as we want to get the image size
+  private static function get_icon_field_value($path) {
+    $field = array();
+    if (!empty($path)){
+      if (is_file($path)){
+         list($field['width'], $field['height']) = getimagesize($path);
+         $path = (url($path) == $path) ? $path : (base_path() . $path);
   }
+      $field['url'] = $path;
 }
+    return $field;
+  }
+}
\ No newline at end of file
