//////////////////////////////////////////////////////////////////////////////////
//
// $Id: map.js 364 2006-09-29 00:00:21Z paulegan $
//
// Google Maps wrapper for displaying photograph markers.
//
// paulegan@mail.com	2005-09-25
//


// Path to the album files:
var albumPath = "albums";


// Default map view:
var defaultMapPosition = new GLatLng(14, 25);
var defaultMapZoom = 2;


// Template for photo icons:
var photoIconBase = new GIcon();
photoIconBase.shadow = "images/map_icon-bg.png";
photoIconBase.iconSize = new GSize(120, 90);
photoIconBase.shadowSize = new GSize(149, 101);
photoIconBase.iconAnchor = new GPoint(17, 101);


// Map constructor: create a new photo map in the mapElement container.
// Changes in the albumStack are written to messageElement.
//
function Map(mapElement, messageElement)
{
	var map = new GMap2(mapElement);
	map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());

	this.map = map;
	this.albumStack = new Array();

	this.addAlbumStackListener(messageElement);

	var qs = this.parseQueryString();
	this.loadAlbum(qs.albumID, qs.position, qs.zoom);

	return this;
}


// Map.parseQueryString(): pull out the album ID, and map position & zoom 
// from the URL query-string.
//
Map.prototype.parseQueryString = function()
{
	var q = new QueryString();
	var data = {};

	data.albumID = q.value("album");

	if (q.value("latitude") && q.value("longitude")) {
		data.position = new GLatLng(parseFloat(q.value("latitude")),
			parseFloat(q.value("longitude")));
	}

	if (q.value("zoom")) {
		data.zoom = parseInt(q.value("zoom"));
	}
	return data;
}


// Map.loadAlbum(): load the album file, push the album ID onto the albumStack
// and show and album photos.
//
Map.prototype.loadAlbum = function(albumID, position, zoom)
{
	var map = this;

	if (!albumID) {
		albumID = this.albumStack.pop() || "index";
	}

	GDownloadUrl(albumPath+"/"+albumID+".xml", function(responseText, responseCode) {
		if (responseCode == 200) {
			map.albumStack.push(albumID);
			map.albumXml = GXml.parse(responseText)
			map.showAlbum(position, zoom);
		} else {
			GLog.writeHtml(responseText);
		}
	});

	return albumID;
}


// Map.showAlbum(): position the map (as specified by the arguments or
// using the album GeoLocation), and add photo markers for each photo
// in the album.
//
Map.prototype.showAlbum = function(position, zoom)
{
	var geoLocation = this.albumXml.getElementsByTagName("GeoLocation")[0];
	var photos = this.albumXml.getElementsByTagName("Photo");

	if (!position || !zoom) {
		if (geoLocation && geoLocation.parentNode == this.albumXml.documentElement) {
			position = new GLatLng(parseFloat(geoLocation.getAttribute("Latitude")),
				parseFloat(geoLocation.getAttribute("Longitude")));
			zoom = parseInt(geoLocation.getAttribute("Zoom"));			
		} else {
			position = defaultMapPosition;
			zoom = defaultMapZoom;
		}
	}

	this.map.clearOverlays();
	this.map.setCenter(position, zoom, G_HYBRID_MAP);

	for (var i = 0; i < photos.length; i++) {
		this.addMarker(photos[i]);
	}

	return true;
}


// Map.addMarker(): add a marker for the specified photo to the map.
// Photos marked as an album cover are treated slightly differently.
//
Map.prototype.addMarker = function(photo)
{
	var geoLocation = photo.getElementsByTagName("GeoLocation")[0];
	if (geoLocation) {
		var point = new GLatLng(parseFloat(geoLocation.getAttribute("Latitude")),
			parseFloat(geoLocation.getAttribute("Longitude")));
		var marker;
		if (photo.getAttribute("IsAlbumCover") == "true") {
			marker = this.albumMarker(photo, point);
		} else {
			marker = this.photoMarker(photo, point);
		}
		this.map.addOverlay(marker);
	}
	return true;
}


// Map.albumMarker(): create a photo marker which denotes another album.
// A click on such a marker load the specified album.
//
Map.prototype.albumMarker = function(photo, point)
{
	var marker = new GMarker(point, {icon:this.photoIcon(photo), 
		title:photo.getAttribute("Title")});
	var photoID = photo.getAttribute("ID");
	var map = this;
	GEvent.addListener(marker, "click", function() {
		map.loadAlbum(photoID);
	});
	return marker;
}


// Map.photoMarker(): create a photo marker.  A click on a photo marker
// opens the photo URL.
//
Map.prototype.photoMarker = function(photo, point)
{
	var marker = new GMarker(point, {icon:this.photoIcon(photo), 
		title:photo.getAttribute("Title")});
	var url = photo.getAttribute("URL");
	GEvent.addListener(marker, "click", function() {
		window.location = url;
	});
	return marker;
}


// Map.photoIcon(): create a photo icon using the photoIconBase template
// and the thumbnail from the specified photo.
//
Map.prototype.photoIcon = function(photo)
{
	var image = photo.getElementsByTagName("Thumbnail")[0];
	var icon = new GIcon(photoIconBase);
	icon.image = image.getAttribute("URL");
	return icon;
}


// Map.addAlbumStackListener(): setup a "movend" listener to update the
// albumStack list on the messageElement.
//
Map.prototype.addAlbumStackListener = function(messageElement)
{
	var map = this;
	GEvent.addListener(this.map, "moveend", function() {
		while (messageElement.firstChild) {
			messageElement.removeChild(messageElement.firstChild);
		}
		for (var i = 0; i < map.albumStack.length; i++) {
			var link = document.createElement("a");
			link.setAttribute("name", map.albumStack[i]);
			link.textContent = map.albumStack[i];
			link.onclick = function() {
				while (map.albumStack.pop() != this.name);
				return map.loadAlbum(this.name);
			};
			messageElement.appendChild(link);
		}
	});
	return true;
}

