    //<![CDATA[

    var centreLat=0.0;
    var centreLon=0.0;
    var initialZoom=2
    var map; //the GMap2 itself
		var which = "mas"; // which map will it be, hmm?
		var ii = "mas-flag";
		var ino = 0;
		var m, p, bigiurl;

		var mas_default = "http://uk.youtube.com/watch?v=t3InhMdcK1w";

		// I think I'm reducing CPU here, at the expense of memory. I'm not sure which is better. Advice welcome.
		var marks = new Array(); // Array to store all the markers.
		var markeys = new Array();

		var layers = new Array();

		var icon = new GIcon();
		icon.image = "images/" + ii + ".gif";
		icon.iconSize = new GSize(15, 30);
		icon.iconAnchor = new GPoint(7, 25);
		icon.infoWindowAnchor = new GPoint(10, 15);

		function update_layers(t) {
			// Somehow need to segregate the layers, so that we can show only those 
			// which are relevant.

			// This likely means that we'll need to store the layers in a proper array, so that 
			// they can be switched off. This needs more thought - they need to be assigned at
			// creation time.

			// So, it would need an array of markers, with something like
			// markers["some id"]["class"] = map/type hash (mas/as_flag)
			// markers["some id"]["marker"] = GMarker

			// Questions. How do we generate "some id"
			// how do we generate map-type combo
			// map is defined by the dropdown, which is held in 'which'.
			// type is stored in, erm, ii
			// so, maptype hash is which + "-" + ii
			// How to build someid. maybe just concat lat/lon.

			// Therefore
			// someid = mo.getAttribute["lat"] + mo.getAttribute["lon"];
			// class = which + "-" + ii;
			// xml file should be named after class.
		
			var checked = t.checked;
			var layer = which + "-" + t.value;
			var j = marks.length;

			// Log
			urchinTracker("/layer/" + layer);

			if(!checked) {
				// remove that layer.
				for(var i = 0;i < j; i++) {
					// alert("When removing layer in update_layers, marks[" + i + "]['class'] = " + marks[i]["class"] + " and we're comparing to " + layer);
					if(marks[i]["class"] == layer) {
						map.removeOverlay(marks[i]["m"]);
					}
				}
				
			}
			else {
				// Add that layer.
				// Is it already loaded?
				// alert("In update layers, markeys[" + layer + "] = " + layer);
				if(!markeys[layer]) {
					load_markers(t.value);
				}
				else {
					// Ok. Thunderbirds are go.
					for(var i = 0;i < j; i++) {
						// alert(marks[i]["class"] + "-" + layer);
						if(marks[i]["class"] == layer) {
							map.addOverlay(marks[i]["m"]);
						}
					}
				}
				
			}
		}

		function show_big(i) {
			// map.openInfoWindowHtml(map.getCenter(), "<img src='images/mas/18_large.jpg'>");
			var e = document.getElementById("bigimg");
			var x;
			if(bigiurl) x = bigiurl;
			else x = "images/" + which + "/" + i + "_large.jpg";
			e.innerHTML =  "<img src='" + x + "' onclick='hide_big()' title='click to return' alt='masyaf assassin flag'>";
			e.innerHTML += "<br>From <a href='http://picasaweb.google.com/chewing/AssassinsCreed'>Assassins Creed</a>";
			e.style.display = 'block';
			urchinTracker("/showimage/big/" + which + "/" + i + "_large.jpg");
		}

		function hide_big() {
			var e = document.getElementById("bigimg");
			e.style.display = 'none';
		}

		function cm(p, mo, pos) {
			// Marker options
			// THis needs to be altered to send the right image each time. Might need multiple icon  objects. Unclear at this stage.
			var thisicon = new GIcon(icon);
			thisicon.image = "images/" + ii + ".gif";
			// alert(icon.image);
			var mO = { icon:thisicon };
			// Marker
			var m = new GMarker(p, mO);
			ino = mo.getAttribute("img");
			bigiurl = mo.getAttribute("ibig");
			if(!bigiurl) bigiurl = "";

			// Possibly not mine, so no direct link.
			bigilink = mo.getAttribute("bigilink");
			if(!bigilink) bigilink = "";
			
			var x = "<img align='center' onclick='show_big(\"" + bigiurl + "\")' src='images/" + which + "/" + ino + "_small.jpg' ";
			x += "width='254' height='190' title='Click me'>";

			if(!bigiurl && bigilink) {
				x = "";
				if(mo.getAttribute("extra")) 
					x = mo.getAttribute("extra") + "<br>";
				x += "<a href='" + bigilink + "' target='_largeimg'><img ";
				x += "align='center' src='images/" + which + "/" + ino + "_small.jpg' ";
				x += "width='254' height='190' title='Click me' border='0'></a>";
			}
			var vidstring = "";
			
			if(!ino) x = mo.getAttribute("lat");
			x += "<br>Got a better picture? <a href='contact.php'>Send it in</a>";
			GEvent.addListener(m, "click", function() {
				// var l1 = new GInfoWindowTab("Pic", mo.getAttribute("lat"));
				var l1 = new GInfoWindowTab("Pic", x);
				if(mo.getAttribute("vid")) {
					vidstring = '<object width="318" height="279"><param name="movie" value="http://www.youtube.com/v/';
					vidstring += mo.getAttribute("vid");
					vidstring += '&rel=0"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/';
					vidstring += mo.getAttribute("vid");
					vidstring += '&rel=0" type="application/x-shockwave-flash" wmode="transparent"';
					vidstring += ' width="318" height="279"></embed></object><br>';
				}
				if(which == "mas" && !vidstring) {
					vidstring = "<a href='" + mas_default + "' target='_blank'>See all the Masyaf flags</a><br>";
				}
				
			
				var l2 = new GInfoWindowTab("Vid", vidstring + 'Got a video? <a href="contact.php">Send it in</a>');
				urchinTracker("showimage/small/" + which + "/" + ino + "_small.jpg");
				m.openInfoWindowTabsHtml([l1, l2 ]);
			});
			return m;
			
		}

		function load_markers(layer) {
			var key = which + "-" + layer;
			var file = key + ".xml";
			// alert(file);
			var marker;
			

			GDownloadUrl(file, function(data, responseCode) {
				var xml = GXml.parse(data);
				var nom = "";
				markers = xml.documentElement.getElementsByTagName("marker");
				// alert("Loading: Length: " + markers.length);
				for(var i = 0; i < markers.length; i++) {
					
					var lat = parseFloat(markers[i].getAttribute("lat"));
					var lon = parseFloat(markers[i].getAttribute("lon"));
					p = new GLatLng(lat, lon);
			
					var someid = "" + lat + "-" + lon + "-" + which; 

					// alert("Markeys[" + key + "]: " + markeys[key]);
					// Do the markers exist?
					if(!markeys[key]) {
						// Do I have to do this? Is there an easier way to add to arrays?
						var cake = marks.length;
						marks[cake] = new Array();
						marks[cake]["class"] = key;
						ii = key;
						marker = cm(p, markers[i], i);
						marks[cake]["m"] = marker;
						marks[cake]["icon"] = icon;
					}
					map.addOverlay(marker);
				}
				// alert("going to update markeys with this key: " + key);
				markeys[key] = 1;
			});
		}

		function recentre() {
			map.setCenter(new GLatLng(centreLat, centreLon));
		}

		function update_options() {
			// Ok. So.
			// Which is the layer. Need to first unload all layers, then, erm, load these layers.
			map.clearOverlays();

			// Walk the layers. Add the right ones. Which are checked. Shit.
			var j = marks.length;
			var cf =  which + "-flag";
			var ct =  which + "-temp";
			var cfloaded = 0;
			var ctloaded = 0;
			
			for(var i=0;i<j;i++) {
			// alert(cf + " | " + marks[i]["class"]);
					
				if((marks[i]["class"] == cf && document.getElementById("checkflag").checked) ||
					 (marks[i]["class"] == ct && document.getElementById("checktemp").checked)) {
					map.addOverlay(marks[i]["m"]);
				}
				if(marks[i]["class"] == cf) cfloaded = 1;
				if(marks[i]["class"] == ct) ctloaded = 1;
			}
			if(!cfloaded && document.getElementById("checkflag").checked) load_markers("flag");
			if(!ctloaded && document.getElementById("checktemp").checked) load_markers("temp");
		}

		function switch_map(t) {
			// Somehow reload the map.
			// Also, set the variable;
			if(t.options[t.selectedIndex].value == 0) return;
			which = t.options[t.selectedIndex].value;
			urchinTracker("/map/" + which);
			recentre();
			update_options();
		}
    function customGetTileURL(a,b) {
			
      //converts tile x,y into keyhole string
      
      // b is zoom. Maybe.
      // Fix it.

      var c=Math.pow(2,b);

        var d=a.x;
        var e=a.y;
        var f="t";
        for(var g=0;g<b;g++){
            c=c/2;
            if(e<c){
                if(d<c){f+="q"}
                else{f+="r";d-=c}
            }
            else{
                if(d<c){f+="t";e-=c}
                else{f+="s";d-=c;e-=c}
            }
        }
        return "tiles/" + which + "/" + f + ".jpg"
    }


    function getWindowHeight() {
        if (window.self&&self.innerHeight) {
            return self.innerHeight;
        }
        if (document.documentElement&&document.documentElement.clientHeight) {
            return document.documentElement.clientHeight;
        }
        return 0;
    }

    function resizeMapDiv() {
        //Resize the height of the div containing the map.
        //Do not call any map methods here as the resize is called before the map is created.
    	var d=document.getElementById("map");
        var offsetTop=0;
        for (var elem=d; elem!=null; elem=elem.offsetParent) {
            offsetTop+=elem.offsetTop;
        }
        var height=getWindowHeight()-offsetTop-16;
        if (height>=0) {
            d.style.height=height+"px";
        }
    }


    function load() {
      if (GBrowserIsCompatible()) {
        resizeMapDiv();
        var copyright = new GCopyright(1,
                              new GLatLngBounds(new GLatLng(-90, -180),
                                                new GLatLng(90, 180)),
                              0,
                              "<a href='http://www.lickmyear.org'>Ubisoft Montreal</a>");
        var copyrightCollection = new GCopyrightCollection("Images");
        copyrightCollection.addCopyright(copyright);
        var copyright1 = new GCopyright(2,
                              new GLatLngBounds(new GLatLng(-90, -180),
                                                new GLatLng(90, 180)),
                              0,
                              "<a href=\"http://www.casa.ucl.ac.uk\">CASA</a>");
        // var copyrightCollection = new GCopyrightCollection("GMapImgCutter");
        copyrightCollection.addCopyright(copyright1);

        //create a custom picture layer
        var pic_tileLayers = [ new GTileLayer(copyrightCollection , 0, 17)];
        pic_tileLayers[0].getTileUrl = customGetTileURL;
        pic_tileLayers[0].isPng = function() { return false; };
        pic_tileLayers[0].getOpacity = function() { return 1.0; };
        var pic_customMap = new GMapType(pic_tileLayers, new GMercatorProjection(5), "Pic",
            {maxResolution:4, minResolution:0, errorMessage:"Data not available"});


        //Now create the custom map. Would normally be G_NORMAL_MAP,G_SATELLITE_MAP,G_HYBRID_MAP
        map = new GMap2(document.getElementById("map"),{mapTypes:[pic_customMap]});
        map.addControl(new GLargeMapControl());
        map.addControl(new GMapTypeControl());
				map.addControl(new GOverviewMapControl());
        map.enableDoubleClickZoom();
				map.enableContinuousZoom();
				map.enableScrollWheelZoom();
        map.setCenter(new GLatLng(centreLat, centreLon), initialZoom, pic_customMap);
				/*
				if($_GET["plot"]) { 
					GEvent.addListener(map, 'click', function(overlay, point) {
						if (overlay) {
							map.removeOverlay(overlay);
						} else if (point) {
							var html = '<marker lat="' + point.y + '" lon="' + point.x + '" name="Flag"/>' + "\n";
							document.getElementById("out").value += html;
							map.addOverlay(new GMarker(point));
						}
					});
				}

			*/
				
/////////////////////////////////////////////////////////////////////////////////////
//Add any markers here e.g.
//      map.addOverlay(new GMarker(new GLatLng(x,y)));
/////////////////////////////////////////////////////////////////////////////////////

			load_markers("flag");

			var overlay1 = document.getElementById('layers');
			map.getContainer().appendChild(overlay1);
//			return overlay1;

      }
    }

    //]]>
