
/*	GOOGLE MAP
------------------------------------------------------*/
var GoogleMap = {

	cur_map: null,

	menu: null,

	init: function(id){
	
		if (!$('map-menu')) {
			this.show(id);
			return;
		}
		this.menu = $$('#map-menu li a');
		this.cur_map = id;
		
	
		this.menu.each(function(a,i){
			a.addEvent('click', function(){
				GoogleMap.toggle(i);
			});
		});
		// get the ball rolling
		this.toggle(id);
		
	},

	toggle: function(id){
//		if (id !== this.cur_map) {
			this.show(id);
			// highlight menu item
			if (this.cur_map != null) this.menu[this.cur_map].removeClass('selected');
			this.menu[id].addClass('selected');
			this.cur_map = id;
//		}
	},

	show: function(id){
		var map,
			mapURL,
			mapURL2,
			mapCity;
		var mapZoom = 12;
		var latPanOffset = .0008;
		var lngPanOffset = 0;
		var showImage = true;
		
		switch(id) {
/*			case 0:
			// WE LIVE HERE / WHERE WE PLAY
			mapURL = 'http://maps.google.com/maps/ms?ie=UTF8&hl=en&msa=0&msid=215825142763644749184.0004ac7a44baa805ef218&output=kml';
			var browserName=navigator.appName;								
			if (browserName=="Microsoft Internet Explorer"){
				mapCity = new google.maps.LatLng(30.271592,-97.751929);//30.272518,-97.752658
				latPanOffset = .003;
			} else {
				mapCity = new google.maps.LatLng(30.271592,-97.751929);//30.272518,-97.752658
				latPanOffset = .0015;
			}
			mapZoom = 17;
			latPanOffset = .0005;
			lngPanOffset = 0;
			showImage = true;
			break;
*/			
			
			case 0:
			// WE LIVE HERE / WHERE WE PLAY
			mapURL = 'http://maps.google.com/maps/ms?ie=UTF8&hl=en&msa=0&msid=116250796638808646834.0004952dd57dfe16d3fc6&output=kml';
			var browserName=navigator.appName;
			if (browserName=="Microsoft Internet Explorer"){
				mapCity = new google.maps.LatLng(30.273023,-97.752766);//30.272518,-97.752658
				latPanOffset = .003;
			} else {
				mapCity = new google.maps.LatLng(30.272773,-97.75283);//30.272518,-97.752658
				latPanOffset = .0015;
			}
			mapZoom = 17;
			latPanOffset = .0015;
			lngPanOffset = 0;
			showImage = true;
			break;
			
			case 1:
			// WHERE WE WORK
				mapURL = 'http://maps.google.com/maps/ms?ie=UTF8&hl=en&msa=0&msid=116250796638808646834.0004952ddb1b6f560c27a&ll=25.594039,-39.703012&spn=25.67432,40.605469&z=2&output=kml';
				mapCity = new google.maps.LatLng(27.792497,6.703238);//25.594039,-39.703012
				mapZoom = 2;
				latPanOffset = 2;
				lngPanOffset = 0;
				showImage = false;
			break;
			
			case 2:
			// SEASONAL - SXSW/ACL
				mapURL = 'http://maps.google.com/maps/ms?ie=UTF8&hl=en&oe=UTF8&msa=0&msid=116250796638808646834.0004952ddd61d4844b369&output=kml';
				var browserName=navigator.appName;
				if (browserName=="Microsoft Internet Explorer"){
					mapCity = new google.maps.LatLng(30.273023,-97.752766);//30.272518,-97.752658
					latPanOffset = .003;
				} else {
					mapCity = new google.maps.LatLng(30.272773,-97.75283);//30.272518,-97.752658
					latPanOffset = .0015;
				}
				mapZoom = 17;
				latPanOffset = .0015;
				lngPanOffset = 0;
				showImage = true;
			break;
			
			case 3:
			// CONTACT AUSTIN
				mapURL = 'http://maps.google.com/maps/ms?ie=UTF8&hl=en&msa=0&msid=116250796638808646834.0004952dd57dfe16d3fc6&output=kml';
				if (DetectSmartphone()) {
					mapCity = new google.maps.LatLng(30.273917,-97.75194);
				
				} else {
					mapCity = new google.maps.LatLng(30.271962,-97.754504);
				}
				mapZoom = 17;
				latPanOffset = .0015;
				lngPanOffset = 0;
				showImage = true;
			break;

			case 4:
			// CONTACT CHICAGO
				mapURL = 'http://maps.google.com/maps/ms?ie=UTF8&hl=en&oe=UTF8&msa=0&msid=116250796638808646834.000496478f12ba173dbdb&output=kml';
				if (DetectSmartphone()) {
					mapCity = new google.maps.LatLng(30.273917,-97.75194);
				} else {
					mapCity = new google.maps.LatLng(41.889649,-87.626396);
				}
				
				mapZoom = 17;
				latPanOffset = .0015;
				lngPanOffset = 0;
				showImage = true;
			break;

			case 5:
			// PR MAP
				mapURL = 'http://maps.google.com/maps/ms?ie=UTF8&hl=en&msa=0&msid=215825142763644749184.000497dd0107204dda717&output=kml';
				mapCity = new google.maps.LatLng(41.889569,-87.624754);
				mapZoom = 17;
				latPanOffset = .0005;
				lngPanOffset = 0;
				showImage = true;
			break;

			case 6:
			// ANDROID and MOBILE
				mapURL = 'http://maps.google.com/maps/ms?ie=UTF8&hl=en&msa=0&msid=215825142763644749184.000497dd0107204dda717&output=kml';
				if (DetectSmartphone()) {
					mapCity = new google.maps.LatLng(30.273917,-97.75194);
				
				} else {
					mapCity = new google.maps.LatLng(30.271962,-97.754504);
				}
				mapZoom = 17;
				latPanOffset = .0005;
				lngPanOffset = 0;
				showImage = true;
			break;

		}
		
		var stylez = [{
			featureType: "all",
			elementType: "all",
			stylers: [
				{ hue: "#ff9900" },
				{ saturation: -99 },
				{ gamma: 1.36 },
				{ lightness: 0 }
			]}
		];
		
		 var mapOptions = {
			zoom: mapZoom,
			center: mapCity,
			mapTypeControl: false,
			//mapTypeControlOptions: {style: google.maps.MapTypeControlStyle.DROPDOWN_MENU},
			navigationControl: true,
			navigationControlOptions: {style: google.maps.NavigationControlStyle.SMALL, position: google.maps.ControlPosition.TOP_RIGHT},
		 //   streetViewControl: false,
			mapTypeId: google.maps.MapTypeId.ROADMAP	
		 };
		 
		 
	    map = new google.maps.Map(document.getElementById("google-map"), mapOptions);


		var georssLayer = new geoXML3.parser({map:map, zoom:false, singleInfoWindow:true, infoWindowOptions:{maxWidth:275, disableAutoPan:true}, markerOptions:{flat:true}, createMarker:addMyMarker});
		georssLayer.parse(mapURL);
		
		var icMarker, icLocation;
		var markerArray = [];
		function addMyMarker(placemark) {
			// Marker handling code goes here
			var marker = new google.maps.Marker(georssLayer.createMarker(placemark));
			markerArray.push(marker);

			if (showImage == true && (marker.getTitle() == "GSD&M")) {
				//marker.infoWindow.open(map, marker);
				marker.ib.open(map, marker);
				google.maps.event.addListener(georssLayer, 'click', closeIC);
				//alert(marker);
			}
			setMapClick(id, marker, map);
			
		};
		
		function closeIC(event) {
			event.target.removeEventListener('click',arguments.callee,false);
			event.target.ib.close();		
			//google.maps.event.removeListener(map, 'center_changed', true);
			//alert(refMarker.getTitle());
		}
		function getLPO() {
			var newLPO = latPanOffset
			return newLPO;
		}
		//var georssLayer = new google.maps.KmlLayer(mapURL,{preserveViewport:true,suppressInfoWindows: false});
		var mapZoomed = false;
		google.maps.event.addListener(map, 'zoom_changed', function() {
			mapZoomed = true;
		});
		
		function shiftMap(cLatLng, whichMap) {
			var llOffset = getLPO();
			var llArray = cLatLng.split(", ");
			var newLat = new Number(llArray[0].slice(1,llArray[0].length));
			var newLng = new Number(llArray[1].slice(0,(llArray[1].length-1)));
			newLat += llOffset;
			//newLng += llOffset;
			var newDestLatLng = new google.maps.LatLng(newLat,newLng);
				if (id == 1) {
				whichMap.setZoom(6);
			} else {
				whichMap.setZoom(17);
			}
			whichMap.panTo(newDestLatLng);
		}
		
		function setMapClick(switcher, refMarker, refMap)  {
			switch(switcher) {
				case 0:
				case 1:
				case 2:
					google.maps.event.addListener(refMarker, 'click', function(event) {
						var currentLatLng = new String(refMarker.getPosition());
			//			alert(refMarker.ib.getPosition());
			//			alert(currentLatLng);
						refMarker.ib.open(map,refMarker);
						shiftMap(currentLatLng, refMap);
					});				
				
				break;
				
				case 3:
				case 4:
					google.maps.event.addListener(refMarker, 'click', function(event) {
						var currentLatLng = new String(refMarker.getPosition());
						//alert(refMarker.ib.getPosition());
						//alert(currentLatLng);
						if (!$('contact-content').getParent('#panel_2').hasClass('collapsed')) {
							$('collapse-contact').fireEvent('click');
						}
						//$('panel_2').addClass('collapse-contact');
						refMarker.ib.open(map,refMarker);
						shiftMap(currentLatLng, refMap);
						//$('panel_2').addClass('collapsed');
						//$('contact-content').getParent('#panel_2').addClass('collapsed');
						var currentLatLng = new String(refMarker.getPosition());
						shiftMap(currentLatLng, refMap);
					});				
				break;
			}
		}

 		
	    var styledMapOptions = {
	        map: map,
	        name: "tips4php"
	    }
	    
	    var icmap = new google.maps.StyledMapType(stylez, styledMapOptions);
	    map.mapTypes.set('tips4php', icmap);
	    map.setMapTypeId('tips4php');
	}
};

//COMMENT OUT LATER
 window.addEvent('domready',function() {
	//GoogleMap.init(0);
 });

/*geoXML3.js*/
// Extend the global String with a method to remove leading and trailing whitespace
if (!String.prototype.trim) {
  String.prototype.trim = function () {
    return this.replace(/^\s+|\s+$/g, '');
  };
}

// Declare namespace
geoXML3 = window.geoXML3 || {};

// Constructor for the root KML parser object
geoXML3.parser = function (options) {
  // Private variables
  var parserOptions = geoXML3.combineOptions(options, {
    singleInfoWindow: false,
    processStyles: true,
    zoom: true
  });
  var docs = []; // Individual KML documents
  var lastMarker;

  // Private methods

  var parse = function (urls) {
    // Process one or more KML documents
  
    if (typeof urls === 'string') {
      // Single KML document
      urls = [urls];
    }

    // Internal values for the set of documents as a whole
    var internals = {
      docSet: [],
      remaining: urls.length,
      parserOnly: !parserOptions.afterParse
    }; 

    var thisDoc;
    for (var i = 0; i < urls.length; i++) {
      thisDoc = {
        url: urls[i], 
        internals: internals
      };
      internals.docSet.push(thisDoc);
      geoXML3.fetchXML(thisDoc.url, function (responseXML) {render(responseXML, thisDoc);});
    }
  };

  var hideDocument = function (doc) {
    // Hide the map objects associated with a document 
    var i;
    for (i = 0; i < doc.markers.length; i++) {
      this.markers[i].set_visible(false);
    }
    for (i = 0; i < doc.overlays.length; i++) {
      doc.overlays[i].setOpacity(0);
    }
  };
  
  var showDocument = function (doc) {
    // Show the map objects associated with a document 
    var i;
    for (i = 0; i < doc.markers.length; i++) {
      doc.markers[i].set_visible(true);
    }
    for (i = 0; i < doc.overlays.length; i++) {
      doc.overlays[i].setOpacity(doc.overlays[i].percentOpacity_);
    }
  };

  var render = function (responseXML, doc) {
    // Callback for retrieving a KML document: parse the KML and display it on the map

    if (!responseXML) {
      // Error retrieving the data
      geoXML3.log('Unable to retrieve ' + doc.url);
      if (parserOptions.failedParse) {
        parserOptions.failedParse(doc);
      }
    } else if (!doc) {
      throw 'geoXML3 internal error: render called with null document';
    } else {
      doc.styles = {};
      doc.placemarks = [];
      doc.groundOverlays = [];
      if (parserOptions.zoom && !!parserOptions.map)
        doc.bounds = new google.maps.LatLngBounds();
  
      // Parse styles
      var styleID, iconNodes, i;
      var styleNodes = responseXML.getElementsByTagName('Style');
      for (i = 0; i < styleNodes.length; i++) {
        styleID   = styleNodes[i].getAttribute('id');
        iconNodes = styleNodes[i].getElementsByTagName('Icon');
        if (!!iconNodes.length) {
          doc.styles['#' + styleID] = {
            href: geoXML3.nodeValue(iconNodes[0].getElementsByTagName('href')[0])
          };
        }
      }
      if (!!parserOptions.processStyles || !parserOptions.createMarker) {
        // Convert parsed styles into GMaps equivalents
        processStyles(doc);
      }
      
      // Parse placemarks
      var placemark, node, coords, path;
      var placemarkNodes = responseXML.getElementsByTagName('Placemark');
      for (i = 0; i < placemarkNodes.length; i++) {
        // Init the placemark object
        node = placemarkNodes[i];
        placemark = {
          name:  geoXML3.nodeValue(node.getElementsByTagName('name')[0]),
          description: geoXML3.nodeValue(node.getElementsByTagName('description')[0]),
          styleUrl: geoXML3.nodeValue(node.getElementsByTagName('styleUrl')[0])
        };
        placemark.style = doc.styles[placemark.styleUrl] || {};
        if (/^https?:\/\//.test(placemark.description)) {
          placemark.description = '<a href="' + placemark.description + '">' + placemark.description + '</a>';
        }

        // Extract the coordinates
        coords = geoXML3.nodeValue(node.getElementsByTagName('coordinates')[0]).trim();
        coords = coords.replace(/\s+/g, ' ').replace(/, /g, ',');
        path = coords.split(' ');

        // What sort of placemark?
        if (path.length === 1) {
          // Polygons/lines not supported in v3, so only plot markers
          coords = path[0].split(',');
          placemark.point = {
            lat: parseFloat(coords[1]), 
            lng: parseFloat(coords[0]), 
            alt: parseFloat(coords[2])
          };
          if (!!doc.bounds) {
            doc.bounds.extend(new google.maps.LatLng(placemark.point.lat, placemark.point.lng));
          }

          // Call the appropriate function to create the marker
          if (!!parserOptions.createMarker) {
            parserOptions.createMarker(placemark, doc);
          } else {
            createMarker(placemark, doc);
          }
        }
      }
  
      // Parse ground overlays
      var groundOverlay, color, transparency;
      var groundNodes = responseXML.getElementsByTagName('GroundOverlay');
      for (i = 0; i < groundNodes.length; i++) {
        node = groundNodes[i];
        
        // Init the ground overlay object
        groundOverlay = {
          name:        geoXML3.nodeValue(node.getElementsByTagName('name')[0]),
          description: geoXML3.nodeValue(node.getElementsByTagName('description')[0]),
          icon: {href: geoXML3.nodeValue(node.getElementsByTagName('href')[0])},
          latLonBox: {
            north: parseFloat(geoXML3.nodeValue(node.getElementsByTagName('north')[0])),
            east:  parseFloat(geoXML3.nodeValue(node.getElementsByTagName('east')[0])),
            south: parseFloat(geoXML3.nodeValue(node.getElementsByTagName('south')[0])),
            west:  parseFloat(geoXML3.nodeValue(node.getElementsByTagName('west')[0]))
          }
        };
        if (!!doc.bounds) {
          doc.bounds.union(new google.maps.LatLngBounds(
            new google.maps.LatLng(groundOverlay.latLonBox.south, groundOverlay.latLonBox.west),
            new google.maps.LatLng(groundOverlay.latLonBox.north, groundOverlay.latLonBox.east)
          ));
        }

        // Opacity is encoded in the color node
        color = geoXML3.nodeValue(node.getElementsByTagName('color')[0]);
        if ((color !== '') && (color.length == 8)) {
          transparency = parseInt(color.substring(0, 2), 16);
          groundOverlay.opacity = Math.round((255 - transparency) / 2.55);
        } else {
          groundOverlay.opacity = 100;
        }
  
        // Call the appropriate function to create the overlay
        if (!!parserOptions.createOverlay) {
          parserOptions.createOverlay(groundOverlay, doc);
        } else {
          createOverlay(groundOverlay, doc);
        }
      }

      if (!!doc.bounds) {
        doc.internals.bounds = doc.internals.bounds || new google.maps.LatLngBounds();
        doc.internals.bounds.union(doc.bounds); 
      }
      if (!!doc.styles || !!doc.markers || !!doc.overlays) {
        doc.internals.parserOnly = false;
      }

      doc.internals.remaining -= 1;
      if (doc.internals.remaining === 0) {
        // We're done processing this set of KML documents

        // Options that get invoked after parsing completes
        if (!!doc.internals.bounds) {
          parserOptions.map.fitBounds(doc.internals.bounds); 
        }
        if (parserOptions.afterParse) {
          parserOptions.afterParse(doc.internals.docSet);
        }

        if (!doc.internals.parserOnly) {
          // geoXML3 is not being used only as a real-time parser, so keep the parsed documents around
          docs.concat(doc.internals.docSet);
        }
      }
    }
  };
    
  var processStyles = function (doc) {
    var stdRegEx = /\/(red|blue|green|yellow|lightblue|purple|pink|orange)(-dot)?\.png/;
    for (var styleID in doc.styles) {
      if (!!doc.styles[styleID].href) {
        // Init the style object with a standard KML icon
        doc.styles[styleID].icon =  new google.maps.MarkerImage(
          doc.styles[styleID].href,
          new google.maps.Size(64, 64),
          new google.maps.Point(0, 0),
          new google.maps.Point(32, 32)
        );

        // Look for a predictable shadow
        if (stdRegEx.test(doc.styles[styleID].href)) {
          // A standard GMap-style marker icon
         /* doc.styles[styleID].shadow = new google.maps.MarkerImage(
              'http://maps.google.com/mapfiles/ms/micons/msmarker.shadow.png',
              new google.maps.Size(59, 32),
              new google.maps.Point(0, 0),
              new google.maps.Point(16, 12));*/
        } else if (doc.styles[styleID].href.indexOf('-pushpin.png') > -1) {
          /*doc.styles[styleID].shadow = new google.maps.MarkerImage(
            'http://maps.google.com/mapfiles/ms/micons/pushpin_shadow.png',
            new google.maps.Size(59, 32),
            new google.maps.Point(0, 0),
            new google.maps.Point(16, 12));*/
        } else {
        }
      }
    }
  };

  var createMarker = function (placemark, doc) {
    if (!!window.XMLHttpRequest) {// Most browsers
		var markerOptions = geoXML3.combineOptions(parserOptions.markerOptions, {
		  map:      parserOptions.map,
		  position: new google.maps.LatLng(placemark.point.lat, placemark.point.lng),
		  title:    placemark.name,
		  zIndex:   Math.round(-placemark.point.lat * 100000),
		  icon:     placemark.style.icon
		});
    } else if (!!window.ActiveXObject) {// Some IE
		var markerOptions = geoXML3.combineOptions(parserOptions.markerOptions, {
		  map:      parserOptions.map,
		  position: new google.maps.LatLng(placemark.point.lat, placemark.point.lng),
		  title:    placemark.name,
		  zIndex:   Math.round(-placemark.point.lat * 100000)
		});
    }
  
	var marker = new google.maps.Marker(markerOptions);
	var contentFormat;
	
	var browserName=navigator.appName;
	var newOverlayOffset;
	var closeBtnOffset;
	
	if (browserName=="Microsoft Internet Explorer"){
	 	if(Browser.name == 'ie' && Browser.version == 7) {
			newOverlayOffset =  new google.maps.Size(-80,-85);
			closeBtnOffset = "10px 0px -30px 246px";
	 	} else {
			newOverlayOffset =  new google.maps.Size(-80,-85);
			closeBtnOffset = "50px 10px -20px 0px";
	 	}
	 	contentFormat = '<div class="rounded"><div class="top">&nbsp;</div><div class="map-canvas-info-ie"><div id="map-canvas-info-header-ie"><h1>'+placemark.name+'</h1></div>		<div class="map-canvas-info-content-ie"><p>' + placemark.description + '</p></div></div><div class="btm">&nbsp;</div></div><div class="map-canvas-info-footer-ie">&nbsp;</div>';
	 	
	} else {
		newOverlayOffset =  new google.maps.Size(-80,-85);
		closeBtnOffset = "10px 10px 0px 0px";
		contentFormat = '<div class="map-canvas-info"><div id="map-canvas-info-header"><h1>' + placemark.name + '</h1></div><div class="map-canvas-info-content"><p>' + placemark.description + '</p></div></div><div id="map-canvas-info-footer">&nbsp;</div>';
	}   

   
	if (marker.getTitle() == "GSD&M Idea City" || marker.getTitle() == "GSD&M") {
		lastMarker = marker;
	}
	
	var infoWindowOptions = geoXML3.combineOptions(parserOptions.infoWindowOptions, {
	  content: contentFormat,
	  pixelOffset: new google.maps.Size(0, 2)
	});
	
	var boxText = document.createElement("div");
	boxText.innerHTML = contentFormat;
	
	var myOptions = {
		content: boxText
		,position: new google.maps.LatLng(placemark.point.lat, placemark.point.lng)
		,alignBottom: true
		,disableAutoPan: true
		,pixelOffset: newOverlayOffset
		,zIndex: null
		,closeBoxMargin: closeBtnOffset
		,closeBoxURL: "/images/map/close.gif"
		,infoBoxClearance: new google.maps.Size(0, 0)
		,isHidden: false
		,pane: "floatPane"
		,enableEventPropagation: false
	};
	
	marker.ib = new InfoBox(myOptions);

	
	marker.infoWindow = new google.maps.InfoWindow(infoWindowOptions);
    google.maps.event.addListener(marker, 'click', function() {
      if (!!parserOptions.singleInfoWindow) {
        if (!!lastMarker && !!lastMarker.infoWindow) {
          lastMarker.infoWindow.close();
          lastMarker.ib.close();
          //lastMarker.close();
        }
        lastMarker = this;
      }
    //  this.infoWindow.open(this.map, this);
    });
    
    if (!!doc) {
      doc.markers = doc.markers || [];
      doc.markers.push(marker);
    }

    return marker;
  };
  
  var createOverlay = function (groundOverlay, doc) {
    // Add a ProjectedOverlay to the map from a groundOverlay KML object

    if (!window.ProjectedOverlay) {
      throw 'geoXML3 error: ProjectedOverlay not found while rendering GroundOverlay from KML';
    }

    var bounds = new google.maps.LatLngBounds(
        new google.maps.LatLng(groundOverlay.latLonBox.south, groundOverlay.latLonBox.west),
        new google.maps.LatLng(groundOverlay.latLonBox.north, groundOverlay.latLonBox.east)
    );
    var overlayOptions = geoXML3.combineOptions(parserOptions.overlayOptions, {percentOpacity: groundOverlay.opacity});
    var overlay = new ProjectedOverlay(parserOptions.map, groundOverlay.icon.href, bounds, overlayOptions);
    
    if (!!doc) {
      doc.overlays = doc.overlays || [];
      doc.overlays.push(overlay);
    }

    return 
  };

  return {
    options: parserOptions,
    docs:    docs,
    
    parse:         parse,
    hideDocument:  hideDocument,
    showDocument:  showDocument,
    processStyles: processStyles, 
    createMarker:  createMarker,
    createOverlay: createOverlay
  };
};
geoXML3.log = function(msg) {
  if (!!window.console) {
    console.log(msg);
  }
};
geoXML3.combineOptions = function (overrides, defaults) {
  var result = {};
  if (!!overrides) {
    for (var prop in overrides) {
      if (overrides.hasOwnProperty(prop)) {
        result[prop] = overrides[prop];
      }
    }
  }
  if (!!defaults) {
    for (prop in defaults) {
      if (defaults.hasOwnProperty(prop) && (result[prop] === undefined)) {
        result[prop] = defaults[prop];
      }
    }
  }
  return result;
};
geoXML3.fetchers = [];
geoXML3.fetchXML = function (url, callback) {
  function timeoutHandler() {
    callback();
  };

  var xhrFetcher;
  
  if (!!geoXML3.fetchers.length) {
    xhrFetcher = geoXML3.fetchers.pop();
  } else {
    if (!!window.XMLHttpRequest) {
      xhrFetcher = new window.XMLHttpRequest(); // Most browsers
    } else if (!!window.ActiveXObject) {
      xhrFetcher = new window.ActiveXObject('Microsoft.XMLHTTP'); // Some IE
    }
  }
  
if (!xhrFetcher) {
    geoXML3.log('Unable to create XHR object');
    callback(null);
  } else {
	var newURL = "/kml.aspx?url="+url;
	//var newURL = 'SXSWACL.kml';
    xhrFetcher.open('GET', newURL, true);
    xhrFetcher.onreadystatechange = function () {
      if (xhrFetcher.readyState === 4) {
        if (!!xhrFetcher.timeout)
          clearTimeout(xhrFetcher.timeout);
        if (xhrFetcher.status >= 400) {
          geoXML3.log('HTTP error ' + xhrFetcher.status + ' retrieving ' + newURL);
          callback();
        } else {
          callback(xhrFetcher.responseXML);
        }
        geoXML3.fetchers.push(xhrFetcher);
      }
    };
    xhrFetcher.timeout = setTimeout(timeoutHandler, 60000);
    xhrFetcher.send(null);
  } 
};
geoXML3.nodeValue = function(node) {
  if (!node) {
    return '';
  } else {
  if (!!window.ActiveXObject) {
		return (node.innerText || node.text).trim();
    } else {
		return (node.innerText || node.text || node.textContent).trim();
    }
  }
};

/*************************************************
 * @name InfoBox
 * @version 1.1.3 [January 15, 2011]
 * @author Gary Little (inspired by proof-of-concept code from Pamela Fox of Google)
 * @copyright Copyright 2010 Gary Little [gary at luxcentral.com]
 * @fileoverview InfoBox extends the Google Maps JavaScript API V3 <tt>OverlayView</tt> class.
 *  <p>
 *  An InfoBox behaves like a <tt>google.maps.InfoWindow</tt>, but it supports several
 *  additional properties for advanced styling. An InfoBox can also be used as a map label.
 *  <p>
 *  An InfoBox also fires the same events as a <tt>google.maps.InfoWindow</tt>.
 *  <p>
 *  Browsers tested:
 *  <p>
 *  Mac -- Safari (4.0.4), Firefox (3.6), Opera (10.10), Chrome (4.0.249.43), OmniWeb (5.10.1)
 *  <br>
 *  Win -- Safari, Firefox, Opera, Chrome (3.0.195.38), Internet Explorer (8.0.6001.18702)
 *  <br>
 *  iPod Touch/iPhone -- Safari (3.1.2)
 */

/*!
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*jslint browser:true */
/*global google */

/**
 * @name InfoBoxOptions
 * @class This class represents the optional parameter passed to the {@link InfoBox} constructor.
 * @property {string|Node} content The content of the InfoBox (plain text or an HTML DOM node).
 * @property {boolean} disableAutoPan Disable auto-pan on <tt>open</tt> (default is <tt>false</tt>).
 * @property {number} maxWidth The maximum width (in pixels) of the InfoBox. Set to 0 if no maximum.
 * @property {Size} pixelOffset The offset (in pixels) from the top left corner of the InfoBox
 *  (or the bottom left corner if the <code>alignBottom</code> property is <code>true</code>)
 *  to the map pixel corresponding to <tt>position</tt>.
 * @property {LatLng} position The geographic location at which to display the InfoBox.
 * @property {number} zIndex The CSS z-index style value for the InfoBox.
 *  Note: This value overrides a zIndex setting specified in the <tt>boxStyle</tt> property.
 * @property {string} boxClass The name of the CSS class defining the styles for the InfoBox container.
 *  The default name is <code>infoBox</code>.
 * @property {Object} [boxStyle] An object literal whose properties define specific CSS
 *  style values to be applied to the InfoBox. Style values defined here override those that may
 *  be defined in the <code>boxClass</code> style sheet. If this property is changed after the
 *  InfoBox has been created, all previously set styles (except those defined in the style sheet)
 *  are removed from the InfoBox before the new style values are applied.
 * @property {string} closeBoxMargin The CSS margin style value for the close box.
 *  The default is "2px" (a 2-pixel margin on all sides).
 * @property {string} closeBoxURL The URL of the image representing the close box.
 *  Note: The default is the URL for Google's standard close box.
 *  Set this property to "" if no close box is required.
 * @property {Size} infoBoxClearance Minimum offset (in pixels) from the InfoBox to the
 *  map edge after an auto-pan.
 * @property {boolean} isHidden Hide the InfoBox on <tt>open</tt> (default is <tt>false</tt>).
 * @property {boolean} alignBottom Align the bottom left corner of the InfoBox to the <code>position</code>
 *  location (default is <tt>false</tt> which means that the top left corner of the InfoBox is aligned).
 * @property {string} pane The pane where the InfoBox is to appear (default is "floatPane").
 *  Set the pane to "mapPane" if the InfoBox is being used as a map label.
 *  Valid pane names are the property names for the <tt>google.maps.MapPanes</tt> object.
 * @property {boolean} enableEventPropagation Propagate mousedown, click, dblclick,
 *  and contextmenu events in the InfoBox (default is <tt>false</tt> to mimic the behavior
 *  of a <tt>google.maps.InfoWindow</tt>). Set this property to <tt>true</tt> if the InfoBox
 *  is being used as a map label. iPhone note: This property setting has no effect. Events are
 *  always propagated for an InfoBox in the "mapPane" pane and they are <i>not</i> propagated
 *  for an InfoBox in the "floatPane" pane.
 */

/**
 * Creates an InfoBox with the options specified in {@link InfoBoxOptions}.
 *  Call <tt>InfoBox.open</tt> to add the box to the map.
 * @constructor
 * @param {InfoBoxOptions} [opt_opts]
 */
function InfoBox(opt_opts) {

  opt_opts = opt_opts || {};

  google.maps.OverlayView.apply(this, arguments);

  // Standard options (in common with google.maps.InfoWindow):
  //
  this.content_ = opt_opts.content || "";
  this.disableAutoPan_ = opt_opts.disableAutoPan || false;
  this.maxWidth_ = opt_opts.maxWidth || 0;
  this.pixelOffset_ = opt_opts.pixelOffset || new google.maps.Size(0, 0);
  this.position_ = opt_opts.position || new google.maps.LatLng(0, 0);
  this.zIndex_ = opt_opts.zIndex || null;

  // Additional options (unique to InfoBox):
  //
  this.boxClass_ = opt_opts.boxClass || "infoBox";
  this.boxStyle_ = opt_opts.boxStyle || {};
  this.closeBoxMargin_ = opt_opts.closeBoxMargin || "2px";
  this.closeBoxURL_ = opt_opts.closeBoxURL || "/image/map/close.gif";
  if (opt_opts.closeBoxURL === "") {
    this.closeBoxURL_ = "";
  }
  this.infoBoxClearance_ = opt_opts.infoBoxClearance || new google.maps.Size(1, 1);
  this.isHidden_ = opt_opts.isHidden || false;
  this.alignBottom_ = opt_opts.alignBottom || false;
  this.pane_ = opt_opts.pane || "floatPane";
  this.enableEventPropagation_ = opt_opts.enableEventPropagation || false;

  this.div_ = null;
  this.closeListener_ = null;
  this.eventListener1_ = null;
  this.eventListener2_ = null;
  this.eventListener3_ = null;
  this.moveListener_ = null;
  this.contextListener_ = null;
  this.fixedWidthSet_ = null;
}

/* InfoBox extends OverlayView in the Google Maps API v3.
 */
InfoBox.prototype = new google.maps.OverlayView();

/**
 * Creates the DIV representing the InfoBox.
 * @private
 */
InfoBox.prototype.createInfoBoxDiv_ = function () {

  var bw;
  var me = this;

  // This handler prevents an event in the InfoBox from being passed on to the map.
  //
  var cancelHandler = function (e) {
    e.cancelBubble = true;

    if (e.stopPropagation) {

      e.stopPropagation();
    }
  };

  // This handler ignores the current event in the InfoBox and conditionally prevents
  // the event from being passed on to the map. It is used for the contextmenu event.
  //
  var ignoreHandler = function (e) {

    e.returnValue = false;

    if (e.preventDefault) {

      e.preventDefault();
    }

    if (!me.enableEventPropagation_) {

      cancelHandler(e);
    }
  };

  if (!this.div_) {

    this.div_ = document.createElement("div");

    this.setBoxStyle_();

    if (typeof this.content_.nodeType === "undefined") {
      this.div_.innerHTML = this.getCloseBoxImg_() + this.content_;
    } else {
      this.div_.innerHTML = this.getCloseBoxImg_();
      this.div_.appendChild(this.content_);
    }

    // Add the InfoBox DIV to the DOM
    this.getPanes()[this.pane_].appendChild(this.div_);
  //  this.getPanes().floatShadow.appendChild(this.div_);

    this.addClickHandler_();

    if (this.div_.style.width) {

      this.fixedWidthSet_ = true;

    } else {

      if (this.maxWidth_ !== 0 && this.div_.offsetWidth > this.maxWidth_) {

        this.div_.style.width = this.maxWidth_;
        this.div_.style.overflow = "auto";
        this.fixedWidthSet_ = true;

      } else { // The following code is needed to overcome problems with MSIE

        bw = this.getBoxWidths_();

        this.div_.style.width = (this.div_.offsetWidth - bw.left - bw.right) + "px";
        this.fixedWidthSet_ = false;
      }
    }

    this.panBox_(this.disableAutoPan_);

    if (!this.enableEventPropagation_) {

      // Cancel event propagation.
      //
      this.eventListener1_ = google.maps.event.addDomListener(this.div_, "mousedown", cancelHandler);
      this.eventListener2_ = google.maps.event.addDomListener(this.div_, "click", cancelHandler);
      this.eventListener3_ = google.maps.event.addDomListener(this.div_, "dblclick", cancelHandler);
    }

    this.contextListener_ = google.maps.event.addDomListener(this.div_, "contextmenu", ignoreHandler);

    /**
     * This event is fired when the DIV containing the InfoBox's content is attached to the DOM.
     * @name InfoBox#domready
     * @event
     */
    google.maps.event.trigger(this, "domready");
  }
};

/**
 * Returns the HTML <IMG> tag for the close box.
 * @private
 */
InfoBox.prototype.getCloseBoxImg_ = function () {

  var img = "";

  if (this.closeBoxURL_ !== "") {

    img  = "<img";
    img += " src='" + this.closeBoxURL_ + "'";
    img += " align=right"; // Do this because Opera chokes on style='float: right;'
    img += " style='";
    img += " z-index:1000; position: relative;"; // Required by MSIE
    img += " cursor: pointer;";
    img += " margin: " + this.closeBoxMargin_ + ";";
    img += "' width='14' height='13'>";
  }

  return img;
};

/**
 * Adds the click handler to the InfoBox close box.
 * @private
 */
InfoBox.prototype.addClickHandler_ = function () {

  var closeBox;

  if (this.closeBoxURL_ !== "") {

    closeBox = this.div_.firstChild;
    this.closeListener_ = google.maps.event.addDomListener(closeBox, 'click', this.getCloseClickHandler_());
		
  } else {

    this.closeListener_ = null;
  }
};

/**
 * Returns the function to call when the user clicks the close box of an InfoBox.
 * @private
 */
InfoBox.prototype.getCloseClickHandler_ = function () {

  var me = this;

  return function (e) {

    // 1.0.3 fix: Always prevent propagation of a close box click to the map:
    e.cancelBubble = true;

    if (e.stopPropagation) {

      e.stopPropagation();
    }
	
    me.close();

    /**
     * This event is fired when the InfoBox's close box is clicked.
     * @name InfoBox#closeclick
     * @event
     */
    google.maps.event.trigger(me, "closeclick");
  };
};

/**
 * Pans the map so that the InfoBox appears entirely within the map's visible area.
 * @private
 */
InfoBox.prototype.panBox_ = function (disablePan) {

  var map;
  var bounds;
  var xOffset = 0, yOffset = 0;

  if (!disablePan) {

    map = this.getMap();

    if (!map.getBounds().contains(this.position_)) {
    // Marker not in visible area of map, so set center
    // of map to the marker position first.
      map.setCenter(this.position_);
    }

    bounds = map.getBounds();

    var mapDiv = map.getDiv();
    var mapWidth = mapDiv.offsetWidth;
    var mapHeight = mapDiv.offsetHeight;
    var iwOffsetX = this.pixelOffset_.width;
    var iwOffsetY = this.pixelOffset_.height;
    var iwWidth = this.div_.offsetWidth;
    var iwHeight = this.div_.offsetHeight;
    var padX = this.infoBoxClearance_.width;
    var padY = this.infoBoxClearance_.height;
    var pixPosition = this.getProjection().fromLatLngToContainerPixel(this.position_);

    if (pixPosition.x < (-iwOffsetX + padX)) {
      xOffset = pixPosition.x + iwOffsetX - padX;
    } else if ((pixPosition.x + iwWidth + iwOffsetX + padX) > mapWidth) {
      xOffset = pixPosition.x + iwWidth + iwOffsetX + padX - mapWidth;
    }
    if (this.alignBottom_) {
      if (pixPosition.y < (-iwOffsetY + padY + iwHeight)) {
        yOffset = pixPosition.y + iwOffsetY - padY - iwHeight;
      } else if ((pixPosition.y + iwOffsetY + padY) > mapHeight) {
        yOffset = pixPosition.y + iwOffsetY + padY - mapHeight;
      }
    } else {
      if (pixPosition.y < (-iwOffsetY + padY)) {
        yOffset = pixPosition.y + iwOffsetY - padY;
      } else if ((pixPosition.y + iwHeight + iwOffsetY + padY) > mapHeight) {
        yOffset = pixPosition.y + iwHeight + iwOffsetY + padY - mapHeight;
      }
    }

    if (!(xOffset === 0 && yOffset === 0)) {

      // Move the map to the shifted center.
      //
      var c = map.getCenter();
      map.panBy(xOffset, yOffset);
    }
  }
};

/**
 * Sets the style of the InfoBox by setting the style sheet and applying
 * other specific styles requested.
 * @private
 */
InfoBox.prototype.setBoxStyle_ = function () {

  var i, boxStyle;

  if (this.div_) {

    // Apply style values from the style sheet defined in the boxClass parameter:
    this.div_.className = this.boxClass_;

    // Clear existing inline style values:
    this.div_.style.cssText = "";

    // Apply style values defined in the boxStyle parameter:
    boxStyle = this.boxStyle_;
    for (i in boxStyle) {

      if (boxStyle.hasOwnProperty(i)) {

        this.div_.style[i] = boxStyle[i];
      }
    }

    // Fix up opacity style for benefit of MSIE:
    //
    if (typeof this.div_.style.opacity !== "undefined" && this.div_.style.opacity !== "") {

      this.div_.style.filter = "alpha(opacity=" + (this.div_.style.opacity * 100) + ")";
    }

    // Apply required styles:
    //
    this.div_.style.position = "absolute";
    this.div_.style.visibility = 'hidden';
    if (this.zIndex_ !== null) {

      this.div_.style.zIndex = this.zIndex_;
    }
  }
};

/**
 * Get the widths of the borders of the InfoBox.
 * @private
 * @return {Object} widths object (top, bottom left, right)
 */
InfoBox.prototype.getBoxWidths_ = function () {

  var computedStyle;
  var bw = {top: 0, bottom: 0, left: 0, right: 0};
  var box = this.div_;

  if (document.defaultView && document.defaultView.getComputedStyle) {

    computedStyle = box.ownerDocument.defaultView.getComputedStyle(box, "");

    if (computedStyle) {

      // The computed styles are always in pixel units (good!)
      bw.top = parseInt(computedStyle.borderTopWidth, 10) || 0;
      bw.bottom = parseInt(computedStyle.borderBottomWidth, 10) || 0;
      bw.left = parseInt(computedStyle.borderLeftWidth, 10) || 0;
      bw.right = parseInt(computedStyle.borderRightWidth, 10) || 0;
    }

  } else if (document.documentElement.currentStyle) { // MSIE

    if (box.currentStyle) {

      // The current styles may not be in pixel units, but assume they are (bad!)
      bw.top = parseInt(box.currentStyle.borderTopWidth, 10) || 0;
      bw.bottom = parseInt(box.currentStyle.borderBottomWidth, 10) || 0;
      bw.left = parseInt(box.currentStyle.borderLeftWidth, 10) || 0;
      bw.right = parseInt(box.currentStyle.borderRightWidth, 10) || 0;
    }
  }

  return bw;
};

/**
 * Invoked when <tt>close</tt> is called. Do not call it directly.
 */
InfoBox.prototype.onRemove = function () {

  if (this.div_) {

    this.div_.parentNode.removeChild(this.div_);
    this.div_ = null;
  }
};

/**
 * Draws the InfoBox based on the current map projection and zoom level.
 */
InfoBox.prototype.draw = function () {

  this.createInfoBoxDiv_();

  var pixPosition = this.getProjection().fromLatLngToDivPixel(this.position_);

  this.div_.style.left = (pixPosition.x + this.pixelOffset_.width) + "px";
  
  if (this.alignBottom_) {
    this.div_.style.bottom = -(pixPosition.y + this.pixelOffset_.height) + "px";
  } else {
    this.div_.style.top = (pixPosition.y + this.pixelOffset_.height) + "px";
  }

  if (this.isHidden_) {

    this.div_.style.visibility = 'hidden';

  } else {

    this.div_.style.visibility = "visible";
  }
};

/**
 * Sets the options for the InfoBox. Note that changes to the <tt>maxWidth</tt>,
 *  <tt>closeBoxMargin</tt>, <tt>closeBoxURL</tt>, and <tt>enableEventPropagation</tt>
 *  properties have no affect until the current InfoBox is <tt>close</tt>d and a new one
 *  is <tt>open</tt>ed.
 * @param {InfoBoxOptions} opt_opts
 */
InfoBox.prototype.setOptions = function (opt_opts) {
  if (typeof opt_opts.boxClass !== "undefined") { // Must be first

    this.boxClass_ = opt_opts.boxClass;
    this.setBoxStyle_();
  }
  if (typeof opt_opts.boxStyle !== "undefined") { // Must be second

    this.boxStyle_ = opt_opts.boxStyle;
    this.setBoxStyle_();
  }
  if (typeof opt_opts.content !== "undefined") {

    this.setContent(opt_opts.content);
  }
  if (typeof opt_opts.disableAutoPan !== "undefined") {

    this.disableAutoPan_ = opt_opts.disableAutoPan;
  }
  if (typeof opt_opts.maxWidth !== "undefined") {

    this.maxWidth_ = opt_opts.maxWidth;
  }
  if (typeof opt_opts.pixelOffset !== "undefined") {

    this.pixelOffset_ = opt_opts.pixelOffset;
  }
  if (typeof opt_opts.position !== "undefined") {

    this.setPosition(opt_opts.position);
  }
  if (typeof opt_opts.zIndex !== "undefined") {

    this.setZIndex(opt_opts.zIndex);
  }
  if (typeof opt_opts.closeBoxMargin !== "undefined") {

    this.closeBoxMargin_ = opt_opts.closeBoxMargin;
  }
  if (typeof opt_opts.closeBoxURL !== "undefined") {

    this.closeBoxURL_ = opt_opts.closeBoxURL;
  }
  if (typeof opt_opts.infoBoxClearance !== "undefined") {

    this.infoBoxClearance_ = opt_opts.infoBoxClearance;
  }
  if (typeof opt_opts.isHidden !== "undefined") {

    this.isHidden_ = opt_opts.isHidden;
  }
  if (typeof opt_opts.enableEventPropagation !== "undefined") {

    this.enableEventPropagation_ = opt_opts.enableEventPropagation;
  }

  if (this.div_) {

    this.draw();
  }
};

/**
 * Sets the content of the InfoBox.
 *  The content can be plain text or an HTML DOM node.
 * @param {string|Node} content
 */
InfoBox.prototype.setContent = function (content) {
  this.content_ = content;

  if (this.div_) {

    if (this.closeListener_) {

      google.maps.event.removeListener(this.closeListener_);
      this.closeListener_ = null;
    }

    // Odd code required to make things work with MSIE.
    //
    if (!this.fixedWidthSet_) {

      this.div_.style.width = "";
    }

    if (typeof content.nodeType === "undefined") {
      this.div_.innerHTML = this.getCloseBoxImg_() + content;
    } else {
      this.div_.innerHTML = this.getCloseBoxImg_();
      this.div_.appendChild(content);
    }

    // Perverse code required to make things work with MSIE.
    // (Ensures the close box does, in fact, float to the right.)
    //
    if (!this.fixedWidthSet_) {

      this.div_.style.width = this.div_.offsetWidth + "px";
      this.div_.innerHTML = this.getCloseBoxImg_() + content;
    }

    this.addClickHandler_();
  }

  /**
   * This event is fired when the content of the InfoBox changes.
   * @name InfoBox#content_changed
   * @event
   */
  google.maps.event.trigger(this, "content_changed");
};

/**
 * Sets the geographic location of the InfoBox.
 * @param {LatLng} latlng
 */
InfoBox.prototype.setPosition = function (latlng) {

  this.position_ = latlng;

  if (this.div_) {

    this.draw();
  }

  /**
   * This event is fired when the position of the InfoBox changes.
   * @name InfoBox#position_changed
   * @event
   */
  google.maps.event.trigger(this, "position_changed");
};

/**
 * Sets the zIndex style for the InfoBox.
 * @param {number} index
 */
InfoBox.prototype.setZIndex = function (index) {

  this.zIndex_ = index;

  if (this.div_) {

    this.div_.style.zIndex = index;
  }

  /**
   * This event is fired when the zIndex of the InfoBox changes.
   * @name InfoBox#zindex_changed
   * @event
   */
  google.maps.event.trigger(this, "zindex_changed");
};

/**
 * Returns the content of the InfoBox.
 * @returns {string}
 */
InfoBox.prototype.getContent = function () {

  return this.content_;
};

/**
 * Returns the geographic location of the InfoBox.
 * @returns {LatLng}
 */
InfoBox.prototype.getPosition = function () {

  return this.position_;
};

/**
 * Returns the zIndex for the InfoBox.
 * @returns {number}
 */
InfoBox.prototype.getZIndex = function () {

  return this.zIndex_;
};

/**
 * Shows the InfoBox.
 */
InfoBox.prototype.show = function () {

  this.isHidden_ = false;
  this.div_.style.visibility = "visible";
};

/**
 * Hides the InfoBox.
 */
InfoBox.prototype.hide = function () {

  this.isHidden_ = true;
  this.div_.style.visibility = "hidden";
};

/**
 * Adds the InfoBox to the specified map. If <tt>anchor</tt>
 *  (usually a <tt>google.maps.Marker</tt>) is specified, the position
 *  of the InfoBox is set to the position of the <tt>anchor</tt>. If the
 *  anchor is dragged to a new location, the InfoBox moves as well.
 * @param {Map} map
 * @param {MVCObject} [anchor]
 */
InfoBox.prototype.open = function (map, anchor) {

  var me = this;

  if (anchor) {

    this.position_ = anchor.getPosition();
    this.moveListener_ = google.maps.event.addListener(anchor, "position_changed", function () {
      me.setPosition(this.getPosition());
    });
  }

  this.setMap(map);

  if (this.div_) {

    this.panBox_();
  }
};

/**
 * Removes the InfoBox from the map.
 */
InfoBox.prototype.close = function () {

  if (this.closeListener_) {

    google.maps.event.removeListener(this.closeListener_);
    this.closeListener_ = null;
  }

  if (this.eventListener1_) {

    google.maps.event.removeListener(this.eventListener1_);
    google.maps.event.removeListener(this.eventListener2_);
    google.maps.event.removeListener(this.eventListener3_);
    this.eventListener1_ = null;
    this.eventListener2_ = null;
    this.eventListener3_ = null;
  }

  if (this.moveListener_) {

    google.maps.event.removeListener(this.moveListener_);
    this.moveListener_ = null;
  }

  if (this.contextListener_) {

    google.maps.event.removeListener(this.contextListener_);
    this.contextListener_ = null;
  }

  this.setMap(null);
};

//******************************CURVED CORNERS IE

