//<![CDATA[

var stdBubbleWidth = 240;
var stdBubbleHeight = 150;

function Hash()
{
	this.length = 0;
	this.items = new Array();
	for (var i = 0; i < arguments.length; i += 2) {
		if (typeof(arguments[i + 1]) != 'undefined') {
			this.items[arguments[i]] = arguments[i + 1];
			this.length++;
		}
	}
   
	this.removeItem = function(in_key)
	{
		var tmp_value;
		if (typeof(this.items[in_key]) != 'undefined') {
			this.length--;
			var tmp_value = this.items[in_key];
			delete this.items[in_key];
		}
	   
		return tmp_value;
	}

	this.getItem = function(in_key) {
		return this.items[in_key];
	}

	this.setItem = function(in_key, in_value)
	{
		if (typeof(in_value) != 'undefined') {
			if (typeof(this.items[in_key]) == 'undefined') {
				this.length++;
			}

			this.items[in_key] = in_value;
		}
	   
		return in_value;
	}

	this.hasItem = function(in_key)
	{
		return typeof(this.items[in_key]) != 'undefined';
	}
}

function loadup() {
map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.addControl(new GScaleControl());
map.addMapType(G_PHYSICAL_MAP) ;
//map.setCenter(new GLatLng(63.0, 10.0), 4); // Change these to your own part of the world
map.setCenter(new GLatLng(start_lat, start_lon), start_zoom); // Change these to your own part of the world
map.setMapType(G_PHYSICAL_MAP);

// ====== set up marker mouseover tooltip div ======
tooltip = document.createElement("div");
map.getPane(G_MAP_FLOAT_PANE).appendChild(tooltip);
tooltip.style.visibility="hidden";

	for(var i=0; i<16; i++)
	{
		icon_k[i] = myicon("http://www.shipspotting.com/images/googlemap/black"+(i+1)+".gif");
		icon_b[i] = myicon("http://www.shipspotting.com/images/googlemap/blue"+(i+1)+".gif");
		icon_a[i] = myicon("http://www.shipspotting.com/images/googlemap/grey"+(i+1)+".gif");
		icon_g[i] = myicon("http://www.shipspotting.com/images/googlemap/green"+(i+1)+".gif");
		icon_r[i] = myicon("http://www.shipspotting.com/images/googlemap/red"+(i+1)+".gif");
		icon_w[i] = myicon("http://www.shipspotting.com/images/googlemap/white"+(i+1)+".gif");
		icon_y[i] = myicon("http://www.shipspotting.com/images/googlemap/yellow"+(i+1)+".gif");
		icon_m[i] = myicon("http://www.shipspotting.com/images/googlemap/purple"+(i+1)+".gif");
	}

	updateMarkers();
	GEvent.addListener(map, "moveend", updateMarkers);
	
	window.setTimeout('countDown()', 1000);
}

var polyClusters = Array();
function updateMarkers()
{
	countDownTime=refreshInterval;
/*	map.clearOverlays();
	var g1,g2;
	var p1=new GLatLng(65,20);
	var p2=new GLatLng(65,21);
	map.addOverlay(g1 = new GMarker(p1));
	map.addOverlay(g2 = new GMarker(p2));
	var px1 = map.fromLatLngToContainerPixel(p1);
	var px2 = map.fromLatLngToContainerPixel(p2);
	alert("zoom:"+map.getZoom()+" dist: "+p1.distanceFrom(p2)+" p1x:"+px1.x+" p1y:"+px1.y+" p2x:"+px2.x+" p2y:"+px2.y+" dist:"+Math.sqrt((px1.x-px2.x)*(px1.x-px2.x)+(px1.y-px2.y)*(px1.y-px2.y))); 
	return;*/
	var ne = map.getBounds().getNorthEast();
	var sw = map.getBounds().getSouthWest();
	var url = "ais_get_markers.php?minlat="+sw.lat()+"&maxlat="+ne.lat()+"&minlon="+sw.lng()+"&maxlon="+ne.lng()+"&zoom="+map.getZoom();
	
	GDownloadUrl(url, function(data, responseCode) {
		var xmlDoc = GXml.parse(data);
		if (!xmlDoc.documentElement) 
		 	return;

		for (var i = 0; i < polyClusters.length; i++) {
			map.removeOverlay(polyClusters[i]);
		}
		polyClusters = Array();

		var xmlcluster = xmlDoc.documentElement.getElementsByTagName("cluster");
		for (var i = 0; i < xmlcluster.length; i++) {
			createCluster(xmlcluster[i]);
	 	}

		var xmlmarker = xmlDoc.documentElement.getElementsByTagName("marker");
		
		if (!aisdata)
			aisdata = new Hash();
		var newaisdata = new Hash();

		var ais = xmlmarker[i];

		for (var i = 0; i < xmlmarker.length; i++) {
			var mmsi = xmlmarker[i].getAttribute("mmsi");
			if (mmsi != "" && mmsi != "undefined") {
				var item = new Object;
				var Lat = parseFloat(xmlmarker[i].getAttribute("lat"));
				var Lon = parseFloat(xmlmarker[i].getAttribute("lon"));
				var name = xmlmarker[i].getAttribute("name");
				var deltax = parseFloat(xmlmarker[i].getAttribute("dx"));
				var deltay = parseFloat(xmlmarker[i].getAttribute("dy"));
				var type = parseInt(xmlmarker[i].getAttribute("type"));
				var icon = getIcon(type, xmlmarker[i].getAttribute("dir"));

				var point = new GLatLng(Lat, Lon);
				if (aisdata.hasItem(mmsi)) {
					item.marker = aisdata.getItem(mmsi).marker 
					item.marker.setLatLng(point);
				}
				else {
					item.marker = createMarker(point, name, item, icon);
				}
				item.mmsi = mmsi;
				item.html = makeinfo(name, type, xmlmarker[i], 240, 240);
				newaisdata.setItem(mmsi, item);
			}
		}

//		var removed = 0;
		for (i in aisdata.items)
		{
			if (!isNaN(i)) // skip stupid methods added by mootools
			{
				var item = aisdata.getItem(i);
				if (!newaisdata.hasItem(item.mmsi))
				{
					map.removeOverlay(item.marker);
//					removed++;
				}
			}
		}

		aisdata = newaisdata;
		
//		alert("removed:"+removed);
		
		var shiptime = document.getElementById("shiptime");
		if (shiptime) {
			var currentTime = new Date();
			// See eg http://www.tizag.com/javascriptT/javascriptdate.php for
			// fancier time formatting
			shiptime.innerHTML = "Ship positions last uploaded: " + currentTime + '.';
		}
	});
}

function ais_type(id)
{
 var type1 = new Array('unspecified', 'Reserved', 'Wing In Grnd', '', 'Hi Spd Crft', '', 'Passenger', 'Cargo', 'Tanker', 'Other');
 var type2 = new Array('', // All ships of this type
 'Haz A', /* Major Hazard */
 'Haz B', /* Hazard */
 'Haz C', /* Minor Hazard */
 'Haz D', /* Recogniseable Hazard */
 '',
 '',
 '',
 '',
 '' // No additional information
 );

 type3 =new Array('Fishing', 'Towing', 'Towing', 'Dredger', 'Dive Vessel', 'Military Ops', 'Sail', 'Pleasure Craft', 'Reserved', 'Reserved');
 type5 = new Array('Pilot Vessel', 'SAR', 'Tug', 'Port Tender', 'Anti-polution', 'Law enforce', 'Local Vessel', 'Local Vessel', 'Medical Trans', 'Special craft');

 navaid = new Array('Default Navaid',
 'Reference point',
 'RACON',
 'Off Shore Structure',
 'Spare',
 'Light, without sectors',
 'Light, with sectors',
 'Leading Light Front',
 'Leading Light Rear',
 'Beacon, Cardinal N',
 'Beacon, Cardinal E',
 'Beacon, Cardinal S',
 'Beacon, Cardinal W',
 'Beacon, Port hand',
 'Beacon, Starboard hand',
 'Beacon, Preferred Channel port hand',
 'Beacon, Preferred Channel starboard hand',
 'Beacon, Isolated danger',
 'Beacon, Safe water',
 'Beacon, Special mark',
 'Cardinal Mark N',
 'Cardinal Mark E',
 'Cardinal Mark S',
 'Cardinal Mark W',
 'Port hand Mark',
 'Starboard hand Mark',
 'Preferred Channel Port hand',
 'Preferred Channel Starboard hand',
 'Isolated danger',
 'Safe Water',
 'Manned VTS', // Special Mark
 'Light Vessel / LANBY');

 type = Math.floor(id / 10);
 rem = id % 10;
 result = '';
 if (type == 3)
 result = type3[rem];
 else if (type == 5)
 result = type5[rem];
 else if (id >= 100) {
 result = navaid[id-100];
 } else {
 result = type1[type];
 if (id < 100 && type2[rem] != '')
 result = result +' '+type2[rem];
 }
 return result;
}

function getstatus(status) {
 switch (parseInt(status)) {
 case 0: return 'Underway';
 break;
 case 1: return 'At Anchor';
 break;
 case 2: return 'Not Under Command';
 break;
 case 3: return 'Restricted Manoeuvrability';
 break;
 case 4: return 'Constrained by Her Draught';
 break;
 case 5: return 'Moored';
 break;
 case 6: return 'Aground';
 break;
 case 7: return 'Engaged in Fishing';
 break;
 case 8: return 'Underway by Sail';
 break;
 case 15: return 'Default (15)';
 break;
 default: return status;
 break;
 }
}

function makeinfo(name, type, ais, width, height) {
	//var ais = aisstr.split('!');
	var mmsi = ais.getAttribute("mmsi");
	var imo = ais.getAttribute("imo");
	var call = ais.getAttribute("callsign");
	var dest = ais.getAttribute("dest");
	var eta = ais.getAttribute("eta");
	var speed = ais.getAttribute("speed");
	var course= ais.getAttribute("dir");
	var status= getstatus(ais.getAttribute("status"));
	var length= ais.getAttribute("length");
	var width = ais.getAttribute("width");
	var draft = ais.getAttribute("draft");
	var mtime = ais.getAttribute("received");
	var lid = ais.getAttribute("lid");
	var ext = ais.getAttribute("ext");
	var adstr = "";
	var imgstr = "";
	if (lid > 0) {
		imgstr = '<a href="photo.php?from=aislive&maplat='+map.getCenter().lat()+'&maplon='+map.getCenter().lng()+'&zoom='+map.getZoom()+'&lid='+lid+'"><img src="http://media.shipspotting.com/uploads/thumbs_wm/'+lid+'.'+ext+'" width="120"></a>';
	}
	if (type < 100) {
		callstr = '<tr><td class="aisdatatype">Callsign</td><td class="aisdata">'+call+'</td></tr>\n';
		deststr = '<tr><td class="aisdatatype">Dest</td><td class="aisdata"><i>'+dest+'</i></td></tr>\n';
		etastr = '<tr><td class="aisdatatype">ETA</td><td class="aisdata">'+eta+'</td></tr>\n';
		spdstr = '<tr><td class="aisdatatype">Speed/Dir</td><td class="aisdata">'+speed+' kts / '+course+'</td></tr>\n';
		sizestr = '<tr><td class="aisdatatype">Size</td><td class="aisdata">'+length+'m x '+width+'m x '+draft+'m</td></tr>\n';
	} else {
		callstr = '';
		deststr = '';
		etastr = '';
		spdstr = '';
		sizestr = '';
	}
	if (imo > 0) {
		imostr = '<tr><td class="aisdatatype">IMO</td><td class="aisdata">'+imo+'</td></tr>\n';
	} else {
		imostr = '';
	}
	if (mtime != '') {
		recstr = '<tr><td class="aisdatatype">Received</td><td class="aisdata">'+mtime+' UTC</td></tr>\n';
	} else {
		recstr = '';
	}
	adstr = getAdd();
	return '<div class="gpopup" style="height:250px;">\n'+
		'<table cellpadding="0" cellspacing="0" border="0"><tr>\n'+
		'<tr>\n'+
			'<td><table>'+
				'<tr><td>'+imgstr+'</td></tr>\n'+
				'<tr height="5"></tr>\n'+
				'<tr><td>'+adstr+'</td></tr>\n'+
			'</table></td>\n'+
			'<td width="5"></td>\n'+
			'<td><table>'+
				'<td class="aisdatatype">Name</td><td class="aisdata">'+name+'</a></td></tr>\n'+			
				callstr+
				'<tr><td class="aisdatatype">MMSI</td><td class="aisdatatype">'+mmsi+'</td></tr>\n'+
				imostr+
				'<tr><td class="aisdatatype">Status</td><td class="aisdata">'+status+'</td></tr>\n'+
				deststr+
				etastr+
				'<tr><td class="aisdatatype">Type</td><td class="aisdata">'+type+" "+ais_type(type)+'</td></tr>\n'+
				spdstr+
				sizestr+
				recstr+
				'<tr><td class="aisdatatype"></td><td class="aisdata"></td></tr>\n'+
			'</table></td>\n'+
		'</tr></table>\n'+
		'</div>';
}

function addVector(from, deltax, deltay) {
 if (deltax == 0 && deltay == 0) return null;
 var to = new GLatLng(from.lat() + deltay, from.lng() + deltax)
 var polyline = new GPolyline([from, to], "#ffffff", 2);
 return polyline;
}

function getIcon(type, dir) {
	var idir = Math.floor(dir/22.5);

	if (type == 52)
	return icon_k[idir]; // "black"
	
	if (type == 36)
	return icon_m[idir];
	if (type == 37)
	return icon_m[idir];
	if (type > 99)
	return icon_a[idir]; //"gray"
	
	var itype = Math.floor(type/10);
	switch (itype) {
	case 7:
	ball = icon_g[idir]; // "green";
	break;
	case 8:
	ball = icon_r[idir]; // "red";
	break;
	case 4:
	ball = icon_w[idir]; // "white";
	break;
	case 6:
	ball = icon_b[idir]; // "blue";
	break;
	default:
	ball = icon_y[idir]; // "yellow";
	break;
	}
	return ball;
}
/*
function get_colour(type) {
 if (type == 52)
 return icon_k; // "black"

 if (type == 36)
 return icon_m;
 if (type == 37)
 return icon_m;
 if (type > 99)
 return icon_a; //"gray"

 var itype = Math.floor(type/10);
 switch (itype) {
 case 7:
 ball = icon_g; // "green";
 break;
 case 8:
 ball = icon_r; // "red";
 break;
 case 4:
 ball = icon_w; // "white";
 break;
 case 6:
 ball = icon_b; // "blue";
 break;
 default:
 ball = icon_y; // "yellow";
 break;
 }
 return ball;
}
*/
function myicon(image) {
icon = new GIcon();
icon.iconSize = new GSize(24, 24);
icon.iconAnchor = new GPoint(12, 12);
icon.infoWindowAnchor = new GPoint(12, 12);
//icon.shadow = "http://labs.google.com/ridefinder/images/mm_20_shadow.png";
//icon.shadowSize = new GSize(22, 20);
icon.image = image;
return icon;
}

function createCluster(cluster)
{
	var minlon = cluster.getAttribute("minlon");
	var maxlon = cluster.getAttribute("maxlon");
	var minlat = cluster.getAttribute("minlat");
	var maxlat = cluster.getAttribute("maxlat");
	var polyPoints = Array();
 	var polyPoint;
 	polyPoint = new GLatLng(minlat, minlon);	polyPoints.push(polyPoint);
 	polyPoint = new GLatLng(minlat, maxlon);	polyPoints.push(polyPoint);
 	polyPoint = new GLatLng(maxlat, maxlon);	polyPoints.push(polyPoint);
 	polyPoint = new GLatLng(maxlat, minlon);	polyPoints.push(polyPoint);
 	polyPoint = new GLatLng(minlat, minlon);	polyPoints.push(polyPoint);

	// Using GPolygon(points,  strokeColor?,  strokeWeight?,  strokeOpacity?,  fillColor?,  fillOpacity?)
    var polyCluster = new GPolygon(polyPoints,"#003366",0.5,1.0,"#00CCEE",.5);
	polyCluster.tooltip = '<div id="tooltip"><span>'+cluster.getAttribute('ships')+' ships'+'</span></div>';
	GEvent.addListener(polyCluster, "mouseover", function() {
		showClusterTooltip(polyCluster);
	});
	GEvent.addListener(polyCluster,"mouseout", function() {
		tooltip.style.visibility="hidden"
	});
	GEvent.addListener(polyCluster,"click", function() {
		tooltip.style.visibility="hidden"
		var bounds = new GLatLngBounds(new GLatLng(minlat, minlon), new GLatLng(maxlat, maxlon));
		map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));
	});
    
    polyClusters.push(polyCluster);
    map.addOverlay(polyCluster);
}

function createMarker(point, name, item, iconz) {
	var marker = new GMarker(point, iconz);
	marker.tooltip = '<div id="tooltip"><span>'+name+'</span></div>';
	GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowHtml(item.html);
	});
	map.addOverlay(marker);
	
	GEvent.addListener(marker,"mouseover", function() {
		showTooltip(marker);
	});
	GEvent.addListener(marker,"mouseout", function() {
		tooltip.style.visibility="hidden"
	});
	
	return marker;
}

/*
function autoUpdate() {
GDownloadUrl("data.xml", function(data, responseCode) {
 var xmlDoc = GXml.parse(data);
 if (!xmlDoc.documentElement) return;
 var xmlmarker = xmlDoc.documentElement.getElementsByTagName("marker");
 var movehtml = '';
 var dockhtml = '';
 var sepmove = '';
 var sepdock = '';

 if (!gmarkers)
 gmarkers = new Array();
 if (!htmls)
 htmls = new Array();
 if (!vectors)
 vectors = new Array();

 var Lat, Lon, name, deltax, deltay, type, ais, html, icon;
 for (var i = 0; i < xmlmarker.length; i++) {
 Lat = parseFloat(xmlmarker[i].getAttribute("lat"));
 Lon = parseFloat(xmlmarker[i].getAttribute("lon"));
 name = xmlmarker[i].getAttribute("name");
 deltax = parseFloat(xmlmarker[i].getAttribute("dx"));
 deltay = parseFloat(xmlmarker[i].getAttribute("dy"));
 type = parseInt(xmlmarker[i].getAttribute("type"));
 htmls[i] = makeinfo(name, type, xmlmarker[i].getAttribute("ais"));
 icon = get_colour(type);

 if (gmarkers[i]) {
 GEvent.clearListeners(gmarkers[i], "click");
 GEvent.clearListeners(gmarkers[i], "mouseover");
 GEvent.clearListeners(gmarkers[i], "mouseout");
 map.removeOverlay(gmarkers[i]);
 }

 var point = new GLatLng(Lat, Lon);
 gmarkers[i] = createMarker(point, name, htmls[i], icon);

 if (vectors[i]) map.removeOverlay(vectors[i]);
 vectors[i] = addVector(point, deltax, deltay);
 if (vectors[i]) map.addOverlay(vectors[i]);

 html = "<a href='javascript:findship(" + i + ")' onmouseover='mymouseover(" + i + ")' onmouseout='mymouseout()'>" + name + "</a>";
 if ( Math . abs ( deltax ) > 0 || Math. abs ( deltay ) > 0 ) {
 movehtml += sepmove + html;
// sepmove = ", ";
 sepmove = "<br>";
 } else {
 dockhtml += sepdock + html;
// sepdock = ", ";
 sepdock = "<br>";
 }
 }
 var shipmove = document.getElementById("shipmove");
 if (shipmove)
 shipmove.innerHTML = movehtml + '.';
 var shipdock = document.getElementById("shipdocked");
 if (shipdock)
 shipdock.innerHTML = dockhtml + '.';
 var shiptime = document.getElementById("shiptime");
 if (shiptime) {
 var currentTime = new Date();
 // See eg http://www.tizag.com/javascriptT/javascriptdate.php for
 // fancier time formatting
 shiptime.innerHTML = "Ship positions last uploaded: " + currentTime + '.';
 }
});

// time out after 1hr.
if (refreshcounter++ < numrefresh)
 window.setTimeout('countDown()', 1000);
else {
 if (document.getElementById("countDownText"))
 document.getElementById("countDownText").innerHTML = "REFRESH PAGE to continue updates.";
}
}
*/
// ====== This function displays the tooltip ======
// it can be called from an icon mousover or a sidebar mouseover
function showTooltip(marker) {
 tooltip.innerHTML = marker.tooltip;
 var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
 var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(marker.getPoint(),map.getZoom());
 var anchor=marker.getIcon().iconAnchor;
 var width=marker.getIcon().iconSize.width;
 var height=tooltip.clientHeight;
 var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x - anchor.x + width, offset.y - point.y -anchor.y -height));
 pos.apply(tooltip);
 tooltip.style.visibility="visible";
}

function showClusterTooltip(polyCluster)
{
 tooltip.innerHTML = polyCluster.tooltip;
 var point=map.getCurrentMapType().getProjection().fromLatLngToPixel(map.fromDivPixelToLatLng(new GPoint(0,0),true),map.getZoom());
 var offset=map.getCurrentMapType().getProjection().fromLatLngToPixel(polyCluster.getVertex(3),map.getZoom());
/* var anchor=marker.getIcon().iconAnchor;
 var width=marker.getIcon().iconSize.width;*/
 var height=tooltip.clientHeight;
 var pos = new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(offset.x - point.x, offset.y - point.y -height));
 pos.apply(tooltip);
 tooltip.style.visibility="visible";
}

// ===== This function is invoked when the mouse goes over an entry in the sidebar =====
// It launches the tooltip on the icon
function mymouseover(i) {
 showTooltip(gmarkers[i])
}
// ===== This function is invoked when the mouse leaves an entry in the sidebar =====
// It hides the tooltip
function mymouseout() {
 tooltip.style.visibility="hidden";
}

// Open the info box for the specified marker.
function findship(i){
 gmarkers[i].openInfoWindowHtml(aisdata.getItem(i).html);
}

// Refresh the data after 'refreshInterval' seconds.
// It should not be faster than ship.vbs
var refreshInterval = 200;

// numrefresh is the number of times to refresh this page before timing out.
var numrefresh = 999;

var tooltip;
var refreshcounter = 0;
var aisdata;
var icon_k = new Array();
var icon_b = new Array();
var icon_a = new Array();
var icon_g = new Array();
var icon_m = new Array();
var icon_r = new Array();
var icon_w = new Array();
var icon_y = new Array();
var map;
var countDownTime=refreshInterval+1;
var counter;

function countDown(){
	countDownTime--;
	if (document.getElementById("countDownText"))
		document.getElementById("countDownText").innerHTML= "Refresh in " + countDownTime + " sec.";
	if (countDownTime<=0){	
		countDownTime=refreshInterval;
		clearTimeout(counter);
		updateMarkers();
		// time out after 1hr.
		if (refreshcounter++ < numrefresh)
			window.setTimeout('countDown()', 1000);
		else {
			if (document.getElementById("countDownText"))
				document.getElementById("countDownText").innerHTML = "REFRESH PAGE to continue updates.";
		}
		return;
	}
	counter=setTimeout("countDown()", 1000);
}

function onLoad() {
	if (!GBrowserIsCompatible()) {
		alert("Sorry, the Google Maps API is not compatible with this browser");
	} else {
		setTimeout(loadup, 250);
	}
}

function getAdd() {
	var str = 
		"<iframe id='aff68498' name='aff68498' src='http://ads.communitycompetence.com/www/delivery/afr.php?n=aff68498&amp;zoneid=55&amp;cb=INSERT_RANDOM_NUMBER_HERE' framespacing='0' frameborder='no' scrolling='no' width='125' height='125'><a href='http://ads.communitycompetence.com/www/delivery/ck.php?n=a0f71bed&amp;cb=INSERT_RANDOM_NUMBER_HERE' target='_blank'><img src='http://ads.communitycompetence.com/www/delivery/avw.php?zoneid=55&amp;cb=INSERT_RANDOM_NUMBER_HERE&amp;n=a0f71bed' border='0' alt='' /></a></iframe>" +
		"<script type='text/javascript' src='http://ads.communitycompetence.com/www/delivery/ag.php'></script>";
	return str;
}


//]]>
