var map;
var geocoder;

var marker = new Array();
var infoWindows = new Array();

var current_marker;
var current_infowindow;
var noise = 0.00005;

var addressQueue = new Array();
var addressCache = new Array();

var geocodeTimer;

var canvas_id;

var yellowMarkerImage;
var origMarkerImage;

function map_multi_init(canvas) {
	geocoder = new google.maps.Geocoder();

	canvas_id = canvas;

	var latlng = new google.maps.LatLng(-28.53899, 153.548253);
	var myOptions = {
		zoom: 15,
		center: latlng,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		mapTypeControl: false
	};
	map = new google.maps.Map(document.getElementById(canvas_id), myOptions);

	geocodeTimer = setTimeout(geocodePop, 250);

	yellowMarkerImage = '/images/marker_yellow.png';

	return map;
}

function geocode_makeCallback(loc) {
	return function(result, status) {
		geocodeCallback(loc, result, status);
	};
}

function geocodePop() {
	if (addressQueue.length) {
		var loc = addressQueue.shift();
		if (addressCache[loc.address]) {
			geocodeCallback(loc, addressCache[loc.address], google.maps.GeocoderStatus.OK);
			geocodeTimer = setTimeout(geocodePop, 1);
			return;
		}
		else {
			if (geocoder) {
				geocoder.geocode( { 'address': loc.address }, geocode_makeCallback(loc));
			}
		}
		geocodeTimer = setTimeout(geocodePop, 100);
	}
}

function rand(lower, upper) {
	return (Math.random() * (upper - lower)) + lower;
}

function openInfoWindow(infoWindow, marker) {
	return function() {
		// Close the last selected marker before opening this one.
		if (current_infowindow)
			current_infowindow.close();
		if (current_marker) {
			current_marker.setZIndex(0);
			current_marker.setIcon(origMarkerImage);
		}

		marker.setIcon(yellowMarkerImage);
		marker.setZIndex(1000);
		infoWindow.open(map, marker);
		current_infowindow = infoWindow;
		current_marker = marker;
	};
}

function closeInfoWindow(e) {
	if (current_marker) {
		current_marker.setZIndex(0);
		current_marker.setIcon(origMarkerImage);
	}
}

function showmarker(id) {
	if (!marker[id]) {
		code_address(addresses[id]);
	}
	var $f = openInfoWindow(infoWindows[id], marker[id]);
	$f();
	Effect.ScrollTo(canvas_id);
}

function geocodeCallback(loc, results, status) {
	if (!marker[loc.id]) {
		if (status == google.maps.GeocoderStatus.OK) {
			var latlng = new google.maps.LatLng(results[0].geometry.location.lat() + rand(-noise, noise), results[0].geometry.location.lng() + rand(-noise, noise));
			// map.setCenter(latlng);
			var newMarker = new google.maps.Marker({
					map: map,
					position: latlng,
					title: loc.title,
					id: loc.id
			})
			var content = loc.domelem;
			if (!content) {
				content =  "<div class=\"accomitem\"><h2>";
				if (loc.image)
					content += "<img class=\"accompic\" src=\"" + loc.image + "\" alt=\"Image of " + loc.title + "\" />";
				content += loc.title + "</h2><h3>" + loc.address + "</h3>" + loc.description;
				if (loc.readmorelink)
					content += "<br /><a href=\"" + loc.readmorelink + "\">Read More...</a>";
				content += "</div>";
			}
			var newInfoWindow = new google.maps.InfoWindow({
				content: content,
				maxWidth: '300'
			});

			google.maps.event.addListener(newMarker, 'click', openInfoWindow(newInfoWindow, newMarker));
			google.maps.event.addListener(newInfoWindow, 'closeclick', closeInfoWindow);

			marker[loc.id] = newMarker;
			infoWindows[loc.id] = newInfoWindow;

			// get a default marker image
			if (!origMarkerImage)
				origMarkerImage = newMarker.getIcon();

			// add to cache
			addressCache[loc.address] = results;
// 			addressQueue.shift();
		} else {
			if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
				clearTimeout(geocodeTimer);
				geocodeTimer = setTimeout(geocodePop, 1000);
				// try again later
				addressQueue.push(loc);
			}
			else {
				console.log("Geocode failed on " + loc.address + " because: " + status);
				// remove item so we don't get stuck
// 				addressQueue.shift();
			}
		}
	}
}

function code_address(loc) {
	if (addressCache[loc.address]) {
		geocodeCallback(loc, addressCache[loc.address], google.maps.GeocoderStatus.OK);
	}
	else if (geocoder) {
		addressQueue.push(loc);
		// geocoder.geocode( { 'address': address }, geocodeCallback);
		if (geocodeTimer)
			clearTimeout(geocodeTimer);
		geocodeTimer = setTimeout(geocodePop, 100);
	}
}
