/**
 * Core Javascript for the "Kiwicart Interactive Travelling Distance and Time Calculator"
 * 
 * Relies on CSS skin files for map and layout. Javascript just responds to mouseclicks and mouseovers, sets values and changes classes. 
 *
 * Copyright Kiwicart Web Services Ltd (http://www.kiwicart.co.nz/)
 * Author James McNeill, james # kiwicart . co . nz
 * 
 * Not to be reproduced or modified without permission. 
 */

start_city_id = 0;
current_anchor = null;

average_km_per_hour = 80;
city_list = new Array(
	/*  1 */ ["Akaroa", 2],
	/*  2 */ ["Auckland", 1],
	/*  3 */ ["Blenheim", 2],
	/*  4 */ ["Christchurch", 2],
	/*  5 */ ["Coromandel", 1],
	/*  6 */ ["Cromwell", 2],
	/*  7 */ ["Dargaville", 1],
	/*  8 */ ["Dunedin", 2],
	/*  9 */ ["Whatuwhiwhi", 1],
	/* 10 */ ["Fairlie", 2],
	/* 11 */ ["Franz Josef", 2],
	/* 12 */ ["Greymouth", 2],
	/* 13 */ ["Hanmer Springs", 2],
	/* 14 */ ["Hastings", 1],
	/* 15 */ ["Invercargill", 2],
	/* 16 */ ["Kaikoura", 2],
	/* 17 */ ["Kerikeri", 1],
	/* 18 */ ["Matakohe", 1],
	/* 19 */ ["Motueka", 2],
	/* 20 */ ["Napier", 1],
	/* 21 */ ["Nelson", 2],
	/* 22 */ ["New Plymouth", 1],
	/* 23 */ ["Ninety Mile Beach", 1],
	/* 24 */ ["Oamaru", 2],
	/* 25 */ ["Ohakune", 1],
	/* 26 */ ["Omarama", 2],
	/* 27 */ ["Orewa", 1],
	/* 28 */ ["Papamoa", 1],
	/* 29 */ ["Picton", 2],
	/* 30 */ ["Queenstown", 2],
	/* 31 */ ["Rotorua", 1],
	/* 32 */ ["Russell", 1],
	/* 33 */ ["Golden Bay", 2],
	/* 34 */ ["Te Anau", 2],
	/* 35 */ ["Timaru", 2],
	/* 36 */ ["Taupo", 1],
	/* 37 */ ["Waihi Beach", 1],
	/* 38 */ ["Waitomo", 1],
	/* 39 */ ["Wanaka", 2],
	/* 40 */ ["Wanganui", 1],
	/* 41 */ ["Wellington", 1],
	/* 42 */ ["Westport", 2],
	/* 43 */ ["Whangamata", 1],
	/* 44 */ ["Whangarei ", 1],
	/* 45 */ ["Ohope Beach", 1]
);

city_distances = new Array(
	/*  1 */ [1078,392,84,1060,494,1258,446,1398,265,479,342,219,723,663,267,1314,1258,507,743,508,775,1398,331,729,432,1078,966,420,570,880,1314,566,736,247,800,1006,893,508,615,420,417,1060,1243,965],
	/*  2 */ [686,994,168,1419,187,1356,330,1178,1189,1010,956,441,1573,815,265,145,816,421,768,357,330,1241,380,1305,27,205,658,1480,234,237,876,1646,1157,278,114,200,1431,457,658,946,168,167,843],
	/*  3 */ [308,668,733,866,670,1006,492,486,324,270,331,887,129,922,866,164,351,116,383,1006,555,337,656,686,574,28,794,488,922,224,960,471,408,922,501,801,223,28,264,668,851,573],
	/*  4 */ [976,410,1174,362,1314,184,395,258,135,639,579,183,1240,1174,423,659,424,671,1314,247,645,348,994,882,336,486,796,1230,482,652,163,716,54,809,424,531,336,333,976,1159,881],
	/*  5 */ [1401,348,1338,488,1160,1171,992,938,423,1555,797,404,348,798,403,750,393,488,1223,392,1287,168,170,640,1462,218,404,858,1628,1139,260,1307,236,1413,533,640,928,130,333,263],
	/*  6 */ [1599,221,1739,238,342,526,545,1064,233,607,1655,1599,824,1084,845,1116,1739,228,1070,110,1419,1307,761,62,1221,1655,912,217,268,1141,294,1234,55,956,761,639,1401,1584,1306],
	/*  7 */ [1536,180,1358,1399,1190,1136,621,1753,995,143,55,996,601,948,537,170,1421,560,1485,160,385,838,1660,414,130,1056,1826,1337,458,1244,380,1611,637,838,1126,348,58,478],
	/*  8 */ [1676,278,563,551,497,1001,217,545,1592,1546,785,1021,786,1021,1676,115,1007,234,1356,1244,698,283,1158,1592,844,290,199,1078,434,1171,276,893,698,695,1338,1521,1243],
	/*  9 */ [1498,1609,1360,1276,764,1893,1135,95,235,1136,744,1088,677,40,1561,700,1625,310,525,978,1800,554,130,1196,1966,1477,598,434,520,1751,777,978,1266,488,160,618],
	/* 10 */ [527,371,311,823,471,367,1414,1358,659,843,608,875,1498,156,829,127,1178,0,520,300,980,1066,716,470,71,900,1414,993,240,715,520,478,1160,1343,1065],
	/* 11 */ [177,374,834,575,550,1425,1369,471,854,469,886,1609,506,840,400,1189,0,531,404,991,1077,555,560,493,911,1425,1004,287,726,531,277,1171,1354,1076],
	/* 12 */ [217,655,769,338,1246,1190,298,675,290,707,1360,443,661,502,1010,898,352,583,812,1246,357,739,352,732,938,825,469,547,352,101,992,1175,897],
	/* 13 */ [601,714,141,1192,1136,288,621,286,653,1276,382,607,325,956,844,298,621,758,1192,518,787,298,678,884,771,559,493,298,198,938,1121,843],
	/* 14 */ [1218,460,677,621,461,20,413,432,764,886,225,950,441,319,303,1125,243,677,521,1291,802,163,364,326,1076,232,303,591,423,606,328],
	/* 15 */ [762,1809,1754,1002,1238,1003,1270,1893,332,1224,344,1573,1461,915,187,1375,1809,1061,152,416,1295,1501,1388,285,1110,915,869,1555,1738,1460],
	/* 16 */ [1051,995,293,480,245,512,1135,430,466,531,815,703,157,669,617,1051,353,835,0,537,743,630,607,352,157,340,797,980,702],
	/* 17 */ [160,1052,657,1004,593,106,1477,616,1541,225,441,894,1716,470,35,1112,1882,1343,514,350,436,1667,693,894,1182,404,85,534],
	/* 18 */ [996,601,948,537,245,1421,560,1485,122,385,838,1660,414,160,1056,1826,1337,458,298,380,1621,637,838,1126,348,75,478],
	/* 19 */ [481,48,513,1136,670,467,745,816,704,158,903,618,1052,57,1075,586,538,744,631,846,353,158,246,798,981,703],
	/* 20 */ [433,412,744,906,205,970,421,299,323,1145,223,657,541,1311,822,143,349,306,1096,252,323,611,403,586,308],
	/* 21 */ [465,1088,671,419,772,768,656,110,910,570,1004,108,1025,587,490,696,583,848,305,110,226,750,933,868],
	/* 22 */ [677,938,250,1002,357,308,355,1177,299,593,573,1343,854,296,339,173,1128,160,355,643,393,522,384],
	/* 23 */ [1561,700,1625,310,525,978,1800,554,130,1196,1966,1477,598,434,520,1751,1755,978,1266,488,170,618],
	/* 24 */ [892,113,1241,1129,583,319,1043,1477,729,404,84,1027,1156,1056,231,778,583,580,1223,1406,1128],
	/* 25 */ [956,380,271,309,1131,212,616,527,1297,808,132,338,195,1082,106,309,597,392,545,297],
	/* 26 */ [1305,1193,647,173,1107,1541,778,343,189,1027,1233,1120,113,842,647,644,1287,1470,1192],
	/* 27 */ [205,658,1480,234,217,876,1646,1157,278,114,200,1431,457,658,946,168,140,298],
	/* 28 */ [546,1368,86,441,768,1554,1045,926,116,151,1319,439,546,834,170,370,97],
	/* 29 */ [822,460,894,218,988,499,380,586,473,773,195,0,288,640,823,545],
	/* 30 */ [1282,1716,934,170,335,1202,1408,1295,117,1017,822,664,1462,1645,1367],
	/* 31 */ [470,678,1448,959,80,164,166,1233,309,460,748,218,400,85],
	/* 32 */ [1112,1882,1393,514,350,436,1667,693,894,1182,404,77,534],
	/* 33 */ [1090,645,598,804,691,812,413,218,293,758,1041,763],
	/* 34 */ [489,1368,1574,1461,273,1183,988,830,1628,1811,1533],
	/* 35 */ [879,1085,972,273,972,499,497,1139,1322,1044],
	/* 36 */ [206,163,1153,229,380,668,260,443,165],
	/* 37 */ [182,1359,479,586,874,54,279,209],
	/* 38 */ [1246,273,473,761,236,365,780],
	/* 39 */ [968,773,558,1413,1596,1318],
	/* 40 */ [195,483,533,622,358],
	/* 41 */ [288,640,823,545],
	/* 42 */ [928,1111,833],
	/* 43 */ [973,263],
	/* 44 */ [463]
);

/**
 * Set the mouse events for the city-link anchor tags. 
 * 
 * To be called once the page has loaded, saves us having to put the onclick and onmouseovers in the html (too tedious).
 */
function set_city_link_mouse_events()
{
	link_list = document.getElementsByTagName('a');
	for (i = 0; i < link_list.length; i++)
	{
		if (link_list[i].className == 'city-link')
		{
			anchor = link_list[i];
			parent_node = anchor.parentNode;
			parent_id_string = parent_node.id;
			city_id = parent_id_string.substring(parent_id_string.indexOf("-") +1);
			
			anchor.href = 'javascript:void(0);';
			anchor.onclick = new Function('set_start_city(this, ' + city_id + ');');
			/* anchor.onfocus = new Function('if (!set_travel_information(this, ' + city_id + ')) { set_start_city(this, ' + city_id + '); }'); */
			anchor.onfocus = new Function('set_travel_information(this, ' + city_id + ');');
			anchor.onmouseover = new Function('set_travel_information(this, ' + city_id + ');');
		}
	}
	
	/*
	<li id='city-1'><a href='javascript:void(0);' onclick='set_start_city(this, 1);' onmouseover='set_travel_information(this, 1);'>Akaroa</a></li>
	*/
}

/**
 * Mark a new city as the start city for the distance calculations. 
 *
 * This requires us to clean up any distance information/flags that will become stale with the new start city. 
 * 
 * @param The city's anchor tag (that has been clicked on). 
 * @param The city's id number (their index into the city_list array (note: the index starts at 1, not 0)).
 */
function set_start_city(anchor, id)
{
	/* If this city is already the active city, then we're done. */
	if (start_city_id == id)
	{
		return false;
	}
	
	/* Only one anchor's (parent) list item should be marked as the start city, so clear and set the classes. */
	if (current_anchor)
	{
		current_anchor.parentNode.className = '';
	}
	anchor.parentNode.className = 'start-city';
	
	/* Set the start name in the info panel and the flag location. */
	set_city_name('start-city', id);
	set_flag('flag', id);
	
	/* Reset/clear the current information panel details. */
	reset_list = new Array('destination-city', 'travel-distance', 'travel-time');
	for (var i = 0; i < reset_list.length; i++)
	{
		field = document.getElementById(reset_list[i]);
		if (field)
		{
			field.value = '';
		}
	}
	
	/* Hide the flag images. */
	image_list = new Array('flag-destination', 'ferry');
	for (var i = 0; i < image_list.length; i++)
	{
		image = document.getElementById(image_list[i]);
		if (image)
		{
			image.className = 'hidden';
		}
	}
	
	start_city_id = id;
	current_anchor = anchor;

	return true;
}

/**
 * Set the city name in the information panel (allowing for select fields and text fields).
 * 
 * @param The css/dom id of the field.
 * @param The city id (in the city_list array).
 */
function set_city_name(css_id, city_id)
{
	/* Set the destination name in the info panel. */
	field = document.getElementById(css_id);
	if (field.type == 'select')
	{
		/* Set the option field, not the value. */
	}
	else 
	{
		if (city_list[city_id - 1] && city_list[city_id - 1][0])
		{
			city_name = city_list[city_id - 1][0];
		}
		else
		{
			city_name = 'Unknown';
		}
		field.value = city_name;	
	}
}

/**
 * Position a flag by applying the correct css class.
 *
 * If the flag element doesn't exist, then nothing is done. 
 *
 * The positioning is all controlled in the css skin. That means the javascript doesn't care about where things are positioned (because it shouldn't care). 
 *
 * @param The css/dom id of the flag.
 * @param The city id.
 */
function set_flag(css_id, city_id)
{
	element = document.getElementById(css_id);
	if (element)
	{
		element.className = 'flag-' + city_id;
	}
}
	

/**
 * Change the travel information to reflect a trip from the currently start city (if there is one) to the selected city.
 * 
 * @param The city's anchor tag. 
 * @param The city's id number.
 */
function set_travel_information(anchor, id)
{
	/* We don't do anything if there isn't a start city or the start city is the selected city. */
	if (start_city_id == 0 || start_city_id == id)
	{
		set_flag('flag', id);
		return false;
	}
	
	set_city_name('destination-city', id);
	set_flag('flag-destination', id);
	
	/* We have removed duplicate distances from the city distance information, so to find the distance we have to juggle the start and destination city ids to make sure they're in the right order. */
	min_id = max_id = id;
	if (id < start_city_id)
	{
		max_id = start_city_id;
	}
	else
	{
		min_id = start_city_id;
	}
	
	km = city_distances[min_id-1][max_id-1-min_id];

	/* Calculate miles and estimate a travelling time. The minutes are to the nearest 10 minutes only. */
	//miles = Math.round(km * 8 / 5);
	miles = Math.round(km / 1.61);
	time = km / average_km_per_hour;
	hours = Math.floor(time);
	minutes = Math.round((time - hours) * 6) * 10;
	
	if(minutes == 60) {
		minutes = 0;
		hours++;
	}

	is_different_islands = false;
	if (city_list[start_city_id-1][1] != city_list[id-1][1])
	{
		is_different_islands = true;
	}
	
	/* Fill in our travel info. */
	distance_field = document.getElementById('travel-distance');
	if (distance_field)
	{
		if (km == 0)
		{
			distance_field.value = 'Not available';
		}
		else
		{
			distance_field.value = km + 'km (' + miles + ' miles)';
		}
	}

	time_field = document.getElementById('travel-time');
	if (time_field)
	{
		if (km == 0)
		{
			time_field.value = 'Not available';
		}
		else 
		{
			time_field.value = 
				hours + ' hours ' 
				+ (minutes > 0 ? minutes + ' mins' : '') 
				+ (is_different_islands ? ' + interisland ferry' : '')
			;
		}
	}
	
	/* Reveal the ferry picture, if the cities are on different islands. */
	image = document.getElementById('ferry');
	if (image)
	{
		if (city_list[start_city_id-1][1] != city_list[id-1][1])
		{
			image.className = 'block';
		}
		else
		{
			image.className = 'hidden';
		}
	}

	return true;
}
