/*
	The plan now is to show a special icon when there are multiple pages at one location.
	There will not be numbers. When there is one page shown, show the icon for that page.
	When there are no pages shown, hide the marker.
*/
var GNAmapDot = function(lat, lon, pages) {
	this.lat = Number(lat);
	this.lon = Number(lon);
	this.pages = {};
	this.shown = [];
	for (var i=0; i<pages.length; i++) {
		this.pages[pages[i]] = GNAmap.pages[pages[i]];
		if (GNAmap.cats[this.pages[pages[i]].cat].shown) this.shown.push(pages[i]);
	}
	this.show();
};
GNAmapDot.prototype = {
	showAll: function() {
		for (var id in this.pages) this.shown.push(id);
		this.show();
	},
	hideAll: function() {
		this.shown = [];
		this.show();
	},
	hide: function(item_id) {
		// should be able to use array.splice, but they say it doesn't work in IE
		var newshown = [];
		for(var i=0; i<this.shown.length; i++) if (this.shown[i] != item_id) newshown.push(this.shown[i]);
		this.shown = newshown;
		this.show();
	},
	show: function(item_id) {
		if (this.pop) {
			this.pop.parentNode.removeChild(this.pop);
			this.pop = null;
		}
		if (item_id != undefined) this.shown.push(item_id);
		if (this.shown.length == 0) {
			if (this.marker) this.marker.hide();
		} else if (this.shown.length == 1) {
			if (this.marker) {
				this.marker.changeImage(GNAmap.cats[this.pages[this.shown[0]].cat].image);
				this.marker.unhide();
			} else {
				this.marker = new YMarker(
					new YGeoPoint(this.lat, this.lon),
					GNAmap.cats[this.pages[this.shown[0]].cat].image
				);
				YEvent.Capture(this.marker, EventsList.MouseOver, this.showLabel.bind(this)); 
				YEvent.Capture(this.marker, EventsList.MouseOut, (function(){  
					if (this.pop) this.pop.style.display = 'none';
					}).bind(this));
				YEvent.Capture(this.marker, EventsList.MouseClick, (function(){  
					if (parent) parent.location.href = this.pages[this.shown[0]].url;
					else window.location.href = this.pages[this.shown[0]].url;
				}).bind(this));
				GNAmap.map.addOverlay(this.marker);
			}
		} else {
			if (this.marker) {
				this.marker.changeImage(GNAmap.multiImage);
				this.marker.unhide();
			} else {
				this.marker = new YMarker(
					new YGeoPoint(this.lat, this.lon),
					GNAmap.multiImage
				);
				YEvent.Capture(this.marker, EventsList.MouseOver, this.showLabel.bind(this)); 
				YEvent.Capture(this.marker, EventsList.MouseOut, (function(){  
					this.timer = window.setTimeout(
						(function(){ this.pop.style.display = 'none'; }).bind(this),
						200
				);
				}).bind(this));
				GNAmap.map.addOverlay(this.marker);
			}
		}
	},
	showLabel: function() {
		GNAmap.clearPops();
		if (this.timer) {
			window.clearTimeout(this.timer);
			this.timer = null;
		}
		var coord = GNAmap.map.convertLatLonXY(new YGeoPoint(this.lat,this.lon));
		if (!this.pop) {
			this.pop = document.createElement('DIV');
			this.pop.className = 'map_label';
			if (this.shown.length == 1) {
				this.pop.innerHTML = this.pages[this.shown[0]].title;
			} else {
				var inner = '';
				for (var i=0; i<this.shown.length; i++) inner += '<a target="_parent" href="'
					+ this.pages[this.shown[i]].url + '">'
					+ this.pages[this.shown[i]].title + '</a>';
				this.pop.innerHTML = inner;
				this.pop.onmouseover = (function(){ window.clearTimeout(this.timer) }).bind(this);
				this.pop.onmouseout = (function(){
					this.timer = window.setTimeout(
						(function(){ this.pop.style.display = 'none'; }).bind(this),
						200
					);
				}).bind(this);
				GNAmap.pops.push(this);
			}
			GNAmap.labelParent.appendChild(this.pop);
		}
		this.pop.style.top = (coord.y + (GNAmap.enlarged? 17:160) ) + 'px';
		this.pop.style.left = (coord.x + (GNAmap.enlarged? 17:600) ) + 'px';
		this.pop.style.display = 'block';
	}
};
var GNAmap = {
	// The following must be set before calling init():
	// cats (object), pages (object), locs (object), enlarged (boolean), enlargeUrl (string), multiImageUrl (string)
	labelParent: 0, map: 0, multiImage: 0, pops: [],
	clearPops: function() {
		for(var i=0; i<this.pops.length; i++) {
			if (this.pops[i].pop) this.pops[i].pop.style.display = 'none';
			if (this.pops[i].timer) window.clearTimeout(this.pops[i].timer);
		}
		this.pops = [];
	},
	togCat: function(cb) {
		var cat_id = cb.id.split(':').pop();
		var pages = this.cats[cat_id].items;
		for (var i=0; i<pages.length; i++) {
			if (cb.checked) pages[i].dot.show(pages[i].id);
			else pages[i].dot.hide(pages[i].id);
		}
		if (cb.checked) this.map.panToLatLon(this.map.getCenterLatLon());		
		this.cats[cat_id].shown = cb.checked;
		if (!this.enlarged) this.updateEnlargeUrl();
	},
	togAll: function(cb) {
		for (var cat_id in this.cats) {
			this.cats[cat_id].shown = cb.checked;
			document.getElementById('cb:'+cat_id).checked = cb.checked;
		}
		if (cb.checked) {
			for(var loc in this.locs) this.locs[loc].showAll();
			this.map.panToLatLon(this.map.getCenterLatLon());		
		} else for(var loc in this.locs) this.locs[loc].hideAll();
		if (!this.enlarged) this.updateEnlargeUrl();
	},
	updateEnlargeUrl: function() {
		var cat_ids = [];
		for(var i in this.cats) if (this.cats[i].shown) cat_ids.push(i);
		if (cat_ids.length == 0) document.getElementById('map_enlarge_link').href = this.enlargeUrl + 'x';
		else document.getElementById('map_enlarge_link').href = this.enlargeUrl + cat_ids.join('_');
	},
	init: function() {
		this.labelParent = document.getElementsByTagName('BODY')[0];
		this.map = new YMap(document.getElementById('ymap'));
		var imgsize = new YSize(18,19);
		this.multiImage = new YImage(
			this.multiImageUrl,
			imgsize
		);
		try {
			this.map.drawZoomAndCenter(new YGeoPoint(33.74, -84.39), 9);
			this.map.removeZoomScale();
			this.map.addZoomShort();
			// load marker images
			for (var i in this.cats) {
				this.cats[i].image = new YImage(
					this.cats[i].icon,
					imgsize
				);
				var cb = document.getElementById('cb:'+i);
				cb.checked = this.cats[i].shown;
			}
			// set up locations
			for (var i in this.locs) {
				var coord = i.split(/,/);
				var dot = new GNAmapDot(coord[0], coord[1], this.locs[i]);
				for (var j=0; j<this.locs[i].length; j++) {
					var page = this.pages[this.locs[i][j]];
					if (!page) continue;
					page.id = this.locs[i][j];
					page.dot = dot;
					this.cats[page.cat].items.push(page);
				}
				this.locs[i] = dot;
			}
			var markerIDs = this.map.getMarkerIDs();
			for(var i=0; i<markerIDs.length; i++) document.getElementById(markerIDs[i]).className += ' map_label_wrap';
			// now also we need to hide the pages in the hidden categories!
		} catch(e) {alert(e.message);}
	}
};
