// 41d3ea9d76e2e897e527ca64ba91b49b
//
//<![CDATA[
// ---------------------------------------------------------------------------------------------------------------------------------------------
//
// Caret Google Maps wrapper API
// =============================
//
function helpLibGoogleMaps() {
    var helpText = "";
    helpText += "   Caret publicly usable functions: \n";
    helpText += "   -------------------------------- \n";
    helpText += "    load(gmapDivName)                     Initalises a google map in element with given id \n";
    helpText += "    readGmapXML(url)                      Reads and processes xml file. All current markers are destroyed. \n";
    helpText += "    toggleClickToCoords(state)            Enables readback of coords after click on map. Stores values in elements with id 'lng' and 'lat' \n";
    helpText += "    customInfoWindow(content, lng, lat)   Creates html on top of map. Content is html code \n";
    helpText += "    setMapType(mType)                     Changes map type. Possible: map, sat, hybrid, terrain \n";
    helpText += "    gotoCoords(lng,lat)                   Focus map on given coords \n";
    helpText += "    clearMarkers()                        Clears all markers \n";
    helpText += "    clearCustomWindows(id)                Clears all customwindows, or only the one with id \n";
    helpText += "   \n";
    helpText += "   Important variables: \n";
    helpText += "   -------------------- \n";
    helpText += "    clearOldData                          Boolean (0/1) indiciating if old markers should be removes upon loading new xml \n";
    helpText += "    initLat \n";
    helpText += "    initLng \n";
    helpText += "    initZoom                              Coords and zoom level after creation of map (before loading xml) \n";
   alert(helpText);
}
//
// ---------------------------------------------------------------------------------------------------------------------------------------------
    var clearOldData = 1;
    // Focus period.
    var initLat = 52.093416;
    var initLng = 5.118116;
    var initZoom = 17;

    // Don't touch these. Please.
    var map;
    var geocoder;
    var request;
    var ctcHandler;
    var customWindowList = new Array();

    function load(gmapDivName) {
      if (GBrowserIsCompatible()) {
	      map = new GMap2(document.getElementById(gmapDivName));
	      map.addControl(new GLargeMapControl());
	      map.addControl(new GMapTypeControl());
	      // map.addControl(new GOverviewMapControl());
	      map.setCenter(new GLatLng(initLat, initLng), initZoom);
      }
    }

  function toggleClickToCoords(state) {
       if (state) {
	       ctcHandler = GEvent.addListener(map, "click", function(overlay, point) {
			       document.getElementById('lng').value = point.y;
			       document.getElementById('lat').value = point.x;
			       } );
       } else {
	       GEvent.removeListener(ctcHandler);
       }
  }


  function tlabel_clearCustomWindows(winId) {
     if (winId) {
             document.removeChild( document.getElementById(winId) );
             for(i=0;i<customWindowList.length;i++) {
                     if (customWindowsList[i] == winId) { customWindowList[i] = ""; }
             }
     } else  {
             for(i=0;i<customWindowList.length;i++) {
                     if (customWindowList[i]) {
                             var cw = document.getElementById( customWindowList[i] );
                             if (cw) { cw.parentNode.removeChild(cw); }
                     }
             }
     }
  }

  function tlabel_customInfoWindow(content, lng, lat) {
      var customWindow = new TLabel();
      customWindow.id = 'customWindow' + (customWindowList.length + 1);
      customWindow.anchorLatLng = new GLatLng (parseFloat(lng),parseFloat(lat));
      customWindow.anchorPoint = 'bottomLeft';
      customWindow.content = content;
      customWindow.percentOpacity = 70;
      map.addTLabel(customWindow);
      return customWindow.id;
  }

  function elabel_clearCustomWindows(winId) {
  }

  function elabel_customInfoWindow(content, lng, lat) {
      // new ELabel(new GLatLng(lng,lat), content, style, new GSize(offsetXpx, offsetYpx), opacityPct, boolSmartOverlap)
      var customWindow = new ELabel(new GLatLng(lng,lat), content, "customWindowStyle");
      map.addOverlay(customWindow);
      customWindow.show();
      return customWindow;
  }

  // elabels are nicer, but they are not working for me right now....
  function clearCustomWindow(id) { return tlabel_clearCustomWindow(id); }
  function customInfoWindow(content, lng, lat) { return tlabel_customInfoWindow(content, lng, lat); }

function setFocus(focusElm) {
	var lng = parseFloat(focusElm.getAttribute("longitude"));
	var lat = parseFloat(focusElm.getAttribute("latitude"));
	var zoom = parseInt(focusElm.getAttribute("zoom"));
	var mType = focusElm.getAttribute("blabla");
	map.setCenter(new GLatLng(lng, lat), zoom);
}

function setMapType(mType) {
	if (mType == "card" || mType == "normal") {
		map.setMapType(G_NORMAL_MAP);
	} else if (mType == "sat") {
		map.setMapType(G_SATELLITE_MAP);
	} else if (mType == "satellite") {
		map.setMapType(G_SATELLITE_MAP);
	} else if (mType == "hybrid") {
		map.setMapType(G_HYBRID_MAP);
	} else if (mType == "terrain") {
		map.setMapType(G_PHYSICAL_MAP);
	} else if (mType == "physical") {
		map.setMapType(G_PHYSICAL_MAP);
	} else {
		alert("unknown map type : "+mType);
	}
}

function createIcon(icondef) {
	var myicon = new GIcon();
	myicon.image = icondef.getAttribute("image");
	myicon.shadow = icondef.getAttribute("shadow");
	myicon.iconSize = new GSize(icondef.getAttribute("iconWidth"),icondef.getAttribute("iconHeight"));
	myicon.shadowSize = new GSize(icondef.getAttribute("shadowWidth"),icondef.getAttribute("shadowHeight"));
	myicon.iconAnchor = new GPoint(icondef.getAttribute("anchorX"),icondef.getAttribute("anchorY"));
	myicon.infoWindowAnchor = new GPoint(icondef.getAttribute("infowindowAnchorX"),icondef.getAttribute("infowindowAnchorY"));
	return myicon;
}

// A function to create a tabbed marker and set up the event window
// htmlarray is an array with elements consisting of an array("title"=>..., "content"=>....)
function createTabbedMarker(point,myicon,name,htmlarray) {
	var opts = {title:name,icon:myicon};
	if (!myicon) { opts = {title:name}; }
	var marker = new GMarker(point, opts);
	var infoTabs = new Array();
        for(n=0; n < htmlarray.length; n++) {
		infoTabs[n] = new GInfoWindowTab(htmlarray[n]["title"], htmlarray[n]["content"]);
	}
	GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowTabsHtml(infoTabs);
			});
	GEvent.addListener(marker, "infowindowclose", function() {
			gotoCoords(point.y, point.x);
			});
	return marker;
}

// A function to create the marker and set up the event window
function createMarker(point,myicon,name,html) {
	var opts = {title:name,icon:myicon};
	if (!myicon) { opts = {title:name}; }
	var marker = new GMarker(point, opts);
	GEvent.addListener(marker, "click", function() {
			marker.openInfoWindowHtml(html);
			});
	GEvent.addListener(marker, "infowindowclose", function() {
			gotoCoords(point.y, point.x);
			});
	return marker;
}

function processXml() {
	if (request.readyState != 4) { return; }

	var xmlDoc = request.responseXML;
	// var xmlDoc = request.responseText;
	// find general icon definition
	var mainicon = null;
	var icondef = xmlDoc.documentElement.getElementsByTagName("icon");
	if (icondef.length) {
		mainicon = createIcon(icondef[0]);
	}
	var focusElm = xmlDoc.documentElement.getElementsByTagName("startfocus");
	if (focusElm.length) {
		setFocus(focusElm[0]);
	}

	// obtain the array of markers and loop through it
	var customhtml = xmlDoc.documentElement.getElementsByTagName("customhtml");
        if (customhtml.length) {
	    var customwindows = customhtml[0].getElementsByTagName("window");
	    for (var j = 0; j < customwindows.length; j++) {
		var content = customwindows[j].textContent;
                if (content) { // FIXME Gives undefined in IE
                    var lat = customwindows[j].getAttribute("latitude");
                    var lng = customwindows[j].getAttribute("longitude");
                    customWindowList[ customWindowList.length + 1 ] = customInfoWindow( content, lng, lat);
                }
	    }
	}

	// obtain the array of markers and loop through it
	var markers = xmlDoc.documentElement.getElementsByTagName("marker");
	// hide the info window, otherwise it still stays open where the removed marker used to be
	map.getInfoWindow().hide();
        // Clear old data
	if (clearOldData) { map.clearOverlays(); }
	// empty the array
	gmarkers = [];
	// reset the sidebar
	sidebar_html="";
	for (var j = 0; j < markers.length; j++) {
		var icon = mainicon;
		// obtain the attribues of each marker
		var icondef = markers[j].getElementsByTagName("icon");
		if (icondef.length) {
			icon = createIcon(icondef[0]);
		}
		// Weird ass stuff: long and latt are switched ?!@
		var lng = parseFloat(markers[j].getAttribute("latitude"));
		var lat = parseFloat(markers[j].getAttribute("longitude"));
		var point = new GLatLng(lat,lng);
		// var statename = markers[j].firstChild.nodeValue;
		var statename = markers[j].getElementsByTagName("title")[0].firstChild.nodeValue;
		var popup = markers[j].getElementsByTagName("popup")[0].firstChild.nodeValue;
		var tabs = markers[j].getElementsByTagName("tab");
		var tabbedpopup = new Array();
		if (tabs.length) {
			for(var t = 0; t < tabs.length; t++) {
				tabbedpopup[t] = new Array();
				tabbedpopup[t]["title"] = tabs[t].getElementsByTagName("title")[0].firstChild.nodeValue;
				tabbedpopup[t]["content"] = tabs[t].getElementsByTagName("content")[0].firstChild.nodeValue;
			}
		}
		var myid = parseFloat(markers[j].getAttribute("myid"));
		var label =statename;

		// create the marker
		var marker;
		if (tabs.length) {
			marker = createTabbedMarker(point,icon,label,tabbedpopup);
		} else {
			marker = createMarker(point,icon,label,popup);
		}
		map.addOverlay(marker);
	}
}

// A function to read the data of states
function GreaddataStateXML(url) {
	request = GXmlHttp.create();
	request.open("GET", url, true);
	request.onreadystatechange = processXml;
	request.send(null);
}

// A function to read the data of states
function readGmapXML(url) {
   return GreaddataStateXML(url);
}

function clearMarkers() { map.clearOverlays(); }

function gotoCoords(lng,lat) { window.setTimeout(function() { map.panTo(new GLatLng(lng, lat)); }, 1000); }

function helloWorld() { map.openInfoWindow(map.getCenter(), document.createTextNode("Hello, world")); }

// -----------------------------------------------------------------------------------------------------------
// Code below taken from:
// http://gmaps.tommangan.us/tlabel.html
// Version 2.05
function TLabel(){
}

TLabel.prototype.initialize=function(a){
	this.parentMap=a;
	var b=document.createElement('span');
	b.setAttribute('id',this.id);
	b.innerHTML=this.content;
	document.body.appendChild(b);
	b.style.position='absolute';
	b.style.zIndex=1;
	if(this.percentOpacity){this.setOpacity(this.percentOpacity);}
	this.w = document.getElementById(this.id).offsetWidth;
	this.h = document.getElementById(this.id).offsetHeight;
	this.mapTray=a.getPane(G_MAP_MAP_PANE);
	this.mapTray.appendChild(b);
	if(!this.markerOffset){this.markerOffset=new GSize(0,0);}
	this.setPosition();
	GEvent.bind(a,"zoomend",this,function(){this.setPosition()});
	GEvent.bind(a,"moveend",this,function(){this.setPosition()});
}

TLabel.prototype.setPosition=function(a){
	if(a){this.anchorLatLng=a;}
	var b=this.parentMap.fromLatLngToDivPixel(this.anchorLatLng);
	var x=parseInt(b.x);
	var y=parseInt(b.y);
	with(Math){switch(this.anchorPoint){
		case 'topLeft':break;
		case 'topCenter':x-=floor(this.w/2);break;
		case 'topRight':x-=this.w;break;
		case 'midRight':x-=this.w;y-=floor(this.h/2);break;
		case 'bottomRight':x-=this.w;y-=this.h;break;
		case 'bottomCenter':x-=floor(this.w/2);y-=this.h;break;
		case 'bottomLeft':y-=this.h;break;
		case 'midLeft':y-=floor(this.h/2);break;
		case 'center':x-=floor(this.w/2);y-=floor(this.h/2);break;
		default:break;
	}}
	var d=document.getElementById(this.id);
	d.style.left=x-this.markerOffset.width+'px';
	d.style.top=y-this.markerOffset.height+'px';
}

TLabel.prototype.setOpacity=function(b){
	if(b<0){b=0;} if(b>100){b=100;}
	var c=b/100;
	var d=document.getElementById(this.id);
	if(typeof(d.style.filter)=='string'){d.style.filter='alpha(opacity:'+b+')';}
			if(typeof(d.style.KHTMLOpacity)=='string'){d.style.KHTMLOpacity=c;}
			if(typeof(d.style.MozOpacity)=='string'){d.style.MozOpacity=c;}
			if(typeof(d.style.opacity)=='string'){d.style.opacity=c;}
			}
			GMap2.prototype.addTLabel=function(a){
			a.initialize(this);
			}
			GMap2.prototype.removeTLabel=function(a){
			var b=document.getElementById(a.id);
			this.getPane(G_MAP_MAP_PANE).removeChild(b);
			delete(b);
			}

// -----------------------------------------------------------------------------------------------------------
// Code below taken from:
// http://econym.googlepages.com/elabel.htm

// Version 0.2      the .copy() parameters were wrong
// version 1.0      added .show() .hide() .setContents() .setPoint() .setOpacity() .overlap
// version 1.1      Works with GMarkerManager in v2.67, v2.68, v2.69, v2.70 and v2.71
// version 1.2      Works with GMarkerManager in v2.72, v2.73, v2.74 and v2.75
// version 1.3      add .isHidden()
// version 1.4      permit .hide and .show to be used before addOverlay()
// version 1.5      fix positioning bug while label is hidden
// version 1.6      added .supportsHide()
// version 1.7      fix .supportsHide()


      function ELabel(point, html, classname, pixelOffset, percentOpacity, overlap) {
        // Mandatory parameters
        this.point = point;
        this.html = html;
        
        // Optional parameters
        this.classname = classname||"";
        this.pixelOffset = pixelOffset||new GSize(0,0);
        if (percentOpacity) {
          if(percentOpacity<0){percentOpacity=0;}
          if(percentOpacity>100){percentOpacity=100;}
        }        
        this.percentOpacity = percentOpacity;
        this.overlap=overlap||false;
        this.hidden = false;
      } 
      
      ELabel.prototype = new GOverlay();

      ELabel.prototype.initialize = function(map) {
        var div = document.createElement("div");
        div.style.position = "absolute";
        div.innerHTML = '<div class="' + this.classname + '">' + this.html + '</div>' ;
        map.getPane(G_MAP_FLOAT_SHADOW_PANE).appendChild(div);
        this.map_ = map;
        this.div_ = div;
        if (this.percentOpacity) {        
          if(typeof(div.style.filter)=='string'){div.style.filter='alpha(opacity:'+this.percentOpacity+')';}
          if(typeof(div.style.KHTMLOpacity)=='string'){div.style.KHTMLOpacity=this.percentOpacity/100;}
          if(typeof(div.style.MozOpacity)=='string'){div.style.MozOpacity=this.percentOpacity/100;}
          if(typeof(div.style.opacity)=='string'){div.style.opacity=this.percentOpacity/100;}
        }
        if (this.overlap) {
          var z = GOverlay.getZIndex(this.point.lat());
          this.div_.style.zIndex = z;
        }
        if (this.hidden) {
          this.hide();
        }
      }

      ELabel.prototype.remove = function() {
        this.div_.parentNode.removeChild(this.div_);
      }

      ELabel.prototype.copy = function() {
        return new ELabel(this.point, this.html, this.classname, this.pixelOffset, this.percentOpacity, this.overlap);
      }

      ELabel.prototype.redraw = function(force) {
        var p = this.map_.fromLatLngToDivPixel(this.point);
        var h = parseInt(this.div_.clientHeight);
        this.div_.style.left = (p.x + this.pixelOffset.width) + "px";
        this.div_.style.top = (p.y +this.pixelOffset.height - h) + "px";
      }

      ELabel.prototype.show = function() {
        if (this.div_) {
          this.div_.style.display="";
          this.redraw();
        }
        this.hidden = false;
      }
      
      ELabel.prototype.hide = function() {
        if (this.div_) {
          this.div_.style.display="none";
        }
        this.hidden = true;
      }
      
      ELabel.prototype.isHidden = function() {
        return this.hidden;
      }
      
      ELabel.prototype.supportsHide = function() {
        return true;
      }

      ELabel.prototype.setContents = function(html) {
        this.html = html;
        this.div_.innerHTML = '<div class="' + this.classname + '">' + this.html + '</div>' ;
        this.redraw(true);
      }
      
      ELabel.prototype.setPoint = function(point) {
        this.point = point;
        if (this.overlap) {
          var z = GOverlay.getZIndex(this.point.lat());
          this.div_.style.zIndex = z;
        }
        this.redraw(true);
      }
      
      ELabel.prototype.setOpacity = function(percentOpacity) {
        if (percentOpacity) {
          if(percentOpacity<0){percentOpacity=0;}
          if(percentOpacity>100){percentOpacity=100;}
        }        
        this.percentOpacity = percentOpacity;
        if (this.percentOpacity) {        
          if(typeof(this.div_.style.filter)=='string'){this.div_.style.filter='alpha(opacity:'+this.percentOpacity+')';}
          if(typeof(this.div_.style.KHTMLOpacity)=='string'){this.div_.style.KHTMLOpacity=this.percentOpacity/100;}
          if(typeof(this.div_.style.MozOpacity)=='string'){this.div_.style.MozOpacity=this.percentOpacity/100;}
          if(typeof(this.div_.style.opacity)=='string'){this.div_.style.opacity=this.percentOpacity/100;}
        }
      }

      ELabel.prototype.getPoint = function() {
        return this.point;
      }
      ELabel.prototype.U = function() {
        return this.point;
      }
      ELabel.prototype.V = function() {
        return this.point;
      }
      ELabel.prototype.W = function() {
        return this.point;
      }
      ELabel.prototype.X = function() {
        return this.point;
      }
      ELabel.prototype.Y = function() {
        return this.point;
      }
      ELabel.prototype.Z = function() {
        return this.point;
      }

    //]]>

