          /*
           * Constants for given map
           * TODO: read it from tilemapresource.xml
           */
var names;
var markerGroups = new Object;
var locationPhotos = new Object;
var buildingHTML = new Object;
var buildingIcons = new Array;
var switchedOffIcons = new Array;
var XMLloaded = false; // Something to see when the async call has been finished processing
        
var mapBounds = new GLatLngBounds(new GLatLng(-33.8931260952, 151.176229566), new GLatLng(-33.8838145902, 151.195383221));
var mapMinZoom = 1;
var mapMaxZoom = 21;

var opacity = 0.75;
var map;
var hybridOverlay;
// Quad loading and unloading variables
var quadOverlay;
var showQuad = false;

(document.all ? document : window).onload = load;

function load() {
  if (GBrowserIsCompatible()) {
              // Bug in the Google Maps: Copyright for Overlay is not correctly displayed
    var gcr = GMapType.prototype.getCopyrights;
    GMapType.prototype.getCopyrights = function(bounds,zoom) {
      return ["&copy; Arts Digital"].concat(gcr.call(this,bounds,zoom));
    }

    map = new GMap2( document.getElementById("map"), { backgroundColor: '#fff' } );
        
            // ====== Restricting the range of Zoom Levels =====
            // Get the list of map types      
    var mt = map.getMapTypes();
            // Overwrite the getMinimumResolution() and getMaximumResolution() methods
    for (var i=0; i<mt.length; i++) {
      mt[i].getMinimumResolution = function() {return mapMinZoom;}
      mt[i].getMaximumResolution = function() {return mapMaxZoom;}
    }
            
    map.setCenter(new GLatLng(-33.8862, 151.1881), 18);
              
    map.setMapType(G_HYBRID_MAP);  
// Tiled overlay
    hybridOverlay = new GTileLayerOverlay( G_HYBRID_MAP.getTileLayers()[1] );
    GEvent.addListener(map, "maptypechanged", function() {
      if (map.getCurrentMapType() == G_HYBRID_MAP) {
        map.addOverlay(hybridOverlay);
      } else {
        map.removeOverlay(hybridOverlay);
      }
    });
// QuadOverlay
    quadOverlay = new GGroundOverlay(
      "/artsdigital/images/cartography/tiles/quad_overlay.png", 
      new GLatLngBounds(
        new GLatLng(-33.88657786647702, 151.1877503246069),
        new GLatLng(-33.885285305619, 151.1893817782402)
      )
    );
    quadOverlay.hide();
    map.addOverlay(quadOverlay);

    var tilelayer = new GTileLayer(GCopyrightCollection(''), mapMinZoom, mapMaxZoom);
	var mercator = new GMercatorProjection(mapMaxZoom+1);
	tilelayer.getTileUrl = function(tile,zoom) {
		if ((zoom < mapMinZoom) || (zoom > mapMaxZoom)) {
			return "http://www.maptiler.org/img/none.png";
		} 
		var ymax = 1 << zoom;
		var y = ymax - tile.y -1;
		var tileBounds = new GLatLngBounds(
			mercator.fromPixelToLatLng( new GPoint( (tile.x)*256, (tile.y+1)*256 ) , zoom ),
			mercator.fromPixelToLatLng( new GPoint( (tile.x+1)*256, (tile.y)*256 ) , zoom )
		);
		if (mapBounds.intersects(tileBounds)) {
			return "/artsdigital/images/cartography/tiles/"+zoom+"/"+tile.x+"/"+y+".png";
		} else {
			return "/artsdigital/images/cartography/controls/none.png";
		}
	}
	
	// IE 7-: support for PNG alpha channel
    tilelayer.isPng = function() { return true;};
    tilelayer.getOpacity = function() { return opacity; }
          
    overlay = new GTileLayerOverlay( tilelayer );
    map.addOverlay(overlay);

    map.addControl(new GLargeMapControl());
   // map.addControl(new GMapTypeControl());
    
    map.enableContinuousZoom();
    map.enableScrollWheelZoom();

    map.setMapType(G_HYBRID_MAP);

// clustering the map at certain zoom levels
    GEvent.addListener(map, "zoomend", function() {
      if (map.getZoom()<15) {
        for (x in markerGroups) { // Switching off all the icons
          if (_("_"+x)) {
            if (_("_"+x).src.match(/_h\.png/)) switchedOffIcons.push(x); 
          }
          toggleGroup(x, _("_"+x), false);
        }
        markerGroups.usyd[0].show();
      } else {
        for (x=0; x<switchedOffIcons.length; x++) toggleGroup(switchedOffIcons[x], _("_"+switchedOffIcons[x]), true);
        switchedOffIcons = Array();
        markerGroups.usyd[0].hide();
      }
    });
            
    GDownloadUrl("/artsdigital/map/markerdata_test.xml", function(data) {
      var xml = GXml.parse(data);
      var markers = xml.documentElement.getElementsByTagName("marker");
      for (var i = 0; i < markers.length; i++) {
        var name = markers[i].getAttribute("name");
        var comment = markers[i].getAttribute("comment");
        var type = markers[i].getAttribute("type");
        var point = new GLatLng(parseFloat(markers[i].getAttribute("lat")), parseFloat(markers[i].getAttribute("lng")));
        var size = markers[i].getAttribute("size");
        var buildingID = markers[i].getAttribute("buildingid");

        if (markers[i].childNodes.length) { // picking up icon and accessibility info 
          var link = false;
          var icons = Array();
          for (x=0; x<markers[i].childNodes.length; x++) {
            if (markers[i].childNodes[x]) {
              if (markers[i].childNodes[x].tagName=="link") link = true;
              else if (markers[i].childNodes[x].tagName=="icon") icons.push(markers[i].childNodes[x].getAttribute("value"));
            }
          }
          var iconData = new Object;
          iconData["link"] = link ? "http://www.facilities.usyd.edu.au/oam/blaccess-r01.cfm?fld0="+buildingID : null;
          iconData["icons"] = icons;
          iconData["id"] = buildingID;
          buildingIcons.push(iconData);
        }
        if (markers[i].getAttribute("photo")) locationPhotos[(buildingID ? buildingID : name)] = markers[i].getAttribute("photo");
        var marker = createMarker(point, name, comment, type, size, buildingID, iconData);
        map.addOverlay(marker);
      }
      XMLloaded = true;
    });
  }
  setTimeout("MAPdelay()", 500);
}  

function MAPdelay() { // Functions to run on page load but makes sure everything's loaded first
  if (XMLloaded) {
// Automatically switching off certain icons
    toggleGroup("buses", _("_buses"), false);
    toggleGroup("bikes", _("_bikes"), false);
    toggleGroup("phone", _("_phone"), false);
    markerGroups.usyd[0].hide();
// Testing for GET variables
    if (getURLVar("locationID")) selectBuilding(getURLVar('locationID'));
  } else setTimeout("MAPdelay()", 500);
  return;
}
                
function createMarker(point, name, comment, type, size, buildingID, iconData) {
  var marker;
  var iconSize = new Object;
  switch (size) {
    case "xxlarge" : iconSize.x = 156; iconSize.y = 110; break;
    case "xlarge" : iconSize.x = 100; iconSize.y = 88; break;
    case "large" : iconSize.x = 69; iconSize.y = 60; break;
    case "small" : iconSize.x = 32; iconSize.y = 21; break;
    case "xsmall" : iconSize.x = 25; iconSize.y = 25; break;
    default : iconSize.x = 33; iconSize.y = 35; break;
  }
  var newIcon = new GIcon();
  newIcon.image = '/artsdigital/images/cartography/icons/'+(buildingID ? buildingID : type)+'_icon.png';
  newIcon.iconSize = new GSize(iconSize.x, iconSize.y);
  newIcon.iconAnchor = new GPoint(Math.ceil(iconSize.x/2), Math.ceil(iconSize.y/2));
  if (size && size.match(/x(large|small)$/)) newIcon.infoWindowAnchor = new GPoint(Math.ceil(iconSize.x/2), Math.ceil(iconSize.y/2));
  else newIcon.infoWindowAnchor = new GPoint(30, 2);

  markerProps = new Object;
  markerProps.clickable = type.match(/^(building|webcam)$/) ? true : false;
  markerProps.title = type.match(/^(building|office|webcam|faculty)$/) ? name : comment;
  markerProps.icon = newIcon;
  marker = new GMarker(point, markerProps);

  if (!markerGroups[type]) {
    if (buildingID) markerGroups[type] = new Object; 
    else markerGroups[type] = new Array;
  }
  if (!buildingID) markerGroups[type].push(marker);
  else markerGroups[type][buildingID] = marker;

  if (type.match(/^(building|office|webcam|faculty)$/)) {
    var htm = buildingWindowHTML(name, buildingID, comment);
    markerGroups[type][buildingID].bindInfoWindowHtml(htm);
    buildingHTML[buildingID] = htm;
    if (!type.match(/^(office|faculty)$/)) {
      GEvent.addListener(marker, 'mouseout', function() { setTimeout(function() { marker.closeInfoWindow(); }, 10000); } );
    }
  }
  return marker;
}
function toggleGroup(type, imgObj, forceOn) {
  if (!markerGroups[type]) return;
  if (imgObj) { 
    if (!imgObj.src) { alert("Not a real image!"); return; }
    var on = forceOn===false ? false : true;

    if (imgObj.src.match(/_(off|on).png$/) || forceOn===false) {
      on = false;
      imgObj.src = imgObj.src.replace(/_(off|on).png$/, "_$1_h.png"); 
      imgObj.onmouseover = function() { MM_swapImage(imgObj.id, '', imgObj.src.replace(/_off_h.png$/, "_on_h.png"), 1); }
      imgObj.onmouseout = function() { imgObj.src = imgObj.src.replace(/_on_h.png$/, "_off_h.png"); }
    } else if (imgObj.src.match(/_h.png$/)) {
      imgObj.src = imgObj.src.replace(/_h.png$/, ".png");
      imgObj.onmouseover = function() { MM_swapImage(imgObj.id, '', imgObj.src.replace(/_off.png$/, "_on.png"), 1); }
      imgObj.onmouseout = function() { imgObj.src = imgObj.src.replace(/_on.png$/, "_off.png"); }
    }
  }
  if (typeof(markerGroups[type])=="object") {
    for (i in markerGroups[type]) { 
      if (markerGroups[type][i]) {
        var marker = markerGroups[type][i];
        if (on) marker.show();
        else marker.hide();
      }
    }
  } else if (typeof(markerGroups[type])=="array") {
    for (i=0; i<markerGroups[type].count; i++) { 
      if (markerGroups[type][i]) {
        var marker = markerGroups[type][i];
        if (on) marker.show();
        else marker.hide();
      }
    }
  }
}
   
function MM_showHideLayers() { //v9.0
  var i,p,v,obj,args=MM_showHideLayers.arguments;
  for (i=0; i<(args.length-2); i+=3) 
  with (document) if (getElementById && ((obj=getElementById(args[i]))!=null)) { v=args[i+2];
  if (obj.style) { obj=obj.style; v=(v=='show')?'visible':(v=='hide')?'hidden':v; }
  obj.visibility=v; }
}
function selectBuilding(code, noWindow, noZoom) {
  var type = markerGroups.faculty[code] ? "faculty" : "office";
  if (code.match(/^CAM\d+$/)) type = "webcam";
  else if (code.match(/^(\w{1,2}\d{1,2}\w{0,1}-{0,1}){1,2}$/)) type = "building";
  if (markerGroups[type]) { if (markerGroups[type][code]) {
    var marker = markerGroups[type][code];
    if (!noZoom) map.setZoom(19);
    map.panTo(marker.getLatLng());
    if (!noZoom && code!="OS_ONETREE") map.setZoom(18);
    else if (code=="OS_ONETREE") map.setZoom(13);
    if (!noWindow) marker.openInfoWindowHtml(buildingHTML[code]);
  } }
  return;
}
function buildingWindowHTML(name, code, comment) {
  var photo = locationPhotos[code];
  var className = "info";
  var xtraInfo = "";
  if (comment) xtraInfo = "<br/>"+comment;
  else if (code.match(/^(\w{1,2}\d{1,2}\w{0,1}-{0,1}){1,2}$/)) xtraInfo = "<br/>Building Code: "+code;

  if (photo) {
    if (photo.match(/http:\/\/129.78.249./)) className+= "WebCam";
    else className+= "buildingPhoto";
  } 
  var HTML =  "<div class='"+className+"'><p><b>"+name+"</b>"+xtraInfo+"</p>";
  HTML+= photo ? "<p><img src='"+photo+"' border='0' alt='"+name+", University of Sydney'/></p>" : "";
  var iconData;
  for (x in buildingIcons) {
    if (buildingIcons[x]) { if (buildingIcons[x].id) { if (buildingIcons[x].id==code) {
      iconData = buildingIcons[x];
    } } }
  }
  if (iconData) {
    HTML+= "<p>";
    if (iconData.icons) {
      for (x in iconData.icons) HTML+= "<img src='/artsdigital/images/cartography/icons/"+iconData.icons[x]+"_icon.png'/> ";
      HTML+= iconData.link ? "<br/>" : "";
    }
    HTML+= iconData.link ? "<a href=\"javascript:window.location='"+iconData.link+"'\">see Building details</i></a><br> " : "";
    HTML+= "</p>";
  }
  HTML+= "</div><div style='clear: both'></div>";

  return HTML;
}
function showQuadDetail() {
  if (!showQuad) {
    quadOverlay.show();
    if (_("_office").src.match(/_h.png$/)) toggleGroup("office", _("_office"), false);
    if (_("_faculty").src.match(/_h.png$/)) toggleGroup("faculty", _("_faculty"), false);
    toggleGroup("info");
    map.setZoom(19);
    selectBuilding("A14", true, true);
    showQuad = true;
    _("_quad").src = _("_quad").src.replace(/_s.png$/, "_h.png");
  } else {
    quadOverlay.hide();
    map.setZoom(18);
    showQuad = false;
    _("_quad").src = _("_quad").src.replace(/_h.png$/, "_s.png");
  }
  return;
}

function normalMap() {    
   map.setMapType(G_NORMAL_MAP);
}

function hybridMap() {    
   map.setMapType(G_HYBRID_MAP);
}

function satelliteMap() {    
   map.setMapType(G_SATELLITE_MAP);
}

/* Functions to deal with searching for a Building 
*/
var autosearch; // A variable to track when the delay for returning suggestions is.  Otherwise tends to interfere with users typing in values
var ul; // Object to kill when something's been clicked
function searchBuilding(str, force) {
  if (str) {
    if (str.match(/^\s*$/)) return;
    if (!force) {
      if (autosearch) clearTimeout(autosearch);
      autosearch = setTimeout(function() { searchBuilding(str, true); }, 300);
    } else {
      var suggest = new Object;
      var suggestCount = 0;
      bits = str.replace(/(^\s*|\s*$)/, "").split(/\s+/);
      for (y=0; y<bits.length; y++) {
        for (x in markerGroups['building']) {
          if (markerGroups['building'][x].getTitle().match(RegExp(bits[y], "i"))) {
            if (!suggest[x]) {
              suggest[x] = markerGroups['building'][x].getTitle();
              suggestCount++;
            }
          }
        }
      }

      if (ul) { _("searchBuilding").parentNode.removeChild(ul); ul = null; }//clearing out the old one
      if (suggestCount!=1) {
        ul = document.createElement("ul");
        ul.className = "suggestion";
        ul.style.position = "absolute"; ul.style.zIndex = 100;
        _("searchBuilding").parentNode.appendChild(ul);
        var topLi = document.createElement("li");
        topLi.className = "topLi";
        ul.appendChild(topLi);
      } 

      var count = 0;
      if (!suggestCount) {
        var li = document.createElement("li");
        li.innerHTML = "Could not find a building with this name!";
        li.className = "noReturn";
        ul.appendChild(li);
        setTimeout(function() { if (ul) { _("searchBuilding").parentNode.removeChild(ul); ul = null; } }, 3500);
      } else {
        for (x in suggest) {
          if (suggestCount==1) {
            _("searchBuilding").value = suggest[x];
            selectBuilding(x);
          } else {
            var li = document.createElement("li");
            if (count++<10) ul.appendChild(li);
            li.innerHTML = suggest[x];
            li.setAttribute("name", suggest[x]); li.setAttribute("code", x);
            li.onclick = function() {
              _("searchBuilding").value = this.getAttribute("name");
              if (ul) { _("searchBuilding").parentNode.removeChild(ul); ul = null; }
              selectBuilding(this.getAttribute("code"));
            }
          }
        }
      }
      if (suggestCount!=1) {
        var bottomLi = document.createElement("li");
        bottomLi.className = "bottomLi";
        ul.appendChild(bottomLi);
      }
      setTimeout(function() { if (ul) { _("searchBuilding").parentNode.removeChild(ul); ul = null; } }, 10000);
    }
  }
  return;
}
