Event.observe(window, "load", function() {
	if(!GBrowserIsCompatible()) {
		alert("Your browser is not compatible with Google Maps.");
		return;
	}
	$(document.body).observe("mousemove", mouseMove);

	window.categoryBubbleTemplate = new Template($F(config.categoryBubbleId));
	window.categoryLinkTemplate = new Template($F(config.categoryLinkId));
	window.listBubbleTemplate = new Template($F(config.listBubbleId));
	window.listLinkTemplate = new Template($F(config.listLinkId));
	window.featureBubbleTemplate = new Template($F(config.featureBubbleId));
	window.featureLinkTemplate = new Template($F(config.featureLinkId));
	window.featureTooltipTemplate = new Template($F(config.featureTooltipId));

	window.map = new GMap2($("map"), { mapTypes: config.mapTypes || [G_HYBRID_MAP, G_NORMAL_MAP, G_SATELLITE_MAP] });
	map.setCenter(config.homeLocation, config.homeZoom);
	map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());

	window.table = window[config.table];
	window.relatedTable = window[table.relatedTable];

	if(!config.linkColumn) {
		config.linkColumn = table.columns[0];
	}
	if(config.featuresListId) {
		if(config.featuresSortColumn) {
			var index = table.columns.indexOf(config.featuresSortColumn);
			if(index != -1) {
				table.features = table.features.sort(function(a, b) { return a[index].strip().toLowerCase() > b[index].strip().toLowerCase() ? 1 : -1; });
			}
		}

		table.features.each(function(feature) {
			var obj = Geotools.makeFeatureObject(table, feature);
			obj.link = 'return featureLinkClick("' + obj[config.linkColumn] + '");';
			$(config.featuresListId).insert(featureLinkTemplate.evaluate(obj));
		});
	}

	relatedTable.features.each(function(feature) {
		map.addOverlay(Geotools.createMarker(table, feature, { click: markerClick.curry(feature[0]), mouseover: markerOver.curry(feature[0]), mouseout: markerOut.curry(feature[0]) }));
	});

	var hash = document.location.hash.substr(1);
	if(hash.indexOf("?") > -1) {
		hash = hash.substr(0, hash.indexOf("?"));
	}
	if(hash) {
		featureLinkClick(hash);
	}
});

var tooltips = {};
function markerClick(id) {
	window.marker = Geotools.getFeatureObject(relatedTable, id);
	if(!marker) return;

	var features = Geotools.getRelatedFeatures(table, marker);
	window.categories = Geotools.getCategories(table, features);
	var links = "";
	categories.each(function(c) {
		links += categoryLinkTemplate.evaluate(c);
	});
	marker.links = links;
	map.openInfoWindow(Geotools.getPoint(marker), categoryBubbleTemplate.evaluate(marker));

	return false;
}
function markerOver(id) {
	var tooltip = tooltips[id];
	if(!tooltip) {
		var obj = Geotools.getFeatureObject(relatedTable, id);
		if(!obj) return;
		tooltip = new Tooltip(null, Object.extend({ content: featureTooltipTemplate.evaluate(obj) }, window.tooltipOptions || {}));
		tooltips[id] = tooltip;
	}
	tooltip.show(moveEvent);
	return false;
}
function markerOut(id) {
	var tooltip = tooltips[id];
	if(!tooltip) return;
	tooltip.hide(moveEvent);
	return false;
}

function mouseMove(e) {
	window.moveEvent = e;
}


function categoryClick(name) {
	window.category = categories.find(function(c) {
		return c.category == name;
	});
	if(!category) return false;

	var links = "";
	category.features.each(function(f) {
		links += listLinkTemplate.evaluate(f);
	});
	category.links = links;
	category.back = 'return markerClick(' + marker.id + ');';
	map.openInfoWindow(Geotools.getPoint(marker), listBubbleTemplate.evaluate(category));

	return false;
}

function featureClick(id) {
	window.feature = category.features.find(function(f) {
		return f.id == id;
	});
	if(!feature) return false;

	feature.back = category.link;
	map.openInfoWindow(Geotools.getPoint(marker), featureBubbleTemplate.evaluate(feature));

	return false;
}

function featureLinkClick(id) {
	var index = table.columns.indexOf(function(c) {
		return c == config.linkColumn;
	});
	if(index == -1) index = 0;
	var feature = Geotools.makeFeatureObject(table, table.features.find(function(f) {
		return "" + f[index] == id;
	}));
	if(!feature) return false;

	var fk = feature[table.foreignKey];
	if(!fk) return false;

	var pkIndex = relatedTable.columns.indexOf(table.primaryKey);
	if(pkIndex == -1) return false;

	var marker = Geotools.makeFeatureObject(relatedTable, relatedTable.features.find(function(m) {
		return m[pkIndex] == fk;
	}));
	if(!marker) return false;

	var cat = feature[config.categoryColumn];
	if(!cat) return false;

	var features = Geotools.getRelatedFeatures(table, marker);
	if(features.length == 0) return false;

	var categories = Geotools.getCategories(table, features);
	var category = categories.find(function(c) {
		return c.category == cat;
	});
	if(!category) return false;

	window.marker = marker;
	window.categories = categories;
	window.category = category;
	feature.back = category.link;
	window.feature = feature;

	map.openInfoWindow(Geotools.getPoint(marker), featureBubbleTemplate.evaluate(feature));
	document.location = "#" + feature[config.linkColumn];

	return false;
}
