function createEventMarker (point, html, number) {
	var eventIcon = new GIcon();
		eventIcon.iconSize = new GSize(19, 27);
		eventIcon.iconAnchor = new GPoint(10, 27);
		eventIcon.infoWindowAnchor = new GPoint(10, 10);
		eventIcon.image = "/events/show_pin.php/" + number;

	var eventMarker = new GMarker(point, eventIcon);

	GEvent.addListener(eventMarker, "click", function() {
		eventMarker.openInfoWindowHtml(html);
	});

	return eventMarker;
}

function createCentreMarker (point) {
	var icon = new GIcon();
		icon.iconSize = new GSize(19, 27);
		icon.iconAnchor = new GPoint(10, 27);
		icon.infoWindowAnchor = new GPoint(10, 10);
		icon.image = "/events/images/event_icon_centre.gif";

	var marker = new GMarker(point, icon);

	return marker;
}

function HtmlEscape(str)
{
	if (str == null) {
		return "NULL STRING in HtmlEscape";
	}
	str = str.replace(new RegExp('&','gm'), '&amp;');
	str = str.replace(new RegExp('<','gm'), '&lt;');
	str = str.replace(new RegExp('>','gm'), '&gt;');
	return str;
}

// Return some HTML with names and links for all the events
// at this location.
function GetInfoWindowHtml(events)
{
	var html = "";
	for (var i in events) {
		var event = events[i];
		html += "<a href=\"" + event.link + "\">";
		html += HtmlEscape(event.title);
		html += "</a>, ";
		html += HtmlEscape(event.venue_name) + ".<br />";
	}
	return html;
}

function SetMarkerTitle(marker, title)
{
	// TODO. Make this work with Google maps 2.0
}

// Return a GLatLngBounds object which encloses all our points.
function FindBounds(extend)
{
	if (! extend) {
		extend = 0;
	}
	var minx = 180;
	var maxx = -180;
	var miny = 90;
	var maxy = -90;
	for (var i in map_marker_info) {
		var marker_info = map_marker_info[i];
		minx = Math.min(minx, marker_info.longitude);
		maxx = Math.max(maxx, marker_info.longitude);
		miny = Math.min(miny, marker_info.latitude);
		maxy = Math.max(maxy, marker_info.latitude);
	}
	minx -= extend;
	miny -= extend;
	maxx += extend;
	maxy += extend;
	
	return new GLatLngBounds(
		new GLatLng(miny, minx),
		new GLatLng(maxy, maxx));
}

// This controls the zoom level of single marker maps
var SMALL_DISTANCE = (1.0 / 360); // A one three hundred and sixtieth of a degree, or about half a mile(?), in the UK

// return a GLatLngBounds object which encloses our points and is
//	centred about cx, cy
function FindBoundsCentred(cx, cy, extend)
{
	var bounds = FindBounds(extend);
	var xdist = Math.max(Math.abs(bounds.getSouthWest().lng() - cx), 
		Math.abs(bounds.getNorthEast().lng() - cx));
	var ydist = Math.max(Math.abs(bounds.getSouthWest().lat() - cy), 
		Math.abs(bounds.getNorthEast().lat() - cy));
	bounds.extend(new GLatLng(cy - ydist, cx - xdist));
	bounds.extend(new GLatLng(cy + ydist, cx + xdist));
	return bounds;
}

function GetDefaultZoomLevel(map)
{
	var here = new GLatLng(51 - SMALL_DISTANCE, -1 - SMALL_DISTANCE);
	var there = new GLatLng(51 + SMALL_DISTANCE, -1 + SMALL_DISTANCE);
	return map.getBoundsZoomLevel(new GLatLngBounds(here, there));
}

var google_map_obj;
function SetupGoogleMap() 
{
	var container = document.getElementById("panel");
	if (! container) {
		return; // Nothing to put the map in.
	}
	container_class = $('#panel').attr('class');
	if ( container_class.indexOf('map') === -1 ) {
		return;
	}

	var events = false;
	if (map_marker_info.length > 0) {
		events = true;
	}
	
	if ( !window.map_centre_longitude && ! events) {
		// No centre, no events. Give up.
		return;
	}

	google_map_obj = new GMap2(container);
	var map = google_map_obj;
	map.addControl(new GSmallMapControl());
	var centreMarker = false;
	if (window.map_centre_longitude) {
		var centrePoint = new GLatLng(window.map_centre_latitude, window.map_centre_longitude);
//		var centreMarker = new GMarker(centrePoint);
		var centreMarker = createCentreMarker(centrePoint);
		if (events) var bounds = FindBoundsCentred(centrePoint.lng(), centrePoint.lat(),	
			SMALL_DISTANCE);
	} else if (events) {
		// No centre determined.
		var bounds = FindBounds(SMALL_DISTANCE);
		// Invent a centre point in the middle of the bounds.
		var centrePoint = new GLatLng(
				(bounds.getNorthEast().lat() + bounds.getSouthWest().lat()) / 2,
				(bounds.getNorthEast().lng() + bounds.getSouthWest().lng()) / 2);
	}
	if (events) {
		var zoomLevel = map.getBoundsZoomLevel(bounds);
		map.setCenter(centrePoint, zoomLevel);
	} else if (centrePoint) {
		map.setCenter(centrePoint, GetDefaultZoomLevel(map));
	}
	if (centreMarker) {
		map.addOverlay(centreMarker);
	}

	// Add markers...
	for (var i in map_marker_info) {
		var marker_info = map_marker_info[i];
		var index = marker_info.pin_number;
		var point = new GPoint (marker_info.longitude, marker_info.latitude);
		var title = marker_info.title + " - " +
			marker_info.venue_name;
		var html = GetInfoWindowHtml(marker_info.events);
		var marker = createEventMarker(point, html, index);
		map.addOverlay(marker);
		SetMarkerTitle(marker, title);
	}
	
}
