// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
//
// Google maps
//
//
// Ensure the calling page also includes the following ...
//
//
// script src="http://maps.google.com/maps?file=api&amp;v=2&amp;key=ABQIAAAAsSnIqvpH-TUJcLzmbuE-qxQS0KqigiIpE49A_a_wshKkswsZFhRrSDIODI_oOrco-skVcEtnixvdcQ"
// script src="/scripts/bdccrangerings.js"
// script src="/scripts/geotools2.js"
//

// -------------------------------------------------------------------------------------------------
//
// various API keys used in this mashup
//
	
var bkcGoogleMapsAPIKey      = "ABQIAAAAsSnIqvpH-TUJcLzmbuE-qxQS0KqigiIpE49A_a_wshKkswsZFhRrSDIODI_oOrco-skVcEtnixvdcQ";
var bkcMultimapAPIKey        = "OA09062517428591256";
var bkcFlickrAPIKey          = "4b87b7e8b77543a3f9cdfa6e96a3eb6b"; 	

// -------------------------------------------------------------------------------------------------
//
// the google map
//

var bkcGMap                  = null;

// -------------------------------------------------------------------------------------------------
//
// initial map dimensions
//
// you have to override this in your own script if you want to create a fullscreen map
//

var bkcGMapWidth             = "500px";
var bkcGMapHeight            = "400px";

// -------------------------------------------------------------------------------------------------
//
// center map when loading xml resource files
//
// you have to override this in your own script if you want to ignore future center XML tags
//

var bkcCenterOnLoad          = true;

// -------------------------------------------------------------------------------------------------
//
// create an editable map (i.e. draggable markers and lines)
//
// you have to override this in your own script if you want to create an editable map
//

var bkcCreateEditableMap     = false;
var bkcRouteOpenForEditing   = null;
var bkcMarkerOpenForEditing  = null;

// -------------------------------------------------------------------------------------------------
//
// create a multimap OS map too
//
// you can override this in your own script
//

var bkcGMapCreateOSMap       = false;
var bkcGMapCreateOSMapMarker = true;

// -------------------------------------------------------------------------------------------------
//
// default initialization data if no xml file is supplied
//
// you can override these here or in your own script
//

var bkcGMapLoc               = new GLatLng( 54.5284, -6.0236 );
var bkcGMapZoom              = 12;

// -------------------------------------------------------------------------------------------------
//
// overlay arrays for editing operations
//

var bkcGMapMarkers           = new Array();
var bkcGMapRoutes            = new Array();
var bkcGMapFlickrImages      = new Array();
var bkcGMapFlickrMarkers     = new Array();

// -------------------------------------------------------------------------------------------------
//
// url of xml file to use to initialize the map
//

var bkcGMapResourceFile      = null;

// -------------------------------------------------------------------------------------------------
//
// the HTML containers created for the map and the status box
//

var bkcContainersSetup       = false;

var bkcGMapCanvas            = null;
var bkcStatusDiv             = null;
var bkcOSMapCanvas           = null;

// -------------------------------------------------------------------------------------------------
//
// startup events
//
// call bkcAddLoadEvent to add your own func to the list
//

var bkcOnLoadEvent           = null;

// -------------------------------------------------------------------------------------------------
//
// status message to display underneath map
//
// you can override this here or in your own script
//

var bkcDefaultStatus         = "<em>Mouse over markers to see information.<br>Click to center on a marker. Double-click to get directions.</em>";

// -------------------------------------------------------------------------------------------------
//
// lettered marker base icon - to create a lettered icon, use this and then set the image to
//
//     var myIcon = new GIcon( bkcBaseIcon ); 
//     myIcon.image = "http://belfastkayakclub.co.uk/markers/blue/markerA.png";
//

var bkcBaseIcon              = new GIcon( G_DEFAULT_ICON );

bkcBaseIcon.iconAnchor       = new GPoint( 9, 34 );
bkcBaseIcon.iconSize         = new GSize( 20, 34 );

bkcBaseIcon.shadow           = "http://www.google.com/mapfiles/shadow50.png";
bkcBaseIcon.shadowSize       = new GSize( 37, 34 );

bkcBaseIcon.infoWindowAnchor = new GPoint( 9, 2 );

// -------------------------------------------------------------------------------------------------
//
// flickr user id - used to get photo feeds
//

var bkcFlickrUserId          = "49011369@N07";

// -------------------------------------------------------------------------------------------------
//
// this is the main function used to handle a google map
//
// the first time it is called, which should be in a script tag in the main content flow, it
// creates a DIV into which the map is loaded
//
// you can call this function multiple times in response to changes in form values etc
//

function bkcGMapSetup( xmlResourceFile ) {

	if ( !bkcContainersSetup ) {
		document.write( '<center>' );
		document.write( '<div id="bkcGMapCanvas" style="width: ' + bkcGMapWidth + '; height: ' + bkcGMapHeight + '; border: solid 1px #DDDDDD; overflow: hidden;">Google Map Viewer</p></div>' );
		document.write( '<div id="bkcGMapStatus" style="width: ' + bkcGMapWidth + '; height: 3.5em; border: solid 1px #DDDDDD;">Please wait, loading map ...</p></div>' );
		if ( bkcGMapCreateOSMap ) { document.write( '<div id="bkcOSMapCanvas"></div>' ); }
		document.write( '</center>' );
		bkcContainersSetup = true;
	}
	
	bkcGMapResourceFile = xmlResourceFile;

	setTimeout( 'bkcGMapInitialize()', 3000 );

}

// -------------------------------------------------------------------------------------------------
//
// initialise the google map
//

function bkcGMapInitialize() {
	
	if ( ! GBrowserIsCompatible() ) {
		if ( bkcStatusDiv ) { bkcStatusDiv.innerHTML = "Cannot load google maps in this browser."; }
		return;
	}

	bkcGMapCanvas  = document.getElementById("bkcGMapCanvas");
	bkcStatusDiv   = document.getElementById("bkcGMapStatus");
	bkcOSMapCanvas = document.getElementById("bkcOSMapCanvas");
	 
	if ( !bkcGMapCanvas ) {
		alert( "Cannot find the google map canvas." );
		return;
	}
	
	if ( !bkcStatusDiv ) {
		alert( "Cannot find the status box." );
	}
	
	bkcGMap = new GMap2(document.getElementById("bkcGMapCanvas"));
	bkcGMap.setUIToDefault();
	
	if ( bkcGMapResourceFile ) { 
		bkcGMapLoadOverlaysFromXML( bkcGMapResourceFile ); 
	} else {
		bkcGMap.setCenter( bkcGMapLoc, bkcGMapZoom );
	}
	
	/*
	if ( bkcCreateEditableMap ) { 
		GEvent.addListener( bkcGMap, "click", function() { 
			if ( bkcRouteOpenForEditing ) { 
				alert( 'map click' );
				bkcRouteOpenForEditing.disableEditing(); 
				bkcRouteOpenForEditing = null;
			}
		}); 
	}
	*/
	
	bkcStatusDiv.innerHTML = bkcDefaultStatus;
	
	setTimeout( 'bkcGMapLoadFlickrPhotos()', 3000 );

	if ( bkcGMapCreateOSMap && bkcOSMapCanvas ) { setTimeout( 'bkcOSImageFromGMap()', 2000 ); }
	
	if ( typeof bkcOnLoadEvent == 'function' ) { bkcOnLoadEvent(); }
}

// -------------------------------------------------------------------------------------------------
//
// add a load event to the list called by bkcGMapInitialize
//

function bkcAddLoadEvent(func) {
	var oldEvent = bkcOnLoadEvent;
	if ( typeof bkcOnLoadEvent != 'function' ) {
		bkcOnLoadEvent = func;
	} else {
		bkcOnLoadEvent = function() {
			if ( oldEvent ) { oldEvent(); }
			func();
		}
	}
}

// -------------------------------------------------------------------------------------------------
//
// use geotools library to convert an irish grid reference to a lat/long
//

function bkcGMapConvertIrishGridRef( ref ) {

	var irish = new GT_Irish(); 
	irish.parseGridRef(ref);

	var wgs84 = irish.getWGS84();
	return wgs84;

}

// -------------------------------------------------------------------------------------------------
//
// extend string class to allow trim
//

String.prototype.ltrim = function(chars) {
	chars = chars || "\\s";
	return this.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

String.prototype.rtrim = function(chars) {
	chars = chars || "\\s";
	return this.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

String.prototype.trim = function(chars) {
	var temp = this.ltrim(chars);
	return temp.rtrim(chars);
}

// -------------------------------------------------------------------------------------------------
//
// extend number class to allow radians
//

Number.prototype.padLZ = function(w) {
  var n = this.toString();
  for ( var i=0; i<w-n.length; i++ ) { n = '0' + n };
  return n;
}

Number.prototype.toRad = function() {
  return this * Math.PI / 180;
}

Number.prototype.toDeg = function() {
  return this * 180 / Math.PI;
}

// -------------------------------------------------------------------------------------------------
//
// add a standard lettered marker to the map
//
// parameters
//
//    lat,lng        the position of the marker
//    charLabel      A .. Z
//    strTitle       the status text or tooltip
//    t              the type of the marker ( feature = green, access = blue, else yellow )
//
// uses geotools to turn the position into grid references
//

function bkcGMapAddMarker( lat, lng, charLabel, strTitle, t ) {
	
	var wgs84     = new GT_WGS84(); wgs84.setDegrees( lat, lng );
	var point     = new GLatLng( lat, lng );
	var strStatus = "<strong>(" + charLabel + ") " + strTitle + "</strong><br>WGS84 (" + wgs84.latitude.toFixed(4) + "," + wgs84.longitude.toFixed(4) + ")";
	var strInfo   = "<strong>(" + charLabel + ")<br>" + strTitle + "</strong><br>WGS84 (" + wgs84.latitude.toFixed(4) + "," + wgs84.longitude.toFixed(4) + ")";
	var strTip    = "(" + charLabel + ") " + strTitle;
	var iIcon     = new GIcon( bkcBaseIcon ); 
	
	if ( wgs84.isGreatBritain() ) {
		var osgb = wgs84.getOSGB();
		strStatus += " GB " + osgb.getGridRef(3).split(" ").join("");
		strInfo   += "<br>GB " + osgb.getGridRef(3).split(" ").join("");
		if ( wgs84.isIreland() ) {
			var osni = wgs84.getIrish();
			strStatus += " IRE " + osni.getGridRef(3).split(" ").join("");
			strInfo   += " IRE " + osni.getGridRef(3).split(" ").join("");
		}
	}
			
	if ( t == "access" ) {
		strStatus   = "<strong>Access point</strong> " + strStatus;
		strInfo     = "<strong>Access point</strong> " + strInfo;
		strTip      = "Access point " + strTip;
		iIcon.image = "http://belfastkayakclub.co.uk/markers/blue/marker" + charLabel + ".png";
	} else {
		if ( t == "feature" ) {
			strStatus   = "<strong>Feature</strong> " + strStatus;
			strInfo     = "<strong>Feature</strong> " + strInfo;
			strTip      = "Feature " + strTip;
			iIcon.image = "http://belfastkayakclub.co.uk/markers/green/marker" + charLabel + ".png";
		} else {
			iIcon.image = "http://belfastkayakclub.co.uk/markers/yellow/marker" + charLabel + ".png";
		}
	}
	
	var markerOptions = { icon: iIcon, title: strTip };
	if ( bkcCreateEditableMap ) { markerOptions.draggable = true; }
	
	var marker = new GMarker( point, markerOptions );
	
	marker.bkcLabel     = charLabel;
	marker.bkcTitle     = strTitle;
	marker.bkcType      = t;
	marker.bkcStatus    = strStatus;
	marker.bkcGoogleURL = "http://maps.google.co.uk/maps?q="+lat+","+lng+"("+strTitle+")";

	bkcGMap.addOverlay( marker );
	
	GEvent.addListener( marker, "click", function() {
		bkcStatusDiv.innerHTML = this.bkcStatus;
		bkcGMap.setCenter( this.getLatLng(), 14 );
		if ( bkcGMapCreateOSMap ) { bkcOSImageFromGMapClick(); }
		if ( bkcCreateEditableMap ) { bkcMarkerOpenForEditing = this; }
	});	
	
	GEvent.addListener( marker, "dblclick", function() { window.open( marker.bkcGoogleURL, "Map" ); });	
	
	GEvent.addListener( marker, "mouseover", function() { bkcStatusDiv.innerHTML = marker.bkcStatus; });	
	
	GEvent.addListener( marker, "mouseout", function() { bkcStatusDiv.innerHTML = bkcDefaultStatus; });

	GEvent.addListener( marker, "dragend", function(p) { this.setLatLng(p); });

	if ( bkcCreateEditableMap ) { marker.enableDragging(); }
	
	bkcGMapMarkers.push( marker );
	
	// marker.bindInfoWindowHtml( strInfo, { maxWidth: 100 } );
	var n = bkcGMapMarkers.length - 1;
	if ( bkcCreateEditableMap ) { 
		marker.bkcIndex = n;
		marker.bindInfoWindowHtml( 
			"<div style='text-align: left;'>" 
			+ "<p>Marker Label <input id='bkcMarkerLabel" + n + "' size='3' value='" + charLabel + "'>" 
			+ "&nbsp;&nbsp;&nbsp;Type <select id='bkcMarkerType" + n + "'>"
			+ "<option value='access' " + ( t == "access" ? "selected" : "" ) + ">Access</option>" 
			+ "<option value='feature' " + ( t == "feature" ? "selected" : "" ) + ">Feature</option>" 
			+ "</select></p>" 
			+ "<p>Description  <input id='bkcMarkerTitle" + n + "' size='30' value='" + strTitle.replace(/'/g,"&apos;") + "'></p>" 
			+ "<p>Delete this marker  <input id='bkcMarkerDel" + n + "' type='checkbox'></p>" 
			+ "</div>" 
		);
		GEvent.addListener( marker, "infowindowbeforeclose", function() { 
			var i = this.bkcIndex;
			var del = document.getElementById('bkcMarkerDel'+i).checked; 
			this.bkcLabel = document.getElementById('bkcMarkerLabel'+i).value; 
			this.bkcType  = document.getElementById('bkcMarkerType'+i).value; 
			this.bkcTitle = document.getElementById('bkcMarkerTitle'+i).value; 
			if ( this.bkcType == "access" ) { 
				this.setImage( "http://belfastkayakclub.co.uk/markers/blue/marker" + this.bkcLabel + ".png" ); 
			} else {
				if ( this.bkcType == "feature" ) { 
					this.setImage( "http://belfastkayakclub.co.uk/markers/green/marker" + this.bkcLabel + ".png" ); 
				} else {
					this.setImage( "http://belfastkayakclub.co.uk/markers/yellow/marker" + this.bkcLabel + ".png" ); 
				}
			}
			if ( del ) { setTimeout( 'bkcDeleteMarker(' + i + ')', 2000 ); }
		});
		GEvent.addListener( marker, "infowindowclose", function() { 
			var i = this.bkcIndex;
			bkcUpdateMarkerInfoWindow(i);
		});
	}
		
}

function bkcUpdateMarkerInfoWindow( i ) {
	if ( i >= bkcGMapMarkers.length ) { return; }	
	var marker = bkcGMapMarkers[i];
	marker.bindInfoWindowHtml( 
		"<div style='text-align: left;'>" 
		+ "<p>Marker Label <input id='bkcMarkerLabel" + i + "' size='3' value='" + marker.bkcLabel + "'>" 
		+ "&nbsp;&nbsp;&nbsp;Type <select id='bkcMarkerType" + i + "'>"
		+ "<option value='access' " + ( marker.bkcType == "access" ? "selected" : "" ) + ">Access</option>" 
		+ "<option value='feature' " + ( marker.bkcType == "feature" ? "selected" : "" ) + ">Feature</option>" 
		+ "</select></p>" 
		+ "<p>Description  <input id='bkcMarkerTitle" + i + "' size='30' value='" + marker.bkcTitle.replace(/'/g,"&apos;") + "'></p>" 
		+ "<p>Delete this marker  <input id='bkcMarkerDel" + i + "' type='checkbox'></p>" 
		+ "</div>" 
	);
}

// -------------------------------------------------------------------------------------------------
//
// Add a route
//

function bkcGMapAddRoute( pts, col, w ) {

	var route = new GPolyline( pts, col, w );

	route.bkcRouteLength = ( route.getLength() / 1000 ).toFixed(2);

	route.bkcStrokeColor = col;
	route.bkcStrokeWidth = w;

	GEvent.addListener( route, "mouseover", function() { 
		this.setStrokeStyle( { color: "#00FF00", weight: 4 } );
		bkcStatusDiv.innerHTML = "Route is " + this.bkcRouteLength + " Km"; 
	});	

	GEvent.addListener( route, "mouseout", function() { 
		this.setStrokeStyle( { color: this.bkcStrokeColor, weight: this.bkcStrokeWidth } );
		bkcStatusDiv.innerHTML = bkcDefaultStatus; 
	});

	if ( bkcCreateEditableMap ) { 
		GEvent.addListener( route, "click", function() { 
			this.enableEditing(); 
			if ( bkcRouteOpenForEditing != null && bkcRouteOpenForEditing != this ) { bkcRouteOpenForEditing.disableEditing(); }
			bkcRouteOpenForEditing = this;
		}); 
	}
	bkcGMap.addOverlay( route );
	bkcGMapRoutes.push( route );
}

// -------------------------------------------------------------------------------------------------
//
// Load a file of markers, lines (rivers), info and photos
//

function bkcGMapLoadOverlaysFromXML(str) {

	var request = GXmlHttp.create();
	var debugText = "";

	request.open("GET", str, true);

	request.onreadystatechange = function() {

		if (request.readyState == 4) {

			var i, lat, lng, ref, label, strTitle, col, t, w, wgs84, z;
			var xmlDoc = GXml.parse(request.responseText);
			if ( !xmlDoc.documentElement ) { return; }

			bkcGMapMarkers.length = 0;
			bkcGMapRoutes.length = 0;
			
			var centers = xmlDoc.documentElement.getElementsByTagName("center");
			if ( bkcCenterOnLoad ) {
				for ( i = 0; i < centers.length; i++ ) {
					lat = parseFloat(centers[i].getAttribute("lat"));
					lng = parseFloat(centers[i].getAttribute("lng"));
					ref = centers[i].getAttribute("irishGridRef");
					label = centers[i].getAttribute("label");
					z = parseInt(centers[i].getAttribute("zoom"));
					if ( ref ) { 
						wgs84 = bkcGMapConvertIrishGridRef( ref );
						lat = wgs84.latitude;
						lng = wgs84.longitude;
					}
					debugText += "<p>Center " + lat + " " + lng + " " + z + "</p>";
					bkcGMap.setCenter( new GLatLng(lat,lng), z );
				}
			}
			
  			var markers = xmlDoc.documentElement.getElementsByTagName("marker");
		 	for ( i = 0; i < markers.length; i++ ) {
				lat = parseFloat(markers[i].getAttribute("lat"));
				lng = parseFloat(markers[i].getAttribute("lng"));
				ref = markers[i].getAttribute("irishGridRef");
				label = markers[i].getAttribute("label");
				strTitle = markers[i].getAttribute("title");
				t = markers[i].getAttribute("type");
				if ( ref ) { 
					wgs84 = bkcGMapConvertIrishGridRef( ref );
					lat = wgs84.latitude;
					lng = wgs84.longitude;
				}
				debugText += "<p>Marker " + lat + " " + lng + " " + label + " " + strTitle + " " + t + "</p>";
				bkcGMapAddMarker( lat,lng, label, strTitle, t );
      		}

		 	var lines = xmlDoc.documentElement.getElementsByTagName("line");
		 	for ( i = 0; i < lines.length; i++ ) {
				col = lines[i].getAttribute("color");
				w = parseFloat(lines[i].getAttribute("width"));
				var points = lines[i].getElementsByTagName("point");
				var pts = [];
				for ( j = 0; j < points.length; j++ ) {
					lat = parseFloat(points[j].getAttribute("lat"));
					lng = parseFloat(points[j].getAttribute("lng"));
					ref = points[j].getAttribute("irishGridRef");
					label = points[j].getAttribute("label");
					strTitle = points[j].getAttribute("strTitle");
					if ( ref ) { 
						wgs84 = bkcGMapConvertIrishGridRef( ref );
						lat = wgs84.latitude;
						lng = wgs84.longitude;
					}
					pts[j] = new GLatLng( lat, lng );
				}
				debugText += "<p>Line</p>";
				bkcGMapAddRoute( pts, col, w );
			}
			
			var debugElement = document.getElementById( "debugContainer" );
			if ( debugElement ) { debugElement.innerHTML = debugText; }
		}
	 }

	 request.send( null );
}

// -------------------------------------------------------------------------------------------------
//
// Save a file of markers, lines (rivers), info and photos
//

function bkcEncodeAttr( str ) {
	var s = str;
	s = s.replace(/&/g,"&amp;");
	s = s.replace(/</g,"&lt;");
	s = s.replace(/>/g,"&gt;");
	s = s.replace(/'/g,"&apos;");
	return s;
}

function bkcGMapSaveOverlaysToXML() {
	
	var str = "<overlays>\n";
	var i, j;
	var p = bkcGMap.getCenter();
	var z = bkcGMap.getZoom();
	var n;
	
  	str += "  <center lat='" + p.lat() + "' lng='" + p.lng() + "' zoom='" + z + "' />\n";
  	
	for ( i=0; i<bkcGMapMarkers.length; i++ ) {
		p = bkcGMapMarkers[i].getLatLng();
  		str += "  <marker lat='" + p.lat().toFixed(4) + "' lng='" + p.lng().toFixed(4) + "' " 
  					+ "label='" + bkcEncodeAttr(bkcGMapMarkers[i].bkcLabel) + "' " 
  					+ "title='" + bkcEncodeAttr(bkcGMapMarkers[i].bkcTitle) + "' " 
  					+ "type='" + bkcEncodeAttr(bkcGMapMarkers[i].bkcType) + "' />\n";
	}
	
	for ( i=0; i<bkcGMapRoutes.length; i++ ) {
		str += "  <line color='" + bkcGMapRoutes[i].bkcStrokeColor + "' width='" + bkcGMapRoutes[i].bkcStrokeWidth + "'>\n";
		n = bkcGMapRoutes[i].getVertexCount() ;
		for ( j=0; j <n; j++ ) {
			p = bkcGMapRoutes[i].getVertex(j);
	  		str += "    <point lat='" + p.lat().toFixed(4) + "' lng='" + p.lng().toFixed(4) + "' />\n";
		}
		str += "  </line>\n";
	}
	
	return str + "</overlays>\n";	
}

// -------------------------------------------------------------------------------------------------
//
// Delete a marker
//

function bkcDeleteMarker(n) {
	if ( n<0 || n>=bkcGMapMarkers.length ) { return; }
	var temp = new Array();
	for ( i=0; i<bkcGMapMarkers.length; i++ ) {
		if ( i == n ) { 
			bkcGMap.removeOverlay( bkcGMapMarkers[i] );
		} else {
			temp.push( bkcGMapMarkers[i] ); 
		}
	}
	bkcGMapMarkers = temp;
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
//
// Multimap static images - Ordinance Survey maps
//

function bkcOSImageFromGMapClick() {

	var center  = bkcGMap.getCenter();	
	var img_src = "http://developer.multimap.com/API/map/1.2/OA09062517428591256?mapType=map&dataPreferences=925%2C916&zoomFactor=14";
	var a_href  = "http://www.multimap.com/maps/?countryCode=GB&dp=925,916&zoomFactor=14&qs=" + center.lat().toFixed(4) + "%2C" + center.lng().toFixed(4);

	img_src += "&width=" + bkcGMapWidth + "&height=" + bkcGMapHeight + "&marker=circle%2Epng";
	img_src += "&lat=" + center.lat().toFixed(4) + "&lon=" + center.lng().toFixed(4);
		
	var str = "<a href='" + a_href + "' target='OSMap'>" +
			  "<img border='0' src='" + img_src + "' width='" + bkcGMapWidth + "' height='" + bkcGMapHeight + "' alt='OS Map'>" +
			  "</a>";
			  
	if ( bkcOSMapCanvas ) { bkcOSMapCanvas.innerHTML = "<p>&nbsp;</p>" + str; }
	
	return str;
}

function bkcOSImageFromGMap() {

	var center  = bkcGMap.getCenter();	
	var img_src = "http://developer.multimap.com/API/map/1.2/OA09062517428591256?width=" + bkcGMapWidth + "&height=" + bkcGMapHeight + "&mapType=map&dataPreferences=925%2C916&zoomFactor=14";
	var a_href  = "http://www.multimap.com/maps/?countryCode=GB&dp=925,916&zoomFactor=14&qs=" + center.lat().toFixed(4) + "%2C" + center.lng().toFixed(4);
	var i;
	
	if ( bkcGMapCreateOSMapMarker ) {

		for ( i=0; i<bkcGMapMarkers.length; i++ ) {
	
			var p = bkcGMapMarkers[i].getLatLng();
			var n = i + 1;
	
			img_src += "&lat_"    + n + "=" + p.lat().toFixed(4);
			img_src += "&lon_"    + n + "=" + p.lng().toFixed(4);
			img_src += "&label_"  + n + "=" + bkcGMapMarkers[i].bkcLabel;
			img_src += "&marker_" + n + "=circle%2Epng";
	
			a_href  += "&lat_"    + n + "=" + p.lat().toFixed(4);
			a_href  += "&lon_"    + n + "=" + p.lng().toFixed(4);
			a_href  += "&label_"  + n + "=" + bkcGMapMarkers[i].bkcLabel;
			a_href  += "&marker_" + n + "=circle%2Epng";
		}

	} else { 
	
			img_src += "&lat_1=" + center.lat().toFixed(4);
			img_src += "&lon_1=" + center.lng().toFixed(4);
			img_src += "&label_1=none";
			img_src += "&marker_1=none";	
			
	}
		
	var str = "<a href='" + a_href + "' target='OSMap'>" +
			  "<img border='0' src='" + img_src + "' width='" + bkcGMapWidth + "' height='" + bkcGMapHeight + "' alt='OS Map'>" +
			  "</a>";
			  
	GEvent.addListener( bkcGMap, "moveend", bkcOSImageFromGMapClick ); 

	if ( bkcOSMapCanvas ) { bkcOSMapCanvas.innerHTML = "<p>&nbsp;</p>" + str; }
	
	return str;
}

// -------------------------------------------------------------------------------------------------

function bkcOSImageWGS84( lat, lng, label ) {
	
	var img_src = "http://developer.multimap.com/API/map/1.2/OA09062517428591256?width=500&height=300&mapType=map&dataPreferences=925%2C916"
					+ "&lat=" + lat.toFixed(4) + "&lon=" + lng.toFixed(4) + "&label=" + label + "&marker=circle%2Epng&zoomFactor=15";
	
	var a_href = "http://www.multimap.com/maps/?qs=" + lat.toFixed(4) + "%2C" + lng.toFixed(4) + "&countryCode=GB&dp=925,916";
	
	document.write( 
		"<a href='" + a_href + "'>" +
		"<img border='0' src='" + img_src + "' width='500' height='300' alt='OS Map @ (" + lat + "," + lng + ")'>" +
		"</a>" );
}

// -------------------------------------------------------------------------------------------------

function bkcOSImageRef( ref, label ) {

	var wgs84 = bkcGMapConvertIrishGridRef(ref);

	bkcOSImageWGS84( wgs84.latitude, wgs84.longitude, label );

}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
//
// Photo markers
//

function PhotoMarker(latLng,markerImage,markerSize,markerOffset,photoImage,photoSize,photoOffset,shadowImage,shadowSize,shadowOffset) {
	this.latLng       = latLng;
	this.markerImage  = markerImage;
	this.markerSize   = markerSize;
	this.markerOffset = markerOffset;
	this.photoImage   = photoImage;
	this.photoSize    = photoSize;
	this.photoOffset  = photoOffset;
	this.shadowImage  = shadowImage;
	this.shadowSize   = shadowSize;
	this.shadowOffset = shadowOffset;
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype = new google.maps.Overlay();

// -------------------------------------------------------------------------------------------------

pmAppendElement = function( parentElement, elementType, properties ) {
	var element = document.createElement( elementType );
	if ( properties ) {
		for ( property in properties ) {
			if ( property == 'style' ) {
				for ( nestedProperty in properties[property] ) {
					element.style[nestedProperty] = properties['style'][nestedProperty];
				}
			} else {
				element[property] = properties[property];
			}
		}
	}
	parentElement.appendChild(element);
	return element;
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.initialize = function(map) {
	
	var me = this;
	
	this.map = map;
	
	this.markerDiv = pmAppendElement(
						map.getPane(google.maps.MAP_MARKER_PANE),
						'div',
						{
							title: this.title,
							style:
								{
									position: 'absolute'
								}
						});

	if ( this.markerImage ) {
		this.markerImg = pmAppendElement(
							this.markerDiv,
							'img',
							{
								src: this.markerImage,
								style: 
									{
										position: 'absolute',
										zIndex:   '0',
										width:    this.markerSize.width + 'px',
										height:   this.markerSize.height + 'px',
										cursor:   'pointer'
									}
							});
		GEvent.addDomListener( this.markerImg, "click", function(event){GEvent.trigger(me,"click");} );
	}

	if ( this.photoImage ) {
		this.photoImg = pmAppendElement(
							this.markerDiv,
							'img',
							{
								src: this.photoImage,
								style: 
									{
										position: 'absolute',
										zIndex:   '1',
										width:    this.photoSize.width + 'px',
										height:   this.photoSize.height + 'px',
										left:     this.photoOffset.x + 'px',
										top:      this.photoOffset.y + 'px',
										cursor:   'pointer'
									}
							});
		GEvent.addDomListener( this.photoImg, "click", function(event){GEvent.trigger(me,"click");} );
	}
	
	if ( this.shadowImage ) {
		this.shadowImg = pmAppendElement(
							map.getPane(google.maps.MAP_MARKER_SHADOW_PANE),
							'img',
							{
								src: this.shadowImage,
								style:
									{
										position: 'absolute',
										width:    this.shadowSize.width + 'px',
										height:   this.shadowSize.height + 'px'
									}
							});
	}
	
	this.targetDiv = pmAppendElement(
						map.getPane(google.maps.MAP_MARKER_MOUSE_TARGET_PANE),
						'div',
						{
							title: this.title,
							style:
								{
									position: 'absolute',
									width:    this.markerSize.width + 'px',
									height:   this.markerSize.height + 'px',
									cursor:   'pointer'
								}
						});
	GEvent.addDomListener( this.targetDiv, "click", function(event){GEvent.trigger(me,"click");} );
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.remove = function() {
	this.markerDiv.parentNode.removeChild( this.markerDiv );
	if ( this.shadowImg ) { this.shadowImg.parentNode.removeChild(this.shadowImg); }
	this.targetDiv.parentNode.removeChild( this.targetDiv );
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.copy = function() {
	return new PhotoMarker(this.latLng,this.markerImage,this.markerSize,this.markerOffset,this.photoImage,this.photoSize,this.photoOffset,this.shadowImage,this.shadowSize,this.shadowOffset);
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.redraw = function(force) {

	if ( !force ) { return; }

	var divPixel = this.map.fromLatLngToDivPixel(this.latLng);
	var zIndex   = Math.floor(this.latLng.lat()*-1000000);
	
	this.markerDiv.style.left   = ( divPixel.x - this.markerOffset.x ) + 'px';
	this.markerDiv.style.top    = ( divPixel.y - this.markerSize.height - this.markerOffset.y ) + 'px';
	this.markerDiv.style.zIndex = zIndex;

	if ( this.shadowImg ) {
		this.shadowImg.style.left   = ( divPixel.x - this.shadowOffset.x ) + 'px';
		this.shadowImg.style.top    = ( divPixel.y - this.shadowSize.height - this.shadowOffset.y ) + 'px';
		this.shadowImg.style.zIndex = zIndex;
	}

	this.targetDiv.style.left   = ( divPixel.x - this.markerOffset.x ) + 'px';
	this.targetDiv.style.top    = ( divPixel.y - this.markerSize.height - this.markerOffset.y ) + 'px';
	this.targetDiv.style.zIndex = zIndex;
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.getKml=function(callback) {
	callback(null);
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.getLatLng=function() {
	return this.latLng;
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.setLatLng=function(latLng) {
	this.latLng=latLng;
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.getTitle=function() {
	return this.title;
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.setTitle=function(title) {
	this.title = title;
	if ( this.markerDiv ) this.markerDiv.title = title;
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.show=function() {
	if ( this.markerDiv ) { this.markerDiv.style.display = "block"; }
	if ( this.shadowImg ) { this.shadowImg.style.display = "block"; }
	if ( this.targetDiv ) { this.targetDiv.style.display = "block"; }
}

// -------------------------------------------------------------------------------------------------

PhotoMarker.prototype.hide=function() {
	if ( this.markerDiv ) { this.markerDiv.style.display = "none"; }
	if ( this.shadowImg ) { this.shadowImg.style.display = "none"; }
	if ( this.targetDiv ) { this.targetDiv.style.display = "none"; }
}

// -------------------------------------------------------------------------------------------------
// -------------------------------------------------------------------------------------------------
//
// Flickr photos
//

function FlickrAPI( key, shared_secret ) {

	var auth_url      = 'http://flickr.com/services/auth/?';
	var rest_url      = '/flickr_proxy.php?yws_path=';
	var key           = key;
	var shared_secret = shared_secret;
	var xmlhttp       = null;

	function getSig(perms){
		var sig = shared_secret + "api_key" + key +  "perms" + perms; 
		return hex_md5(sig);
	}

	this.getLoginURL = function(perms) {
		var url = auth_url + "api_key=" + key + "&perms=" + perms + "&api_sig=" + getSig(perms);
		return url;
	}

	this.callMethodXML = function(method, params) {
		return _call(method, params);
	}

	this.callMethodJSON = function(method, params) {
		params['format']         = 'json';
		params['nojsoncallback'] = 1; 
		return _call(method, params);
	}

	function _call(method, params) {
		var url     = rest_url;
		var tmp_url = "http://api.flickr.com/services/rest?method=" + method + "&api_key=" + key;
		for ( key in params ) {
			tmp_url += "&" + key + "=" + params[key]; 
		}
		url += encodeURIComponent(tmp_url);
		xmlhttp = xmlHttpCreate();
		xmlhttp.open("GET", url, false);
		xmlhttp.send(""); 
		if ( params['format'] = 'json' ) {	
			return xmlhttp.responseText;
		}
		return xmlhttp.responseXML;
	}

	function xmlHttpCreate() {
		var req = null;
		try { 
			req = new ActiveXObject("Msxml2.XMLHTTP"); 
		} catch(e) { 
			try { 
				req = new ActiveXObject("Microsoft.XMLHTTP"); 
			} catch(sc) { 
				req = null; 
			}
		}
		if ( !req && typeof XMLHttpRequest != "undefined" ) { req = new XMLHttpRequest(); }
		return req; 
	}
}

// -------------------------------------------------------------------------------------------------

var bkcFlickrAPI = new FlickrAPI( bkcFlickrAPIKey, "" ); 

function bkcGMapLoadFlickrPhotos() {
			
	var params  = new Array();
	
	params['per_page'] = 15;
	params['api_key']  = bkcFlickrAPIKey;
	params['user_id']  = bkcFlickrUserId;
	params['tags']     = 'route';
	params['extras']   = 'has_geo,geo,url_sq,url_s';
	params['per_page'] = 500;

	var json   = bkcFlickrAPI.callMethodJSON('flickr.photos.search',params);			
	var obj    = eval('(' + json + ')');
	
	if ( obj.stat == "fail" ) { alert( "There was an error loading photos from Flickr" ); return; }
	
	var photos = obj.photos.photo;
				
	for(i = 0; i < photos.length; i++){    

		var latitude  = photos[i].latitude;
		var longitude = photos[i].longitude;
		var url_m     = photos[i].url_s;
		var width_m   = photos[i].width_s;
		var height_m  = photos[i].height_s;
		var url_sq    = photos[i].url_sq;
		var width_sq  = photos[i].width_sq;
		var height_sq = photos[i].height_sq;
		var id        = photos[i].id;
		var strTitle  = photos[i].title ? photos[i].title : "Flickr Photo";
		
		var p = new GLatLng( latitude, longitude );
		
		/*
		var photoMarker = new PhotoMarker( p,
								'http://belfastkayakclub.co.uk/images/flickrMarker.png', new google.maps.Size(100,83), new google.maps.Point(-50,50), 
								url_sq, new google.maps.Size(width_sq,height_sq), new google.maps.Point(21,4) );
		*/
		
		var photoMarker = new PhotoMarker( p,
								'http://belfastkayakclub.co.uk/images/flickrMarker240.png', new GSize(240,240), new GPoint(-50,50), 
								url_m, new GSize(width_m,height_m), new GPoint(0,0) );

		photoMarker.setTitle( strTitle );
		photoMarker.url = 'http://www.flickr.com/photo.gne?id='+id;
		GEvent.addListener( photoMarker, "click", function() { window.open(this.url,"Flickr"); });	
		
		// bkcGMap.addOverlay( photoMarker );
		bkcGMapFlickrImages.push( photoMarker );
		
		var iIcon   = new GIcon( bkcBaseIcon ); 
		iIcon.image = "http://belfastkayakclub.co.uk/markers/marker_flickr.png";

		var markerOptions = { icon: iIcon, title: strTitle };
		var marker = new GMarker( p, markerOptions );
		marker.url = 'http://www.flickr.com/photo.gne?id='+id;
		marker.photoMarker = photoMarker;
		GEvent.addListener( marker, "click", function() { window.open(this.url,"Flickr"); });	
		GEvent.addListener( marker, "mouseover", function() { bkcGMap.addOverlay(this.photoMarker); });	
		GEvent.addListener( marker, "mouseout", function() { bkcGMap.removeOverlay(this.photoMarker); });	

		bkcGMap.addOverlay( marker );
		bkcGMapFlickrMarkers.push( marker );
				
	}
}


