var gmaps = new Hash();
var gmarkers = new Hash();
var mapDefaults = new Hash();
var GMAPS_ACT_MARK = '_act';
var GMAPS_ACT_OWN = '_own';

function initMap(id, lat, lng, zoom, mode, noInit) {
	if (GBrowserIsCompatible()) {
		if(id && lat && lng) {
			activeMarker = null;
			var center = new GLatLng(lat, lng);
			var aMapDefault = {centerDef: center, zoomDef: zoom};
			mapDefaults.set(id, aMapDefault);
			var canvas = 'gmap_'+id+'_canvas';

			if($('gMaps_btnSearch_'+id)) {
				Event.observe('gMaps_btnSearch_'+id, 'click', function(event){
					event.preventDefault();
					var address = $('gMaps_query_'+id).getValue();
					var geocoder = new GClientGeocoder(); 
					geocoder.getLocations(address, function(response) {
						showResponse(response, id);
					}); 
				});
			}

			map = new GMap2(document.getElementById(canvas));
			if(mode && mode != '') {
				setMode(mode);
			}
			map.setCenter(center, zoom);
			map.setUIToDefault();
			
			GEvent.addListener(map, "moveend", function() {
				rememberCoords(id);
			});
			gmaps.set(id, map);			
		}
	}
}

function resetMap(id) {
	var aMapDefault = mapDefaults.get(id)
	if (aMapDefault) {
		var aMap = gmaps.get(id);
		aMap.setCenter(aMapDefault.centerDef, aMapDefault.zoomDef);
	}
}

function rememberCoords(id) {
	if($(id))
		$(id).setValue(getMapCoordsWithMarker(id));
}

function getMapCoordsWithMarker(id) {
	var coords = getMapCoords(id);
	var actMarker = gmaps.get(id+GMAPS_ACT_MARK);
	if(actMarker) {
		coords += '#' + actMarker.getPoint().lat() + '#' + actMarker.getPoint().lng();
	}
	return coords;
}

function getMapCoords(id) {
	var map = gmaps.get(id);
	return (map.getCenter().lat() + '#' + map.getCenter().lng() + '#' + map.getZoom());
}

function setMode(m, id) {
	mode = m;
	if (mode=='search') {
		if('gMaps_searchForm_'+id)
			$('gMaps_searchForm_'+id).show();
		if('gMaps_ownExpl_'+id)
			$('gMaps_ownExpl_'+id).hide();
		if('gMaps_matches_'+id)
			$('gMaps_matches_'+id).show();
	} else {
		if('gMaps_searchForm_'+id)
			$('gMaps_searchForm_'+id).hide();
		if('gMaps_ownExpl_'+id)
			$('gMaps_ownExpl_'+id).show();
		if('gMaps_matches_'+id)
			$('gMaps_matches_'+id).hide();

		var map = gmaps.get(id);
		if(map) {
			map.disableDoubleClickZoom();
			GEvent.addListener(map, "dblclick", function(x,p) {
				var own = gmaps.get(id+GMAPS_ACT_MARK);
				if (own != null) {
					map.removeOverlay( own );
				}
				var icon = new GIcon(G_DEFAULT_ICON);
				own = new GMarker( p , { icon: icon,draggable:true } );
				own.enableDragging();
				gmaps.set(id+GMAPS_ACT_MARK, own);
				GEvent.addListener(own, "dblclick", function(x,p) {
					map.removeOverlay( own );
				});
				map.addOverlay( own);
				gmaps.set(id+GMAPS_ACT_MARK, own);
				rememberCoords(id);
			});				
		}
	}
}

/*
 * Search mode
*/
function showResponse(response, id) {
	if (! response) {
		alert("Geocoder request failed");
	} else { 
		var map = gmaps.get(id);
		var markers = gmarkers.get(id);
		if (markers != null) {
			for (var i = 0; i < markers.length; i++) {
				map.removeOverlay(markers[i]);
			}
			gmarkers.unset(id);
		}
		listMatches(response, id);
		markers = gmarkers.get(id);
		if(markers) {
			for (var i = 0; i < markers.length; i++) {
				var marker = markers[i];
				map.addOverlay(marker);
				addMarkerClickListener(id, marker, null);
			} 
			if (markers.length > 0) {
				selectMarker(id, 0);
			}
		}			
	}
}

function listMatches(response, id) {
	var matchesHtml = '';
	if(response.Placemark) {
		var resultCount = response.Placemark.length;
		var icons = new Array(resultCount); 
		var markers = new Array(resultCount); 
		for (var i = 0; i < resultCount; i++) {
			var pm = response.Placemark[i];
			icons[i] = new GIcon(G_DEFAULT_ICON);
			var latlngs = new GLatLng(pm.Point.coordinates[1], pm.Point.coordinates[0]);
			markers[i] = new GMarker(latlngs, { icon: icons[i], draggable:true } ); 
			matchesHtml += "<div class=\"entry\" id=\""+id+"_entry_"+i+"\" onclick=\"selectMarker('"+id+"', '"+i+"')\">";
			matchesHtml += '<img src="' + icons[i].image + '" id="entryIcon'+i+'"/>';
			matchesHtml += pm.address;
			matchesHtml += '</div>';
		}
		gmarkers.set(id, markers);
	}
	$('gMaps_matches_'+id).update(matchesHtml);
}

function markMarkerInfos(id, n) {
	$$('.entry').each(function (e){
		e.removeClassName('selected');
		if (e.id==id+'_entry_'+n) {
			e.addClassName('selected');
		}
	});
}

function selectMarker(id, n) {
	var markers = gmarkers.get(id);
	if(markers) {
		var activeMarker = markers[n];
		markMarkerInfos(id, n);
		gmaps.set(id+GMAPS_ACT_MARK, activeMarker);
		GEvent.trigger(activeMarker, "click");
	}
}

function displaySelectionOfMarker(id, marker) {
	var map = gmaps.get(id);
	map.panTo(new GLatLng(marker.getPoint().lat(),marker.getPoint().lng())); 
}

function addMarker(id, lat, lng) {
	addMarker(id, lat, lng, null);
}

function addMarker(id, lat, lng, infoWindow) {
	addMarker(id, lat, lng, infoWindow, null);
}

function addMarker(id, lat, lng, infoWindow, markerId) {
	addMarker(id, lat, lng, infoWindow, markerId, null);
}

function addMarker(id, lat, lng, infoWindow, markerId, callback) {
	addMarker(id, lat, lng, infoWindow, markerId, callback, null);
}

function addMarker(id, lat, lng, infoWindow, markerId, callback, iconUrl) {
	var map = gmaps.get(id);
	if(map) {
		var marker;
		var latlng = new GLatLng(lat, lng);
		if(iconUrl) {
			var myIcon = new GIcon(G_DEFAULT_ICON);
			myIcon.image = iconUrl;
			markerOptions = {icon: myIcon};
			marker = new GMarker(latlng, markerOptions);
		} else {
			marker = new GMarker(latlng);			
		}
		map.addOverlay(marker);
		addMarkerClickListener(id, marker, infoWindow);
		if(markerId) {
			gmarkers.set(markerId, marker);
		}
		if(callback && typeof window[callback] == 'function') {
			window[callback](markerId, marker);
		}

	}	
}

function addMarkerClickListener(id, marker, infoWindow) {
	GEvent.addListener(marker, "click", function() {
		displaySelectionOfMarker(id, marker);			
		if(infoWindow)
			marker.openInfoWindow(infoWindow);
	});
}

function gmaps_Route_From(id) {
	$(id+'_route_from').show();
	$(id+'_route_to').hide();
}
function gmaps_Route_To(id) {
	$(id+'_route_from').hide();
	$(id+'_route_to').show();
}
