/*
 * A map displayer for Local Secrets
 *
 * Copyright (c) 2008 Dave Cleal
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  See <http://www.gnu.org/licenses/>.
 *
 * INSTRUCTIONS
 *
 * The page that uses this script needs to define
 *  some data like this:
 *  
 *   var towns = [ 
 *      { id: "camb", name: "Cambridge", xPos: 125, yPos: 45, xLabelPos: 134, yLabelPos: 62, url: '#', townsNearby: ["saff"]},
 *      { id: "hunt", name: "Huntingdon", xPos: 40, yPos: 40, xLabelPos: 37, yLabelPos: 49, url: '#', townsNearby: []},
 *      { id: "saff", name: "Saffron<br />Walden", xPos: 128, yPos: 75, xLabelPos: 124, yLabelPos: 79, url: '#', townsNearby: ["camb"]}
 *   ];
 *
 * Most of these properties should be obvious, the townsNearby should list the ids of other towns within 50 miles so that
 * they can be coloured lighter red when the map is displayed.
 * 
 * The page must then make a call like this (for preference, at load time):
 * 
 * drawMap('camb', towns, 'themap');
 * 
 * where 
 *  'camb' is the id of the town to select first,
 *  towns is the data defined earlier,
 *  'themap' is the id of a relatively positioned div that will contain the map
 *
 * Next, the caller must define a load of styles. Here's a sample set. You can change the urls of the images to make it look
 * different: but see note below on images.
 *
 * #themap { position: relative; border: 1px black solid; background-color: #0078c1; width: 500; height: 300; left: 60px; top: 30px; }
 * #themap div { position: absolute; }
 * #themap div.borderselected, #themap div.borderhighlighted, #themap div.border, #themap div.borderoverlapped { width: 74px; height: 74px; }
 * #themap div.border { background: transparent url(redcircle.png) no-repeat top left; z-index: 11; }
 * #themap div.borderoverlapped { background: transparent url(lightredcircle.png) no-repeat top left; z-index: 11; }
 * #themap div.borderhighlighted { background: transparent url(whitecircle.png) no-repeat top left; z-index: 11; }
 * #themap div.borderselected { background: transparent url(filledcircle.png) no-repeat top left; z-index: 1; }
 * #themap div.location { width: 10px; height: 10px; z-index: 10; cursor: pointer; cursor: hand; line-height: 1; z-index: 12; }
 * #themap div.maplink, #themap div.maplinkselected { cursor: pointer; cursor: hand; z-index: 12; }
 * #themap a { text-decoration: none; color: red; font: bold 9px verdana; z-index: 12 }
 * #themap a:hover, #themap div.maplinkselected { color: white; z-index: 12  }
 * #themap img.preload { display: none; }
 *
 * The style rules include references to four images. These can be changed to make the map look different, but you 
 * must also change two Javascript constants: imagesToPreload and locationOffsetFromBorder.
 * 
 * 1. imagesToPreload is simply an array containing the urls of the four images.
 *
 * 2. locationOffsetFromBorder is the offset from the top left of a border dive to the top left of its location div,
 * and so if they are square, its value will be half the difference in the size of these divs. Thus in the sample
 * above this would be ((74-10)/2) = 32. If you decide to change the dimension of either div, you must adjust this constant
 * accordingly.
 *
 */

locationOffsetFromBorder = 69; // As long as the border div is 64 pixels bigger than the location div
imagesToPreload = ["../images/redcircle.png", "../images/lightredcircle.png", "../images/whitecircle.png", "../images/filledcircle.png"];
selectedTownId = '';
highlightedTownId = '';
highlightedTownBaseStyle = '';

function setTownBorderStyle(id, style) {
	document.getElementById("border" + id).className = style;
}

function setTownLinkTextStyle(id, style) {
	document.getElementById("linktext" + id).className = style;
}

function highlightBorder(id) {
	if (id != selectedTownId) {
		highlightedTownId = id;
		highlightedTownBaseStyle = document.getElementById("border" + id).className;
		setTownBorderStyle(id, "borderhighlighted");
	}
	return false;
}

function unhighlightBorder(id) {
	if (id == highlightedTownId) {
		setTownBorderStyle(id, highlightedTownBaseStyle);
		highlightedTownId = '';
	}
	return false;
}

function selectTown(id) {
	if (selectedTownId != '') {
		setTownBorderStyle(selectedTownId, "border");
		setTownLinkTextStyle(selectedTownId, "maplink");
		townsToBrighten = townsNear(selectedTownId);
		for (i=0; i<townsToBrighten.length; i++) {
			setTownBorderStyle(townsToBrighten[i], "border");
		}
	}
	selectedTownId = id;
	setTownBorderStyle(selectedTownId, "borderselected");
	setTownLinkTextStyle(selectedTownId, "maplinkselected");
	townsToFade = townsNear(id);
	for (i=0; i<townsToFade.length; i++) {
		setTownBorderStyle(townsToFade[i], "borderoverlapped");
	}
	highlightedTownId = '';
	return true;
}

function drawTown(town) {
	result = '<div id="border' + town.id + '" class="border" style="left: ' + (town.xPos-locationOffsetFromBorder) + 'px; top: ' + (town.yPos-locationOffsetFromBorder) + 'px">&nbsp</div>';
	result = result + '<a href="' + town.url + '" onmouseover="highlightBorder(\'' + town.id +'\');" onmouseout="unhighlightBorder(\'' + town.id +'\');" onmouseup="selectTown(\'' + town.id +'\');">';
	result += '<div id="linktext' + town.id + '" class="maplink" style="left: ' + town.xLabelPos + 'px; top: ' + town.yLabelPos + 'px">' + town.name;
	result += '</div><div class="location" style="left: ' + town.xPos + 'px; top: ' + town.yPos + 'px"></div></a>';
	return result;
}
function imagePreloadText(imageName) {
	return '<img src="../images/' + imageName + '" class="preload" />';
}

function drawMap(townIdToSelect, townData, divToDrawOn) {
	text = '';
	for (i=0; i<townData.length; i++) {
		town = townData[i];
		text += drawTown(town);
		townsNear[town.id] = town.townsNearby;
	}
	for (i=0; i<imagesToPreload.length; i++) {
		text += imagePreloadText(imagesToPreload[i]);
	}
	document.getElementById(divToDrawOn).innerHTML = text;
	selectTown(townIdToSelect);
}

function townsNear(townId) {
	return townsNear[townId];
}

