Index: /extensions/rv_gmaps/trunk/admin/admin.php
===================================================================
--- /extensions/rv_gmaps/trunk/admin/admin.php	(revision 12699)
+++ /extensions/rv_gmaps/trunk/admin/admin.php	(revision 12700)
@@ -26,6 +26,6 @@
 $template->assign_var_from_handle( 'ADMIN_CONTENT', 'plugin_admin_content');
 
-if ( empty($conf['gmaps_api_key']) )
-  $page['infos'][] = 'Please define the Google maps api key';
+/*if ( empty($conf['gmaps_api_key']) )
+  $page['infos'][] = 'Please define the Google maps api key';*/
 
 ?>
Index: /extensions/rv_gmaps/trunk/admin/admin_config.php
===================================================================
--- /extensions/rv_gmaps/trunk/admin/admin_config.php	(revision 12699)
+++ /extensions/rv_gmaps/trunk/admin/admin_config.php	(revision 12700)
@@ -6,12 +6,27 @@
 if ( isset($_POST['submit']) )
 {
-  $query = '
+  if (isset($_POST['gmaps_api_key']))
+  {
+    $query = '
 UPDATE '.CONFIG_TABLE.'
   SET value="'.$_POST['gmaps_api_key'].'"
   WHERE param="gmaps_api_key"
   LIMIT 1';
-  pwg_query($query);
-  list($conf['gmaps_api_key']) = array_from_query('SELECT value FROM '.CONFIG_TABLE.' WHERE param="gmaps_api_key"', 'value');
+    pwg_query($query);
+    list($conf['gmaps_api_key']) = array_from_query('SELECT value FROM '.CONFIG_TABLE.' WHERE param="gmaps_api_key"', 'value');
+  }
 
+  if (isset($_POST['gmaps_auto_sync']))
+  {
+    conf_update_param('gmaps_auto_sync', "1");
+    $conf['gmaps_auto_sync']=1;
+  }
+  else
+  {
+    $query = 'DELETE FROM '.CONFIG_TABLE.' WHERE param="gmaps_auto_sync"';
+    pwg_query($query);
+    unset($conf['gmaps_auto_sync']);
+  }
+  
   $gm_config = rvm_get_config();
 
@@ -42,4 +57,5 @@
       'NB_GEOTAGGED' => $nb_geotagged,
       'GMAPS_API_KEY' => $conf['gmaps_api_key'],
+      'GMAPS_AUTO_SYNC' => isset($conf['gmaps_auto_sync']) ? 1:0,
       'NB_MARKERS' => rvm_get_config_var('nb_markers',40),
       'NB_IMAGES_PER_MARKER' => rvm_get_config_var('nb_images_per_marker',20),
Index: /extensions/rv_gmaps/trunk/admin/admin_config.tpl
===================================================================
--- /extensions/rv_gmaps/trunk/admin/admin_config.tpl	(revision 12699)
+++ /extensions/rv_gmaps/trunk/admin/admin_config.tpl	(revision 12700)
@@ -4,17 +4,25 @@
 <form method="post" action="" class="properties">
 <fieldset>
-  <legend>Map configuration</legend>
-  <ul>
-  
-  <li>
-  <label>
-    Google Maps API Key:
-    <input type="text" size="48" name="gmaps_api_key" value="{$GMAPS_API_KEY}" />
-  </label>
-    <br/>Signup for the key here: <a href="http://www.google.com/apis/maps/signup.html" target="_blank">http://www.google.com/apis/maps/signup.html</a>.
-  </li>
-  
-  <br/>
-  
+	<legend>Map configuration</legend>
+	<ul>
+
+	<!--<li>
+	 <label>
+		Google Maps API Key:
+		<input type="text" size="48" name="gmaps_api_key" value="{$GMAPS_API_KEY}" />
+	</label>
+		<br/>Signup for the key here: <a href="http://www.google.com/apis/maps/signup.html" target="_blank">http://www.google.com/apis/maps/signup.html</a>.
+	</li>
+	<br/> -->
+
+	<li>
+	 <label>
+		Automatically sync from exif
+		<input type="checkbox" name="gmaps_auto_sync" {if $GMAPS_AUTO_SYNC}checked="checked"{/if} />
+		</label>
+		<br/><small>When metadata is synchronized, tour manual set coordinates might be overriden.</small>
+	</li>
+	<br/>
+
   <li>
   <label>
@@ -24,7 +32,7 @@
     <br/><small>The images will be "clustered" based on this number and the visible region on the map.</small>
   </li>
-  
+
   <br/>
-  
+
   <li>
   <label>
Index: /extensions/rv_gmaps/trunk/include/functions.php
===================================================================
--- /extensions/rv_gmaps/trunk/include/functions.php	(revision 12699)
+++ /extensions/rv_gmaps/trunk/include/functions.php	(revision 12700)
@@ -36,7 +36,4 @@
 function rvm_make_map_picture_url($params)
 {
-	global $conf;
-	if ( empty($conf['gmaps_api_key']) and $_SERVER['SERVER_ADDR']!='127.0.0.1' )
-		return "";
 	$map_url = make_picture_url($params);
 	return add_url_params($map_url, array('map'=>null) );
@@ -45,7 +42,4 @@
 function rvm_duplicate_map_picture_url()
 {
-	global $conf;
-	if ( empty($conf['gmaps_api_key']) and $_SERVER['SERVER_ADDR']!='127.0.0.1' )
-		return "";
 	$map_url = duplicate_picture_url();
 	return add_url_params($map_url, array('map'=>null) );
@@ -55,6 +49,4 @@
 {
 	global $conf, $rvm_dir;
-	if ( empty($conf['gmaps_api_key']) and $_SERVER['SERVER_ADDR']!='127.0.0.1' )
-		return "";
 	$url = get_root_url().'map';
 	if ($conf['php_extension_in_urls'])
Index: /extensions/rv_gmaps/trunk/main.inc.php
===================================================================
--- /extensions/rv_gmaps/trunk/main.inc.php	(revision 12699)
+++ /extensions/rv_gmaps/trunk/main.inc.php	(revision 12700)
@@ -106,11 +106,8 @@
 			global $rvm_dir;
 			$map_url = rvm_duplicate_map_picture_url();
-			if (!empty($map_url))
-			{
-				$link_title = sprintf( l10n('displays %s on a map'), strip_tags($pictures['current']['name']) );
-				$template->concat( 'PLUGIN_PICTURE_ACTIONS' , sprintf(RVM_ACTION_MODEL,
+			$link_title = sprintf( l10n('displays %s on a map'), strip_tags($pictures['current']['name']) );
+			$template->concat( 'PLUGIN_PICTURE_ACTIONS' , sprintf(RVM_ACTION_MODEL,
 					$map_url, $link_title, ' target="_top"', 'map', 'map'
 				));
-			}
 		}
 	}
Index: /extensions/rv_gmaps/trunk/template/data_handler.js
===================================================================
--- /extensions/rv_gmaps/trunk/template/data_handler.js	(revision 12699)
+++ /extensions/rv_gmaps/trunk/template/data_handler.js	(revision 12700)
@@ -11,5 +11,6 @@
 		, opts || {} );
 
-	google.maps.event.addListener( map, "infowindowclose", function() {map.getInfoWindow().pwgMarker=null;} );
+	google.maps.event.bind( this._map, "click", this, this._onMapClick);
+	google.maps.event.bind( this._infoWindow, "domready", this, this._onInfoWindowDomReady);
 }
 
@@ -21,5 +22,6 @@
 _markers: [],
 _navHtmlIds: ["gotoPrevImage", "gotoNextImage"],
-_timerBindPictureNavigation: null,
+_navHtmlHandles: [],
+_recursionProtect: 0,
 _prevResult: { nb_items:0 },
 
@@ -69,5 +71,5 @@
 	{
 		var newMarkers = [];
-		var infoWindowMarker = this._infoWindow.pwgMarker;
+		var infoWindowMarker = this._infoWindow.getAnchor();
 
 		for (i=0; i<data.image_clusters.length; i++)
@@ -84,8 +86,6 @@
 			if (marker && marker==infoWindowMarker)
 			{
-        marker.setMap(null);
-				google.maps.event.clearListeners(marker, "click" );
-				google.maps.event.clearListeners(marker, "dblclick" );
-				this._infoWindow.pwgMarker = infoWindowMarker = null;
+				marker.setMap(null);
+				google.maps.event.clearInstanceListeners(marker);
 				if (document.is_debug) glog('removed marker with infoWindow');
 				marker = this._markers.pop();
@@ -95,9 +95,8 @@
 			{
 				marker = new google.maps.Marker(this.options.markerOptions);
-        marker.setPosition(cluster.position);
-        marker.setTitle(theTitle);
+				marker.setPosition(cluster.position);
+				marker.setTitle(theTitle);
 				google.maps.event.addListener( marker, "click", pwgBind(this, this._onMarkerClick, marker) );
 				google.maps.event.addListener( marker, "dblclick", pwgBind(this, this._onMarkerDblClick, marker) );
-        marker.setMap(this._map);
 			}
 			else
@@ -106,6 +105,6 @@
 				marker.setPosition( cluster.position );
 				marker.setTitle(theTitle);
-				marker.setMap(this._map);
 			}
+			marker.setMap(this._map);
 
 			newMarkers.push(marker);
@@ -122,10 +121,8 @@
 		{
 			this._markers[i].setMap(null);
-			google.maps.event.clearListeners(this._markers[i], "click" );
-			google.maps.event.clearListeners(this._markers[i], "dblclick" );
+			google.maps.event.clearInstanceListeners(this._markers[i]);
 		}
 
 		this._markers = newMarkers;
-
 		this._prevResult.nb_items=data.nb_items;
 	}
@@ -136,5 +133,5 @@
 _onMarkerClick: function( marker )
 {
-	if (this._infoWindow.pwgMarker == marker )
+	if (this._infoWindow.getAnchor() == marker )
 		return; // already open
 	var content = "";
@@ -160,13 +157,11 @@
 	content += '<div id="pwgImageDetail">' + this.buildCurrentPictureHtml( marker ) + '</div>';
 
+	var h;
+	while (h = this._navHtmlHandles.pop())
+		google.maps.event.removeListener(h);
+
 	this._infoWindow.setContent( content );
 	this._infoWindow.setPosition( marker.getPosition() );
-	this._infoWindow.open( this._map );
-
-	// bind to next / prev a little later because sometimes the nodes are not immediately created
-	if (this._timerBindPictureNavigation) clearTimeout(this._timerBindPictureNavigation);
-	this._timerBindPictureNavigation = null;
-	if (marker.pwg.images.length>1)
-		this._timerBindPictureNavigation = setTimeout( pwgBind(this, this._onTimeoutBindPictureNavigation, marker), 250 );
+	this._infoWindow.open( this._map, marker );
 },
 
@@ -174,4 +169,9 @@
 {
 	this._map.fitBounds( marker.pwg.bounds );
+},
+
+_onMapClick: function( marker )
+{
+	this._infoWindow.close();
 },
 
@@ -204,14 +204,21 @@
 
 
-_onTimeoutBindPictureNavigation: function( marker )
-{
-	clearTimeout(this._timerBindPictureNavigation);
-	this._timerBindPictureNavigation = null;
-	this._infoWindow.pwgMarker = marker;
-	for (var i=0; i< this._navHtmlIds.length; i++)
-	{
-		var elt = document.getElementById( this._navHtmlIds[i] );
-		if (elt)
-			google.maps.event.addDomListener(elt, "click", pwgBind(this, this._onPictureNavigate, marker, i) );
+_onInfoWindowDomReady: function()
+{
+	if (this._recursionProtect)
+		return;
+	if (!this._infoWindow.getAnchor() || this._infoWindow.getAnchor().pwg.images.length<2)
+		return;
+	try {
+		this._recursionProtect = 1;
+		for (var i=0; i< this._navHtmlIds.length; i++)
+		{
+			var elt = document.getElementById( this._navHtmlIds[i] );
+			if (elt)
+				this._navHtmlHandles.push( google.maps.event.addDomListener(elt, "click", pwgBind(this, this._onPictureNavigate, this._infoWindow.getAnchor(), i) ) );
+		}
+	}
+	finally {
+		this._recursionProtect = 0;
 	}
 },
Index: /extensions/rv_gmaps/trunk/template/data_loader.js
===================================================================
--- /extensions/rv_gmaps/trunk/template/data_loader.js	(revision 12699)
+++ /extensions/rv_gmaps/trunk/template/data_loader.js	(revision 12700)
@@ -4,5 +4,5 @@
 	this.options = jQuery.fn.extend(
 		{
-			reload_data_timeout: 500,
+			reload_data_timeout: 200,
 			rectangle_of_confusion: new google.maps.Size(32,16)
 		}
@@ -92,18 +92,4 @@
 			if ( this._map.getZoom() <= this._previousLoadDataReq.zoom )
 				return;
-			else
-			{
-				if (
-					this._map.getZoom() == this._previousLoadDataReq.zoom + 1
-					&& this._map.getZoom() < this._map.getBoundsZoomLevel(this._previousLoadDataReq.resultBounds)
-					)
-				{
-					if (document.is_debug) google.maps.Log.write('no load: zoom crt: '+this._map.getZoom()+'; prev: '+this._previousLoadDataReq.zoom+'; target: '+this._map.getBoundsZoomLevel(this._previousLoadDataReq.resultBounds));
-					return;
-				}
-			}
-		}
-		else
-		{
 		}
 	}
Index: /extensions/rv_gmaps/trunk/template/map.tpl
===================================================================
--- /extensions/rv_gmaps/trunk/template/map.tpl	(revision 12699)
+++ /extensions/rv_gmaps/trunk/template/map.tpl	(revision 12700)
@@ -59,8 +59,9 @@
 	var mapOptions = {
 		mapTypeId: google.maps.MapTypeId.ROADMAP,
-		overviewMapControl: true
-	}
-
-	if (1/*!PageLinker.url2Map(mapOptions)*/)
+		overviewMapControl: true,
+		overviewMapControlOptions: {opened: true}
+	}
+
+	if (!PageLinker.url2Map(mapOptions))
 	{
 {/literal}
@@ -106,5 +107,5 @@
 		);
 
-	map.pwgDataHandler = new PwgDataHandler(map, {icon: pwgMarkerOptions, show_all_img_src: "{/literal}{$PLUGIN_ROOT_URL}{literal}/icons/pic_s.gif" } );
+	map.pwgDataHandler = new PwgDataHandler(map, {markerOptions: pwgMarkerOptions, show_all_img_src: "{/literal}{$PLUGIN_ROOT_URL}{literal}/icons/pic_s.gif" } );
 	google.maps.event.addListener(map.pwgDataLoader, "dataloaded", pwgBind(map.pwgDataHandler, map.pwgDataHandler.handle) );
 
Index: /extensions/rv_gmaps/trunk/template/markers/small_bullet_orange.tpl
===================================================================
--- /extensions/rv_gmaps/trunk/template/markers/small_bullet_orange.tpl	(revision 12699)
+++ /extensions/rv_gmaps/trunk/template/markers/small_bullet_orange.tpl	(revision 12700)
@@ -1,6 +1,7 @@
-var icon = new google.maps.Icon();
-icon.image = "{$PLUGIN_ROOT_URL}/template/markers/small_bullet_orange.png";
-icon.iconSize = new google.maps.Size(11, 11);
-icon.iconAnchor = new google.maps.Point(5, 5);
-icon.infoWindowAnchor = new google.maps.Point(5, 0);
-return icon;
+return {ldelim}
+	rectangle_of_precision: new google.maps.Size(11, 11),
+	icon: new google.maps.MarkerImage("{$PLUGIN_ROOT_URL}/template/markers/small_bullet_orange.png",
+			new google.maps.Size(11, 11), 
+			new google.maps.Point(0, 0),
+			new google.maps.Point(5, 0))
+}
Index: /extensions/rv_gmaps/trunk/template/markers/small_bullet_red.tpl
===================================================================
--- /extensions/rv_gmaps/trunk/template/markers/small_bullet_red.tpl	(revision 12699)
+++ /extensions/rv_gmaps/trunk/template/markers/small_bullet_red.tpl	(revision 12700)
@@ -1,6 +1,7 @@
-var icon = new google.maps.Icon();
-icon.image = "{$PLUGIN_ROOT_URL}/template/markers/small_bullet_red.png";
-icon.iconSize = new google.maps.Size(11, 11);
-icon.iconAnchor = new google.maps.Point(5, 5);
-icon.infoWindowAnchor = new google.maps.Point(5, 0);
-return icon;
+return {ldelim}
+	rectangle_of_precision: new google.maps.Size(11, 11),
+	icon: new google.maps.MarkerImage("{$PLUGIN_ROOT_URL}/template/markers/small_bullet_red.png",
+			new google.maps.Size(11, 11), 
+			new google.maps.Point(0, 0),
+			new google.maps.Point(5, 5))
+}
Index: /extensions/rv_gmaps/trunk/template/markers/small_bullet_yellow.tpl
===================================================================
--- /extensions/rv_gmaps/trunk/template/markers/small_bullet_yellow.tpl	(revision 12699)
+++ /extensions/rv_gmaps/trunk/template/markers/small_bullet_yellow.tpl	(revision 12700)
@@ -1,6 +1,7 @@
-var icon = new google.maps.Icon();
-icon.image = "{$PLUGIN_ROOT_URL}/template/markers/small_bullet_yellow.png";
-icon.iconSize = new google.maps.Size(11, 11);
-icon.iconAnchor = new google.maps.Point(5, 5);
-icon.infoWindowAnchor = new google.maps.Point(5, 0);
-return icon;
+return {ldelim}
+	rectangle_of_precision: new google.maps.Size(11, 11),
+	icon: new google.maps.MarkerImage("{$PLUGIN_ROOT_URL}/template/markers/small_bullet_yellow.png",
+			new google.maps.Size(11, 11), 
+			new google.maps.Point(0, 0),
+			new google.maps.Point(5, 5))
+}
Index: /extensions/rv_gmaps/trunk/template/page_linker.js
===================================================================
--- /extensions/rv_gmaps/trunk/template/page_linker.js	(revision 12699)
+++ /extensions/rv_gmaps/trunk/template/page_linker.js	(revision 12700)
@@ -1,74 +1,70 @@
 function PageLinker(map, aElementId)
 {
-  this._map = map;
-  this._elementId = aElementId;
+	this._map = map;
+	this._elementId = aElementId;
 
-  google.maps.event.bind( this._map, "idle", this, this._regenerateUrl );
-  google.maps.event.bind( this._map, "maptypeid_changed", this, this._regenerateUrl );
+	google.maps.event.bind( this._map, "idle", this, this._regenerateUrl );
+	google.maps.event.bind( this._map, "maptypeid_changed", this, this._regenerateUrl );
 }
 
 PageLinker.getQueryVars = function()
 {
-  var vars = {};
-  var qString = unescape( top.location.search.substring(1) );
-  if (qString.length==0)
-    return vars;
-  var pairs = qString.split(/\&/);
-  for (var i=0; i<pairs.length; i++ )
-  {
-    var nameVal = pairs[i].split(/\=/);
-    vars[nameVal[0]] = nameVal[1];
-  }
-  return vars;
+	var vars = {};
+	var qString = unescape( top.location.search.substring(1) );
+	if (qString.length==0)
+		return vars;
+	var pairs = qString.split(/\&/);
+	for (var i=0; i<pairs.length; i++ )
+	{
+		var nameVal = pairs[i].split(/\=/);
+		vars[nameVal[0]] = nameVal[1];
+	}
+	return vars;
 };
 
 PageLinker.map2Url = function( map )
 {
-  var vars = PageLinker.getQueryVars();
-  vars['ll'] = map.getCenter().toUrlValue(5);
-  vars['z'] = map.getZoom();
-  if ( map.getMapTypeId()===google.maps.MapTypeId.ROADMAP )
-    { if (vars['t']) vars['t']=null; }
-  else
-    vars['t']=map.getMapTypeId();
+	var vars = PageLinker.getQueryVars();
+	vars['ll'] = map.getCenter().toUrlValue(5);
+	vars['z'] = map.getZoom();
+	if ( map.getMapTypeId()===google.maps.MapTypeId.ROADMAP )
+		{ if (vars['t']) vars['t']=null; }
+	else
+		vars['t']=map.getMapTypeId();
 
-  var url = document.location.protocol+'//'+document.location.hostname+document.location.pathname;
-  var bFirst = true;
-  for (var key in vars)
-  {
-    url += bFirst ? "?" : "&";
-    bFirst = false;
-    url += key;
-    if (vars[key]!=null)
-      url += "="+vars[key];
-  }
-  return url;
+	var url = document.location.protocol+'//'+document.location.hostname+document.location.pathname;
+	var bFirst = true;
+	for (var key in vars)
+	{
+		url += bFirst ? "?" : "&";
+		bFirst = false;
+		url += key;
+		if (vars[key]!=null)
+			url += "="+vars[key];
+	}
+	return url;
 };
 
 PageLinker.url2Map = function( mapOptions )
 {
-  var vars = PageLinker.getQueryVars();
-  if ( !( (vars['z'] && vars['ll']) || vars['t'] ) )
-    return false;
+	var vars = PageLinker.getQueryVars();
+	if ( !( (vars['z'] && vars['ll']) || vars['t'] ) )
+		return false;
 
-  var mapType = google.maps.MapTypeId.ROADMAP;
-  if  (vars['t'])
-  for (var i=0; i<map.getMapTypes().length; i++)
-    if ( map.getMapTypes()[i].getUrlArg()==vars['t'] )
-    {
-      mapOptions.mapTypeId = map.getMapTypes()[i];break;
-    }
-  
-  if (vars['z'] && vars['ll'])
-  {
-    mapOptions.zoom = parseFloat(vars['z']);
-    var ll = vars['ll'].split( "," );
-    if (ll.length==2)
-    {
-      mapOptions.center = new google.maps.LatLng( ll[0], ll[1] );
-    }
-    return true;
-  }
-  return false;
+	var mapType = google.maps.MapTypeId.ROADMAP;
+	if  (vars['t'])
+		mapOptions.mapTypeId = vars['t'];
+	
+	if (vars['z'] && vars['ll'])
+	{
+		mapOptions.zoom = parseFloat(vars['z']);
+		var ll = vars['ll'].split( "," );
+		if (ll.length==2)
+		{
+			mapOptions.center = new google.maps.LatLng( ll[0], ll[1] );
+		}
+		return true;
+	}
+	return false;
 }
 
