// public

var map;

function getMarkerBySoundId(id) {
	for (var i = 0; i < mapMarkers.length; i++) {
		var sounds = mapMarkers[i].sounds;
		for (var j = 0; j < sounds.length; j++) {
			if (sounds[j].id == id) { return mapMarkers[i]; }
		}
	}
	return null;
}

function selectMarker(marker) {
	if (typeof(marker) == "number") {
		marker = getMarkerBySoundId(marker);
	}
	if (marker) {
		marker.setImage(urlMarkerGo);
		marker.enableDragging();
		marker.selected = true;
	}
}

function deselectMarker(marker) {
	if (typeof(marker) == "number") {
		marker = getMarkerBySoundId(marker);
	}
	if (marker) {
		marker.setImage(urlMarker);
		marker.disableDragging();
		marker.selected = false;
	}
}

// draggable stuff

function nogeoSetDraggable(img) {
	img.onmousedown = nogeoMarkerOnMousedown;
	new Draggable(img, {
		revert: function() { return !($("map").hasClassName("nogeoHover")); },
		onStart: nogeoMarkerOnStart,
		onEnd: nogeoMarkerOnEnd
	});
}
function nogeoMarkerOnMousedown(e) {
	if (window.event) { e = window.event; }
	var offset = $(this).cumulativeOffset();
	this.mouseOffset = [e.pageX - offset[0], e.pageY - offset[1]];
}
function nogeoMarkerOnStart(draggable, e) {
	draggable.element.up("div.soundInstance").select();
	Droppables.add("map", {accept: "nogeoDraggable", hoverclass: "nogeoHover"});
}
function nogeoMarkerOnEnd(draggable, e) {
	if (!$("map").hasClassName("nogeoHover")) { return; }
	if (window.event) { e = window.event; }
	var offset = $("map").cumulativeOffset();
	var img = draggable.element;
	var pt = new GPoint(e.pageX - img.mouseOffset[0] + img.width/2 - offset[0],
	                    e.pageY - img.mouseOffset[1] + img.height  - offset[1]);
	//GLog.write("pt = " + pt.x + " " + pt.y);
	var gLatLng = map.fromContainerPixelToLatLng(pt);
	var marker = newMarker(gLatLng);
	selectMarker(marker);
	var nogeoMarker = draggable.element.up("div.nogeoMarker");
	nogeoMarker.hide();
	var sound = nogeoMarker.up("div.soundInstance").sound;
	sound.setLoc(gLatLng);
	marker.sounds = [sound];
	Droppables.remove("map");
}

// private

var urlMarker = "http://maps.google.com/mapfiles/marker.png";
var urlMarkerGo = "http://maps.google.com/mapfiles/dd-start.png"

var mapMarkers = [];

function initMap() {
	map = new GMap2(document.getElementById("map"));
	map.addMapType(G_SATELLITE_MAP);
	map.addControl(new GSmallZoomControl());
	map.setCenter(new GLatLng(projLat, projLng), projZoom);
	//map.setMapType(G_HYBRID_MAP);
	mediaHandlers.push(mapMediaHandler);
	GEvent.addListener(map, "dragend", rangeChanged);
	GEvent.addListener(map, "zoomend", rangeChanged);
	GEvent.addListener(map, "click", onMapClick);
}

function newMarker(latlng) {
	var marker = new GMarker(latlng, {icon: new GIcon(G_DEFAULT_ICON, urlMarker),
	                                  draggable: true});
	marker.disableDragging();
	GEvent.addListener(marker, "dragend", onMarkerDragend);
	map.addOverlay(marker);
	mapMarkers.push(marker);
	return marker;
}

function mapMediaHandler(data) {
	var visibleSounds = [];
	for (var i = 0; i < data.noGeo.length; i++) {
		var tmp = data.noGeo[i];
		var id = tmp[0];
		var sound = mediaInstances[id];
		if (!sound) { sound = new Media(id, tmp[1], tmp[2]); }
		sound.loc = [];
		visibleSounds.push(sound);
	}
	data = data.mapData;
	for (var i = 0; i < data.length; i++) {
		var row = data[i];
		var latlng = new GLatLng(row[0], row[1]);
		if (i < mapMarkers.length) {
			var marker = mapMarkers[i];
			marker.setLatLng(latlng);
		}
		else {
			var marker = newMarker(latlng);
		}
		marker.sounds = [];
		var selected = false; // update green highlight
		var mediaData = row[2];
		for (var j = 0; j < mediaData.length; j++) {
			var tmp = mediaData[j];
			var id = tmp[0];
			var sound = mediaInstances[id];
			if (!sound) { sound = new Media(id, tmp[1], tmp[2]); }
			marker.sounds.push(sound);
			if (sound.div) { visibleSounds.push(sound); }
			if (!selected && selectedSound && id == selectedSound.id) { selected = true; }
		}
		if (selected) {
			selectMarker(marker);
			//showSounds(marker.sounds);
		}
		else { deselectMarker(marker); }
	}
	showSounds(visibleSounds);
	while (data.length < mapMarkers.length) { map.removeOverlay(mapMarkers.pop()); }
}

function onMapClick(overlay, point) {
	if (overlay) {
		showSounds(overlay.sounds);
	}
	else if (point) {
		clearMapSoundDivs();
	}
}

function onMarkerDragend() {
	var marker = this;
	if (marker.selected && selectedSound) { // just to make sure
		selectedSound.setLoc(marker.getLatLng());
	}
}

