var Maps = {
    map:null,
    point:new GLatLng(39.14990874349427, -84.53659504652023),
    zoomlevel:17,
    campuses:{},
    shiftclick:false
};

Maps.init = function() {
  Maps.map = new GMap2(document.getElementById('themap'));
  Maps.map.addControl(new GLargeMapControl());
  Maps.map.addControl(new GMapTypeControl());
  Maps.map.addControl(new GScaleControl());
  Maps.map.addControl(new GOverviewMapControl(new GSize(100,100)));
  Maps.map.setCenter(Maps.point, Maps.zoomlevel);

  var c = Maps.directLink;

  Maps.campuses = {
    'central'        : new MapCampus('central', c)
  }

  document.onkeydown = function(e) {
      if (!e) var e = window.event;
      if (e.keyCode == 16) Maps.shiftclick = true;
  }

  document.onkeyup = function(e) {
      if (!e) var e = window.event;
      if (e.keyCode == 16) Maps.shiftclick = false;
  }
}

Maps.reset = function() {
  Maps.blurAllCampuses();
  Maps.map.setCenter(Maps.point, Maps.zoomlevel);
  Maps.removeAllLandmarks();

}

Maps.blurAllCampuses = function() {
  if (Maps.campuses) {
    for (c in Maps.campuses) {
      var campus = Maps.campuses[c];
      if (campus.isFocused) {
        campus.blur();
      }
    }
  }
}

Maps.removeAllLandmarks = function() {
  if (Maps.campuses) {
    for (c in Maps.campuses) {
      var campus = Maps.campuses[c];
      for (set in campus.markersets) {
        var ms = campus.markersets[set];
        for (lm in ms.landmarks) {
          ms.landmarks[lm].remove();
        }
      }
    }
  }
}

var MapCampus = function(id, callback) {
  var self = this;

  this.name = null;
  this.shortname = null;
  this.fullname = null;
  this.point = null;
  this.zoomlevel = null;
  this.url = null;
  this.imageurl = null;
  this.marker = null;
  this.overlays = null;
  this.markersets = null;
  this.navDiv = null;
  this.infoDiv = null;
  this.isFocused = false;
  this.clickhandler = null;

  GDownloadUrl('./virtualmap' + id + '.xml', function(data, responseCode) {
    var xml = GXml.parse(data);
    var d = xml.documentElement; 
    if (d) {
      self.initialize(d);
    }
    if (callback) callback(self);
  });
}

MapCampus.prototype.initialize = function(x) {
  var self = this;

  this.name = x.getAttribute('name');
  this.shortname = x.getAttribute('shortname');
  this.fullname = x.getAttribute('fullname');
  this.point = new GLatLng(parseFloat(x.getAttribute('lat')), parseFloat(x.getAttribute('lon')));
  this.zoomlevel = parseInt(x.getAttribute('zoomlevel'));
  this.url = x.getAttribute('url');
  this.imageurl = x.getAttribute('imageurl');

  this.marker = new GMarker(this.point, {title:this.name});
  GEvent.addListener(this.marker, 'click', function() {self.getinfo();});
  GEvent.addListener(this.marker, 'dblclick', function() {self.focus();});
  Maps.map.addOverlay(this.marker);

  this.parseOverlays(x.getElementsByTagName('overlay'));
  this.parseMarkerSets(x.getElementsByTagName('markerset'));
  this.createNavigationDiv();

  var linkbar = document.getElementById('maps-linkbar');
  linkbar.appendChild(this.navDiv);
}

MapCampus.prototype.parseOverlays = function(a) {
  this.overlays = new Object();
  if (a) {
    for (var i = 0; i < a.length; i++) {
      var overlay = new MapOverlay(a[i], this);
      this.overlays[overlay.type] = overlay;
    }
  }
}

MapCampus.prototype.parseMarkerSets = function(a) {
  this.markersets = new Object();
  if (a) {
	for (var i = 0; i < a.length; i++) {
      var set = new MapMarkerSet(this, a[i]);
      this.markersets[set.type] = set;
    }
  }
}

MapCampus.prototype.createNavigationDiv = function() {
  var self = this;

  this.navDiv = document.getElementById('maps-campus-' + this.shortname);

  var linkbar = document.getElementById('campus-linkbar-' + this.shortname);
  for (x in this.markersets) {
    linkbar.appendChild(this.markersets[x].nav);
  }

  if (this.overlays['campus']) {
    var li = document.createElement('li');
    var cb = document.createElement('input');
    cb.id = 'maps-overlay-checkbox-' + this.shortname;
    cb.className = 'maps-overlay-checkbox';
    cb.setAttribute('type', 'checkbox');
    cb.defaultChecked = true;
    cb.onclick = function(e) {
        if (this.checked) {
          if (self.overlays['campus']) self.overlays['campus'].show();
        } else {
          if (self.overlays['campus']) self.overlays['campus'].hide();
        }
    }
    li.appendChild(cb);
    li.appendChild(document.createTextNode(' Show Campus Overlay'));
    linkbar.appendChild(li);
  }
  
  if (this.overlays['campus']) {
    var li = document.createElement('li');
	var a = document.createElement('a');
    a.href= "javascript:void();";
	a.appendChild(document.createTextNode(' Hide All Markers'));
	a.onclick = function(e) {
		Maps.removeAllLandmarks();
	}
    li.appendChild(a);
	linkbar.appendChild(li);
  }
}

MapCampus.prototype.selectLandmark = function(type, code) {
  var set = this.markersets[type];
  if (set) set.select(code);
}

MapCampus.prototype.getinfo = function() {
  var self = this;

  if (!this.infoDiv) {
    this.infoDiv = document.createElement('div');
    this.infoDiv.className = 'maps-campus-info';

    var t = document.createElement('a');
    t.className = 'maps-campus-info-name';
    t.href = 'javascript:void();';
    t.onclick = function(e) {self.focus();}
    t.appendChild(document.createTextNode(this.fullname));
    this.infoDiv.appendChild(t);

    t = document.createElement('a');
    t.className = 'maps-campus-info-permalink';
    t.href = 'virtualmap?campus=' + escape(this.shortname);
    t.appendChild(document.createTextNode('Map Permalink (Copy/Paste Link)'));
    this.infoDiv.appendChild(t);

    if (this.imageurl) {
      t = document.createElement('img');
      t.className = 'maps-campus-info-image';
      t.src = "http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/"+this.imageurl;
      this.infoDiv.appendChild(t);
    }

    t = document.createElement('a');
    t.className = 'maps-campus-info-url';
    t.href = this.url;
    t.appendChild(document.createTextNode('Web site'));
    this.infoDiv.appendChild(t);
  }

  this.marker.openInfoWindow(this.infoDiv);
}

MapCampus.prototype.focus = function(callback) {
  var self = this;

  Maps.map.closeInfoWindow();
  Maps.blurAllCampuses();
  this.isFocused = true;
  Maps.map.setMapType(G_NORMAL_MAP);
  Maps.map.setCenter(this.point, this.zoomlevel);
  Maps.map.removeOverlay(this.marker);

  if (this.overlays['campus']) {
    this.overlays['campus'].show();
    //document.getElementById('maps-legend').style.display = 'block';
  }

  this.navDiv.style.display = 'block';

  if (!this.clickhandler) {
    this.clickhandler = GEvent.addListener(Maps.map, 'click', function(overlay, point) {
        if (point) { //background clicked
          if (Maps.shiftclick) {
            Maps.shiftclick = false;
            var lm = new MapUserLandmark(point, self.shortname);
            lm.focus();
          } else {
            self.findClosestLandmark(point);
          }
        }
    });
  }

  if (callback) callback(this);
}

MapCampus.prototype.blur = function() {
  if (this.clickhandler) {
    GEvent.removeListener(this.clickhandler);
    this.clickhandler = null;
  }

  this.navDiv.style.display = 'none';

  //document.getElementById('maps-legend').style.display = 'none';
  if (this.overlays['campus']) { this.overlays['campus'].hide(); }

  Maps.map.addOverlay(this.marker);

  this.isFocused = false;
}

MapCampus.prototype.findClosestLandmark = function(point) {
  var maxXrange = 0.0015; //degrees lon.
  var maxYrange = 0.001; //degrees lat.
  var minimumdist = 1000; //1 kilometer
  var bestLandmark = null;

  for (i in this.markersets) {
    var set = this.markersets[i];
    for (j in set.landmarks) {
      var lm = set.landmarks[j];
      var candidate = lm.point;
      if ((Math.abs(point.x - candidate.x) < maxXrange) &&
          (Math.abs(point.y - candidate.y) < maxYrange)) {
        var candidatedist = candidate.distanceFrom(point);
        if (candidatedist < minimumdist) {
          minimumdist = candidatedist;
          bestLandmark = lm;
        }
      }
    }
  }
  if (bestLandmark) bestLandmark.focus();
}

var MapMarkerSet = function(campus, xmlMarkerSet) {
  //alphabetize markerset
  var self = this;
  this.parent = campus;
  this.name = xmlMarkerSet.getAttribute('type');
  this.type = xmlMarkerSet.getAttribute('name');//
  this.src = xmlMarkerSet.getAttribute('src');
  this.popup = new MapsPopup(this.type);
  this.selectbox = createSelectBox();
  this.nav = createNavLI();
  this.landmarks = parseLandmarks(xmlMarkerSet.getElementsByTagName('marker'));

  function createSelectBox() {
    var sb = document.createElement('select');
    sb.setAttribute('size', '1');
    sb.onchange = function(e) {
        var val = this.options[this.options.selectedIndex].value;
        if (val && val != '-Select-') {
          var opts = self.landmarks;
          if (opts && opts[val]) {opts[val].focus();}
        }
    }
    var opt = document.createElement('option');
    opt.appendChild(document.createTextNode('-Select-'));
    sb.appendChild(opt);

    return sb;
  }

  function createNavLI() {
    var li = document.createElement('li');
    li.id = self.parent.shortname + '-' + self.type + '-map';

    var span = document.createElement('span');
    span.className = 'maps-linkbar-markerset-text';
    span.appendChild(document.createTextNode(self.name + ': '));

    li.appendChild(span);
    li.appendChild(self.selectbox);

    var pick = document.createElement('a');
    pick.href = 'javascript:void();';
    pick.onclick = function(e) {if (self.popup) self.popup.focus();}

    span = document.createElement('span');
    span.className = 'maps-popup-link';
    span.appendChild(document.createTextNode('')); //Search by name
    pick.appendChild(span);
    li.appendChild(pick);

    var showall = document.createElement('a');
	showall.style.textDecoration = "none";
    showall.href = 'javascript:void();';
    showall.onclick = function(e) {  
		for (j in self.landmarks) {
		  var lm = self.landmarks[j];
			Maps.map.addOverlay(lm.marker);
		}
	};
	var iconPreview = document.createElement('img');
	iconPreview.src = "http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/markers-nopin/"+self.type+".png";
	iconPreview.className = 'maps-icon-preview';
    var span = document.createElement('span');
    span.className = 'maps-showall-link';
	span.appendChild(iconPreview);
    var t = document.createElement('span');
	t.style.textDecoration = "underline";
	t.appendChild(document.createTextNode('Show'));
	span.appendChild(t);
    showall.appendChild(span);
    li.appendChild(showall);


    var removeall = document.createElement('a');
    removeall.href = 'javascript:void();';
    removeall.onclick = function(e) {  
		for (j in self.landmarks) {
		  var lm = self.landmarks[j];
		  lm.remove();
		}
	};
    removeall.className = 'maps-removeall-link';
    removeall.appendChild(document.createTextNode('Hide'));
    li.appendChild(removeall);

    return li;
  }

  function parseLandmarks(a) {
    var hash = new Object();
    if (a) {
      for (var i = 0; i < a.length; i++) {
        var m = new MapLandmark(a[i], self.type, self.parent);
        hash[m.code] = m;

        var opt = document.createElement('option');
        opt.value = m.code;
        opt.appendChild(document.createTextNode(m.code));
        self.selectbox.appendChild(opt);

        self.popup.addoption(m);
      }
    }
    return hash;
  }

  this.select = function(code) {
    for (var i = 0; i < self.selectbox.length; i++) {
      var opt = self.selectbox.options[i].value;
      if (opt == code) {
        self.selectbox.selectedIndex = i;
        self.selectbox.onchange();
        break;
      }
    }
  }

}

var MapLandmark = function(xmlMarker, type, campus) {
  var self = this;
  this.campus = campus;
  this.name = xmlMarker.getAttribute('name');
  this.code = xmlMarker.getAttribute('name');//xmlMarker.getAttribute('code');
  if(xmlMarker.getAttribute('type')){ //if specific type defined for this node use that otherwaise refer to markertype set
	this.type = xmlMarker.getAttribute('type');
  } else {
    this.type = type;  
  }
  this.imageurl = xmlMarker.getAttribute('imageurl');
  this.point = new GLatLng(parseFloat(xmlMarker.getAttribute('lat')), parseFloat(xmlMarker.getAttribute('lon')));
  this.contact = xmlMarker.getAttribute('contact');
  this.parking = xmlMarker.getAttribute('parking');
  this.des = xmlMarker.getAttribute('des');
  this.loc = xmlMarker.getAttribute('loc');
  this.marker = createMarker();
  this.infoDiv = null;

  function createMarker() {
	self.icon = new GIcon(G_DEFAULT_ICON);
	self.icon.image = "http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/markers/"+self.type+".png";
	self.icon.iconSize = new GSize(25, 35);
	self.icon.shadowSize = new GSize(0, 0);

	markerOptions = { icon:self.icon };

    var gmarker = new GMarker(self.point,markerOptions);
    GEvent.addListener(gmarker, 'click', function() {self.getinfo();});
    GEvent.addListener(gmarker, 'dblclick', function() {self.remove();});
    return gmarker;
  }

  this.getinfo = function() {
    if (!self.infoDiv) {
      self.infoDiv = document.createElement('div');
      self.infoDiv.className = 'maps-landmark-info';
	  
	  var rightColumn = document.createElement('td');
	  rightColumn.className = 'maps-landmark-info-right';
	  var leftColumn = document.createElement('td');
	  leftColumn.className = 'maps-landmark-info-left';

	  var i = document.createElement('img');
	  i.className = 'maps-landmark-info-image';
      if (self.imageurl) {
        i.src = "http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/"+self.imageurl;
	  } else {
	    i.src = "http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/images/notfound.jpg";
	  }
      leftColumn.appendChild(i);

      t = document.createElement('a');
      t.className = 'maps-landmark-info-removemarker';
      t.href = 'javascript:void();';
      t.appendChild(document.createTextNode('Remove marker'));
      t.onclick = function(e) {
          Maps.map.removeOverlay(self.marker);
          Maps.map.closeInfoWindow();
      }
      leftColumn.appendChild(t);
	  
      var t = document.createElement('span');
      t.className = 'maps-landmark-info-code';
      t.appendChild(document.createTextNode(self.code));
      rightColumn.appendChild(t);

      if (self.name != self.code) {
        t = document.createElement('span');
        t.className = 'maps-landmark-info-name';
        t.appendChild(document.createTextNode(self.name));
        rightColumn.appendChild(t);
      }
	  
	  if (self.loc) {
        t = document.createElement('div');
        t.className = 'maps-landmark-info-loc';
        t.appendChild(document.createTextNode(self.loc));
        rightColumn.appendChild(t);
      }

      /*t = document.createElement('a');
      t.className = 'maps-landmark-info-permalink';
      t.href = 'virtualmap?campus=' + escape(campus.shortname) + '&' + escape(self.type) + '=' + escape(self.code);
      t.appendChild(document.createTextNode('direct link (copy/paste)')); //Permalink copy/paste
      rightColumn.appendChild(t);
	  */

      if (self.contact) {
        t = document.createElement('div');
        t.className = 'maps-landmark-info-contact';
        t.appendChild(document.createTextNode(self.contact));
        rightColumn.appendChild(t);
      }
	  
	  if (self.des) {
        t = document.createElement('div');
        t.className = 'maps-landmark-info-des';
        t.innerHTML = self.des;
        rightColumn.appendChild(t);
      }
	  
	  if (self.parking) {
        t = document.createElement('div');
        t.className = 'maps-landmark-info-parking';
        t.appendChild(document.createTextNode(self.parking));
        rightColumn.appendChild(t);
      }

	  var table = document.createElement('table');
	  var tbody = document.createElement('tbody');
	  var tr = document.createElement('tr');
		
	  tr.appendChild(leftColumn);
	  tr.appendChild(rightColumn);
	  tbody.appendChild(tr);
	  table.appendChild(tbody)
	  self.infoDiv.appendChild(table);
    }
	
    self.marker.openInfoWindow(self.infoDiv);
  }

  this.focus = function(callback) {
    Maps.map.removeOverlay(self.marker);
    Maps.map.addOverlay(self.marker);
    self.getinfo();

    if (callback) {callback(self.campus);}
  }

  this.remove = function() {
    Maps.map.closeInfoWindow();
    Maps.map.removeOverlay(self.marker);
  }
}

var MapUserLandmark = function(point, campusshortname, text) {
  var self = this;
  this.id = '[' + point.x + ',' + point.y + ']';
  this.campusshortname = campusshortname;
  this.text = text;
  this.marker = createMarker(point);
  this.infoDiv = null;

  function createMarker(p) {
    var gmarker = new GMarker(p,
        {icon:new GIcon(G_DEFAULT_ICON, 'http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/markers/usermarker.png'), draggable:true, bouncy:true}
    );
	//gmarker.icon.iconSize = new GSize(25,35);
	//gmarker.icon.shadowSize = new GSize(0,0);
	
    GEvent.addListener(gmarker, 'click', function() {self.getinfo();});
    GEvent.addListener(gmarker, 'dragend', function() {self.sethref();});
    return gmarker;
  }

  this.settext = function() {
    var elm = document.getElementById('maps-userlandmark-info-text-' + self.id);
    while (elm.childNodes.length) elm.removeChild(elm.childNodes[0]);
    elm.appendChild(self.gettext());
  }

  this.gettext = function() {
    var s = document.createElement('span');
    s.appendChild(document.createTextNode(self.text));
    return s;
  }

  this.sethref = function() {
    var elm = document.getElementById('maps-userlandmark-info-permalink-' + self.id);
    if (elm) elm.href = self.gethref();
  }

  this.gethref = function() {
    var spot = self.marker.getPoint();
    var href = '';
    if (self.campusshortname && Maps.campuses[self.campusshortname]) {
      href += 'virtualmap?campus=' + escape(self.campusshortname) + '&';
    }
    href += 'lon=' + spot.x + '&lat=' + spot.y
    if (self.text) {
      href += '&info=' + escape(self.text);
    }
    return href;
  }

  this.getinfo = function() {
    if (!self.infoDiv) {
      self.infoDiv = document.createElement('div');
      self.infoDiv.className = 'maps-userlandmark-info';

      var d = document.createElement('div');
      d.id = 'maps-userlandmark-info-text-' + self.id;
      d.className = 'maps-userlandmark-info-text';

      if (self.text) {
        d.appendChild(self.gettext());
      } else {
        var s = document.createElement('input');
        s.setAttribute('type', 'text');
        s.setAttribute('size', '15');
        s.onkeyup = function(e) { 
            if (!e) var e = window.event;
            if (e.keyCode == 13) { //enter
              self.text = this.value;
              self.settext();
              self.sethref();
            }
        }
        d.appendChild(s);
      }
      self.infoDiv.appendChild(d);

      var t = document.createElement('a');
      t.id = 'maps-userlandmark-info-permalink-' + self.id;
      t.className = 'maps-userlandmark-info-permalink';
      t.href = self.gethref();
      t.appendChild(document.createTextNode('Map Permalink (Copy/Paste Link)'));
      self.infoDiv.appendChild(t);

      t = document.createElement('a');
      t.className = 'maps-userlandmark-info-removemarker';
      t.href = 'javascript:void();';
      t.appendChild(document.createTextNode('Remove marker'));
      t.onclick = function(e) {self.remove();}
      self.infoDiv.appendChild(t);

      self.marker.openInfoWindow(self.infoDiv);

    } else {
      self.marker.openInfoWindow(self.infoDiv);
      self.sethref();
    }
  }

  this.focus = function(callback) {
    Maps.map.removeOverlay(self.marker);
    Maps.map.addOverlay(self.marker);
    self.getinfo();

    if (callback) {callback(self.campus);}
  }

  this.remove = function() {
    Maps.map.closeInfoWindow();
    Maps.map.removeOverlay(self.marker);
  }
}

var MapOverlay = function(xmlOverlay, campus) {
  var self = this;
  this.type = xmlOverlay.getAttribute('type');
  this.tilelayers = new Object();
  this.visible = false;

  var a = xmlOverlay.getElementsByTagName('tilelayer');
  if (a) {
    for (var i = 0; i < a.length; i++) {
      var layer = new Object();
      layer['zoomlevel'] = a[i].getAttribute('zoomlevel');
      layer['xmin'] = a[i].getAttribute('xmin');
      layer['xmax'] = a[i].getAttribute('xmax');
      layer['ymin'] = a[i].getAttribute('ymin');
      layer['ymax'] = a[i].getAttribute('ymax');

      this.tilelayers[layer['zoomlevel']] = layer;
    }
  }

  var tl = new GTileLayer(new GCopyrightCollection(), 0, 17);
  tl.getTileUrl = function(tile, zoom) {
    var layer = self.tilelayers[zoom];
    if (layer && tile.x >= layer['xmin'] && tile.x <= layer['xmax'] &&
                 tile.y >= layer['ymin'] && tile.y <= layer['ymax']) {
      return 'http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/tiles/' + campus.shortname + '/z' + zoom + 'x' + tile.x + 'y' + tile.y + '.gif';

	  //return 'http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/tiles/' + campus.shortname + '/z' + zoom + 'x' + tile.x + 'y' + tile.y + '.png';

    } else {
      return 'http://webapps.cincinnatistate.edu/cstate_edu/CampusMaps/images/transparent.gif';
    }
  }
  GEvent.addListener(Maps.map, 'maptypechanged', function() {
    if (campus.isFocused) {
      var t = Maps.map.getCurrentMapType();
      if (t == G_SATELLITE_MAP || t == G_HYBRID_MAP) {
        self.hide();
      } else {
        self.show();
      }
    }
  });

  this.overlay = new GTileLayerOverlay(tl);

  this.show = function() {
    if (!this.visible) Maps.map.addOverlay(self.overlay);
    this.visible = true;

    var cb = document.getElementById('maps-overlay-checkbox-' + campus.shortname);
    if (cb) cb.checked = true;
  }

  this.hide = function() {
    if (this.visible) Maps.map.removeOverlay(self.overlay);
    this.visible = false;

    var cb = document.getElementById('maps-overlay-checkbox-' + campus.shortname);
    if (cb) cb.checked = false;
  }
}

var MapsPopup = function(type) {
  var self = this;
  this.type = type;
  this.dirty = true;
  this.options = new Array();

  this.node = null;
  this.list = null;

  this.node = document.createElement('div');
  this.node.className = 'maps-popup maps-popup-inactive';
  this.node.style.opacity = 0.97;
  this.node.style.MozOpacity = 0.97;
  this.node.style.KHTMLOpacity = 0.97;
  this.node.style.filter = 'alpha(opacity:97)';
  this.node.appendChild(createSearchBar());

  this.list = document.createElement('div');
  this.list.className = 'maps-popup-list';
  this.node.appendChild(this.list);

  var d = document.body ? document.body : document.documentElement;
  d.appendChild(this.node);

  function createSearchBar() {
    var t = document.createElement('div');
    t.className = 'maps-popup-searchbar';

    var a = document.createElement('a');
    a.className = 'maps-popup-closebutton';
    a.href = 'javascript:void();';
    a.onclick = function(e) { self.blur(); }
    a.appendChild(document.createTextNode('Close'));
    t.appendChild(a);

    t.appendChild(document.createTextNode('Search: '));

    var s = document.createElement('input');
    s.setAttribute('type', 'text');
    s.setAttribute('size', '60');
    s.onkeyup = function(e) { self.search(this.value); }
    t.appendChild(s);

    return t;
  }

  function createBaseBar() {
    var t = document.createElement('div');
    t.className = 'maps-popup-basebar';
    var a = document.createElement('a');
    a.className = 'maps-popup-bottomclosebutton';
    a.href = 'javascript:void();';
    a.onclick = function(e) { self.blur(); }
    a.appendChild(document.createTextNode('Close'));
    t.appendChild(a);

    return t;
  }

  this.addoption = function(landmark) {
    self.options.push(new MapsPopupOption(self, landmark));
    self.dirty = true;
  }

  this.focus = function() {
    if (self.dirty) {
      while (self.list.childNodes.length) self.list.removeChild(self.list.childNodes[0]);
      if (self.options.length > 0) {
        self.options.sort(self.sort);
        for (var i = 0; i < self.options.length; i++) {
          self.list.appendChild(self.options[i].node);
        }
      } else {
        self.list.appendChild(document.createTextNode('There are no landmarks defined for this type.'));
      }
      self.dirty = false;
    }
    self.node.className = 'maps-popup maps-popup-active';
  }

  this.blur = function() {
    self.node.className = 'maps-popup maps-popup-inactive';
  }

  this.sort = function(a, b) {
    return (a.name > b.name ? 1 : -1);
  }

  this.search = function(value) {
    if (value) {
      var text = value.toLowerCase();
      for (var i = 0; i < self.options.length; i++) {
        if (self.options[i].matches(text)) {
          self.options[i].show();
        } else {
          self.options[i].hide();
        }
      }
    } else {
      for (var i = 0; i < self.options.length; i++) {
        self.options[i].show();
      }
    }
  }

}

var MapsPopupOption = function(parent, landmark) {
  var self = this;
  this.name = landmark.name.toLowerCase();
  this.node = createOption(landmark);

  function createOption(lm) {
    var a = document.createElement('a');
    a.className = 'maps-popup-option';
    a.href = 'javascript:void();';
    a.onclick = function(e) {
        lm.campus.selectLandmark(lm.type, lm.code);
        parent.blur();
    }
    a.appendChild(document.createTextNode(lm.name + (lm.name != lm.code ? ' (' + lm.code + ')' : '')));

    return a;
  }

  this.matches = function(text) {
    return (self.name.match(text));
  }

  this.show = function() {
    self.node.className = 'maps-popup-option';
  }

  this.hide = function() {
    self.node.className = 'maps-popup-option maps-popup-option-hidden';
  }
}

var MapQuery = new Object();
MapQuery.parse = function() {
  var query = document.location.search.substring(1);
  var parms = query.split('&');
  for (var i = 0; i < parms.length; i++) {
    var pos = parms[i].indexOf('=');
    if (pos > 0) MapQuery[parms[i].substring(0, pos)] = unescape(parms[i].substring(pos+1));
  }
}
MapQuery.parse();

Maps.directLink = function(campus) {
  var c = MapQuery['campus'];
  if (c == campus.shortname) {
    campus.focus(Maps.directLandmarkLink);

    var lat = MapQuery['lat'];
    var lon = MapQuery['lon'];

    if (lat && lon) {
      var p = new GLatLng(parseFloat(lat), parseFloat(lon));
      var lm = new MapUserLandmark(p, c, (MapQuery['info'] ? MapQuery['info'] : null));
      lm.focus();
    }
  }
}

Maps.directLandmarkLink = function(campus) {
  var b = MapQuery['building'];
  var m = campus.markersets['building'];
  if (b && m && m.landmarks && m.landmarks[b]) {
    m.landmarks[b].focus();
  }

  var d = MapQuery['decalparking'];
  var m = campus.markersets['decalparking'];
  if (d && m && m.landmarks && m.landmarks[d]) {
    m.landmarks[d].focus();
  }

  var v = MapQuery['visitorparking'];
  var m = campus.markersets['visitorparking'];
  if (v && m && m.landmarks && m.landmarks[v]) {
    m.landmarks[v].focus();
  }
}

