//<![CDATA[

function getQueryVariables() {
  var query = window.location.search.substring(1);
  var vars = query.split("&");
  var pair = vars[0].split("=");
  return query;
}

function DynoMap(_id, _flashNavigationPath, _flashOverlayPath, _mapId, _navigationId, _overlayId) { 
	// only _id is required at constructor time
	//window.yui = 'undefined'==window.yui ? 0 : window.yui;
	this.container = null; 
	this.map = null;
	this.navigation = null;
	this.overlay = null;
	this.gmap = null; // the google map
	
	this.flashOverlayPath = _flashOverlayPath;
	this.flashNavigationPath = _flashNavigationPath;
	this.flashOverlayId = null;
	this.flashNavigationId = null;
	this.flashNavigation = null;
	this.flashBubble = null;
	
	this.startCoordinates = { };
	this.dimensions = { };
	this.startCoordinates.latitude = 0;
	this.startCoordinates.longitude = 0;
	this.dimensions.width = 747;
	this.dimensions.height = 395;
	this.anchorOffsetPercentageLat = 0.1; // % of height from center to move - -> up,   + -> down
	this.anchorOffsetPercentageLong = 0.355; // % of width  from center to move - -> left, + -> right
	this.initialZoomLevel = 11;
	this.zoomLevel = 16;
	
	this.locationsXML = "locations.xml";
	this.localXMLLoadEnabled = false;
	this.loggingEnabled = false;
		
	// constructor code
	/***
	 add clean style-free root element to root element specified so that 
	 positioning is not affected by specified root element style
	***/
	this.generateId = function() {
		return YAHOO.util.Dom.generateId(null,"dmgen");
	};
	
	var innerHTML = "";
	this.container = null != _id ? YAHOO.util.Dom.get(_id) : null; 
	if(null == this.container) {
		// create a root element if it doesn't exist ... but warn
		alert("The container element with id=\"" + _id + "\" for the map does not exist!");
		this.container = document.body.appendChild(document.createElement("div"));		
	} else {
		// copy contents and reset element
		// this is to guarantee proper layout of map and overlay and nav
		// but still allow for graceful fallback if flash doesn't load
		innerHTML = this.container.innerHTML;
		this.container.innerHTML = "";
	}
	this.container = this.container.appendChild(document.createElement("div"));
	this.container.id = this.generateId();
	this.container = YAHOO.util.Dom.get(this.container.id);
	this.container.innerHTML = innerHTML;
	
	this.map = null!=_mapId ? YAHOO.util.Dom.get(_mapId) : null;
	if(null!=this.map) {
		innerHTML = this.map.innerHTML;
		this.map.innerHTML = "";
	}
	this.map = this.container.appendChild(document.createElement("div"));
	this.map.id = this.generateId();
	this.map = YAHOO.util.Dom.get(this.map.id);
	this.map.innerHTML = innerHTML;
	
	this.navigation = null!=_navigationId ? YAHOO.util.Dom.get(_navigationId) : null;
	if(null!=this.navigation) {
		innerHTML = this.navigation.innerHTML;
		this.navigation.innerHTML = "";
	}
	this.navigation = this.container.appendChild(document.createElement("div"));
	this.navigation.id = this.generateId();
	this.navigation = YAHOO.util.Dom.get(this.navigation.id);
	this.navigation.innerHTML = innerHTML;
		
	this.overlay = null!=_overlayId ? YAHOO.util.Dom.get(_overlayId) : null;
	if(null!=this.overlay) {
		innerHTML = this.overlay.innerHTML;
		this.overlay.innerHTML = "";
	}
	this.overlay = this.container.appendChild(document.createElement("div"));
	this.overlay.id = this.generateId();
	this.overlay = YAHOO.util.Dom.get(this.overlay.id);
	this.overlay.innerHTML = innerHTML;
	
	// flash callbacks visible at global scope
	window.gmap = this;	
	window.moveToMarker = function(_id) {
		gmap.moveToMarker(_id);
	};
	window.hideOverlay = function() {
		gmap.hideOverlay();
	};
	window.showOverlay = function() {
		gmap.showOverlay();
	};
	
	// end constructor
	
	// main method
	this.start = function() {
		
		if(this.loggingEnabled) { 
			this._startLogger();
			this._showLogging();
		}
		this._initFlashElements();
		this._initElementPositions();
		this._initGoogleMap();
		YAHOO.log("Getting XML data from " + this.locationsXML);
		YAHOO.util.Connect.asyncRequest('GET',this.locationsXML,this.asyncHandler,null);
	};
	
	// accessor methods
	this.setMapElement = function(_id) {
		this.map = YAHOO.util.Dom.get(_id);
	};
	this.getMapElement = function() { 
		return this.map; 
	};
	
	this.setNavigationElement = function(_id) {
		this.navigation = YAHOO.util.Dom.get(_id);
	};
	this.getNavigationElement = function() { 
		return this.navigation; 
	}; 
	
	this.setOverlayElement = function(_id) {
		this.overlay = YAHOO.util.Dom.get(_id);
	};
	this.getOverlayElement = function() { 
		return this.overlay; 
	}; 
	
	this.setMapCoordinates = function(_latitude,_longitude) {
		this.startCoordinates.latitude = _latitude;
		this.startCoordinates.longitude = _longitude;
	}; 
	
	this.setMapDimensions = function(_width,_height) {
		this.dimensions.width = _width;
		this.dimensions.height = _height;
	};
	
	this.setAnchorOffsetPercentage = function(_lat,_long) {
		this.anchorOffsetPercentageLat = _lat;
		this.anchorOffsetPercentageLong = _long;
	};
	
	this.setMap = function(_map) {
		this.gmap = _map;
	};
	
	this.getMap = function() {
		return this.gmap;
	};
	
	this.setLocationsXMLPath = function(_path) {
		this.locationsXML = _path;
	};
	
	this.getLocationsXMLPath = function() {
		return this.locationsXML;
	};
	
	this.getFlashNavigationId = function() {
		this.flashNavigationId = this.generateId();
		YAHOO.log("Generated id=" + this.flashNavigationId + " for flashNavigation.");
		return this.flashNavigationId;
	};
	
	this.getFlashOverlayId = function() {
		this.flashOverlayId = this.generateId();
		YAHOO.log("Generated id=" + this.flashOverlayId + " for flashOverlay.");
		return this.flashOverlayId;
	};
	
	this.parseXMLText = function(_text) {
		YAHOO.log("Parsing xml text.");
		if (YAHOO.util.isIE) {
			var doc=new ActiveXObject("Microsoft.XMLDOM");
			doc.async="false";
			doc.loadXML(_text);
			return doc;
		} else {
			var parser=new DOMParser();
			var doc=parser.parseFromString(_text,"text/xml");
			return doc;
		}
	};
	
	this.hideOverlay = function() {
		YAHOO.log("Hiding overlay");
		YAHOO.util.Dom.setStyle(this.overlay,"z-index","-1");
	};
	
	this.showOverlay = function() {
		YAHOO.log("Showing overlay");
		YAHOO.util.Dom.setStyle(this.overlay,"z-index","10");
	};
	
	this._startLogger = function() {
		this.logElement = document.body.appendChild(document.createElement("div"));
		this.log = new YAHOO.widget.LogReader(this.logElement,{verboseOutput:false});
		var le = this.logElement;
		YAHOO.log("Setting LogReader style.");
		YAHOO.util.Dom.setStyle(le,"display","block");
		YAHOO.util.Dom.setStyle(le,"position","absolute");
		YAHOO.util.Dom.setStyle(le,"width","1px");
		YAHOO.util.Dom.setStyle(le,"height","1px");
		YAHOO.util.Dom.setStyle(le,"overflow","hidden");
		YAHOO.util.Dom.setStyle(le,"top",YAHOO.util.Dom.getY(this.container)+"px");
		YAHOO.util.Dom.setStyle(le,"left",YAHOO.util.Dom.getX(this.container)+"px");
		YAHOO.util.Dom.setStyle(le,"font-size","11px");
		
		le.id = this.generateId();
		YAHOO.log("Generated id for log element id="+ le.id);
	};
	
	this._showLogging = function() {
		var le = this.logElement;
		
		YAHOO.util.Dom.setStyle(le,"width","500px");
		YAHOO.util.Dom.setStyle(le,"height","300px");
		YAHOO.util.Dom.setStyle(le,"overflow","scroll");
		YAHOO.util.Dom.setStyle(le,"top","10px");
		YAHOO.util.Dom.setStyle(le,"left","10px");
		YAHOO.util.Dom.setStyle(le,"border","1px solid black");
		YAHOO.util.Dom.setStyle(le,"background","white");
		YAHOO.util.Dom.setStyle(le,"opacity",".7");
		YAHOO.util.Dom.setStyle(le,"filter","alpha(opacity=70)");
		YAHOO.log("Setting Drag and Drop on log element.");
		var dd = new YAHOO.util.DD(le);
	};
	
	this.enableLogging = function() {
		this.loggingEnabled = true;
	};
	
	this.enableLocalXMLLoad = function() {
		this.localXMLLoadEnabled = true;
	};
	
	this.setInitialZoomLevel = function(_level) {
		this.initialZoomLevel = Math.round(_level / 5 );
	};
	
	this.setDefaultZoomLevel = function(_level) {
		this.zoomLevel = Math.round(_level / 5);
	};
	
	// init functions
	this._initGoogleMap = function () {
		// initialize the google map so that it starts to render on screen.
		// this can also be added to the init function.
		YAHOO.log("initGoogleMap");
		if(0 == this.startCoordinates.latitude && 0 == this.startCoordinates.longitude) 
			alert("You need to initialize the map with start coordinates!");
		if (GBrowserIsCompatible()) {
	    	this.gmap = new GMap2(this.map);
  			this.gmap.addControl(new GLargeMapControl(),new GControlPosition(G_ANCHOR_TOP_LEFT, new GSize(10, 50)));
  			this.gmap.addControl(new GMapTypeControl());
			this.gmap.setCenter(new GLatLng(this.startCoordinates.latitude,this.startCoordinates.longitude), this.initialZoomLevel);
			this.gmap.setMapType(G_SATELLITE_MAP);
			this.gmap.enableContinuousZoom();
		}
	};
	
	this._initElementPositions = function() {
		
		// map	
		YAHOO.log("initElementPositions");
		YAHOO.util.Dom.setStyle(this.container,"position","relative");
		
		YAHOO.util.Dom.setStyle(this.map,"position","absolute");
		YAHOO.util.Dom.setStyle(this.map,"z-index","9");
		YAHOO.util.Dom.setStyle(this.map,"width",this.dimensions.width+"px");
		YAHOO.util.Dom.setStyle(this.map,"height",this.dimensions.height+"px");
		YAHOO.util.Dom.setX(this.map,YAHOO.util.Dom.getX(this.container));
		YAHOO.util.Dom.setY(this.map,YAHOO.util.Dom.getY(this.container));
		
		// bubble overlay
		YAHOO.util.Dom.setStyle(this.overlay,"position","absolute");
		YAHOO.util.Dom.setStyle(this.overlay,"width",this.dimensions.width+"px");
		YAHOO.util.Dom.setStyle(this.overlay,"height",this.dimensions.height+"px");
		YAHOO.util.Dom.setX(this.overlay,YAHOO.util.Dom.getX(this.container));
		YAHOO.util.Dom.setY(this.overlay,YAHOO.util.Dom.getY(this.container));
		this.hideOverlay();
		
		// navigation
		YAHOO.util.Dom.setStyle(this.navigation,"position","absolute");
		YAHOO.util.Dom.setX(this.navigation,YAHOO.util.Dom.getX(this.map));
		YAHOO.util.Dom.setY(this.navigation,YAHOO.util.Dom.getRegion(this.map).bottom);
		YAHOO.util.Dom.setStyle(this.navigation,"width",this.dimensions.width+"px");
		
		// set dimensions of container
		YAHOO.util.Dom.setStyle(this.container,"width",this.dimensions.width+"px");
		
		var region = YAHOO.util.Dom.getRegion(this.navigation);
		YAHOO.log("Navigation Position top:"+region.top+" bottom:"+region.bottom+" left:"+region.left+" right:"+region.right+";");
		YAHOO.util.Dom.setStyle(this.container,"height",(this.dimensions.height+region.bottom-region.top)+"px");
	};
	
	this._initFlashElements = function() {
		// better place for this would be in the divs 
		YAHOO.log("initFlashElements");
		var navigationHeight = 96;
		var timestamp = new Date().getTime();
		
		if(null!=this.flashNavigationPath) {
			var so2 = new SWFObject(this.flashNavigationPath, this.getFlashNavigationId(), this.dimensions.width, navigationHeight, "8", "#000000");
			so2.addParam("wmode", "transparent");
			so2.addParam("menu", "false");
			so2.addVariable("connectionId",timestamp);
			so2.addVariable("xmlPath", this.locationsXML);
			so2.write(this.getNavigationElement());
		} 
		
		if(null!=this.flashOverlayPath) {
			var so1 = new SWFObject(this.flashOverlayPath, this.getFlashOverlayId(), this.dimensions.width, this.dimensions.height, "8", "#000000");
			so1.addParam("wmode", "transparent");
			so1.addParam("menu", "false");
			so1.addVariable("connectionId",timestamp);
			so1.write(this.getOverlayElement());
		}
	};
	
	this._addGoogleMapMarker = function(_point,_icon) {
	};
	
	var args = { dynomapInstance: this };
	this.asyncHandler = {
		success: function(o) {
			YAHOO.log("XML Request Successful");
			
			var locations = o.responseXML.getElementsByTagName("location");
			YAHOO.log("Number of locations: " + locations.length);
			for(i=0;i<locations.length;i++) {
				var icon = null, point = null, marker = null, elementIndex = i+1,
					locationId = locations.item(i).getAttribute("id");
					
				// create the icon
				icon = new GIcon();
				icon.image = locations.item(i).getAttribute("iconPath");
		        icon.shadow = locations.item(i).getAttribute("iconShadowPath");
		        icon.iconSize = new GSize(parseFloat(locations.item(i).getAttribute("iconWidth")), 
		        					parseFloat(locations.item(i).getAttribute("iconHeight")));
		        icon.shadowSize = new GSize(parseFloat(locations.item(i).getAttribute("iconShadowWidth")), 
		        					parseFloat(locations.item(i).getAttribute("iconShadowHeight")));
		        icon.iconAnchor = new GPoint(parseFloat(locations.item(i).getAttribute("iconAnchorX")), 
		        					parseFloat(locations.item(i).getAttribute("iconAnchorY")));
		        icon.transparent = locations.item(i).getAttribute("transparentURL");
		        icon.infoWindowAnchor = new GPoint(5, 1);
				
				// create a point on map for icon
				point = new GLatLng(parseFloat(locations.item(i).getAttribute("lat")), 
							parseFloat(locations.item(i).getAttribute("lng")));
				
				// create a marker 
				o.argument.dynomapInstance.addMarker(point,icon,elementIndex,locationId,locations.item(i).getAttribute("name"));
			}

			//hack to fix player overlay not displaying on first click
			if(!YAHOO.util.isIE) {
				o.argument.dynomapInstance.showOverlay();
				window.setTimeout(window.hideOverlay,1000);
			}
			//end hack
		},
		
		failure: function(o) {
			YAHOO.log("Couldn't load XML data from " + o.argument.dynomapInstance.locationsXML,"error");
			
			if(!o.argument.dynomapInstance.localXMLLoadEnabled) return;
			
			var elementIndex = 0;
			var doc = o.argument.dynomapInstance.parseXMLText(altXMLDoc).documentElement;
			for(i=0;i<doc.childNodes.length;i++) {
				
				if(1==doc.childNodes[i].nodeType) {
					elementIndex++;
					var icon = null, point = null,
						location = doc.childNodes[i].attributes;
					var locationId = location.getNamedItem("id").value;
					
					// create the icon
					icon = new GIcon();
					icon.image = location.getNamedItem("iconPath").value;
			        icon.shadow = location.getNamedItem("iconShadowPath").value;
			        icon.iconSize = new GSize(parseFloat(location.getNamedItem("iconWidth").value), 
			        					parseFloat(location.getNamedItem("iconHeight").value));
			        icon.shadowSize = new GSize(parseFloat(location.getNamedItem("iconShadowWidth").value), 
			        					parseFloat(location.getNamedItem("iconShadowHeight").value));
			        icon.iconAnchor = new GPoint(parseFloat(location.getNamedItem("iconAnchorX").value), 
			        					parseFloat(location.getNamedItem("iconAnchorY").value));
			        icon.transparent = location.getNamedItem("transparentURL").value;
			        icon.infoWindowAnchor = new GPoint(5, 1);
					
					// create a point on map for icon
					point = new GLatLng(parseFloat(location.getNamedItem("lat").value), 
								parseFloat(location.getNamedItem("lng").value));
					
					// add the marker to the map
					o.argument.dynomapInstance.addMarker(point,icon,elementIndex,locationId,location.getNamedItem("name").value);
				}
			}
			//hack to fix player overlay not displaying on first click
			if(!YAHOO.util.isIE) {
				o.argument.dynomapInstance.showOverlay();
				window.setTimeout(window.hideOverlay,7000);
			}
			//end hack
		},
		argument: args 
	};
	
	this.addMarker = function(_point,_icon,_elementIndex,_locationId,_locationName) {
		// create a marker
		var map = this.gmap;
		YAHOO.log("Adding marker: " + _elementIndex + "," + 
			_locationId + "," + _locationName + ".");
		try {
			map["marker" + _elementIndex] = this.createMarker(_point,_icon,_elementIndex);
			map["marker" + _elementIndex].myId = _locationId;
	        map["marker" + _elementIndex].lat  = _point.lat();
	        map["marker" + _elementIndex].lng  = _point.lng();
        	map.addOverlay(map["marker" + _elementIndex]);
        	YAHOO.log("Added marker: " + _elementIndex + "," + 
				_locationId + "," + _point.lat() + "," + _point.lng());
		} catch (e) {
			YAHOO.log("Couldn't add marker " + _elementIndex + " to the map!","error");
		}
	};
	
	this.createMarker = function(_point, _icon, _elementIndex) {
		var marker = new GMarker(_point,_icon);
		marker.dynomapInstance = this;
		marker.elementIndex = _elementIndex;
		
		// add action listeners to marker			
		GEvent.addListener(marker, "click", function() {
			YAHOO.log("Clicked marker " + marker.elementIndex + " at (" + marker.lat + "," + marker.lng + ")" );
			if(marker.dynomapInstance.initialZoomLevel==marker.dynomapInstance.gmap.getZoom() && 
				marker.dynomapInstance.zoomLevel!=marker.dynomapInstance.initialZoomLevel) {
				marker.dynomapInstance.initialZoomLevel = marker.dynomapInstance.zoomLevel; 
				marker.dynomapInstance.gmap.setZoom(marker.dynomapInstance.zoomLevel);
			}
			marker.dynomapInstance.hideOverlay();
			marker.dynomapInstance.showOverlay();
			marker.dynomapInstance.gmap.savePosition();
			marker.dynomapInstance.moveForInfo(marker.lat, marker.lng);
			marker.dynomapInstance.callExternalInterface(marker.elementIndex);
			marker.dynomapInstance.startDisplay();
			
			YAHOO.log("Mapped marker " + marker.dynomapInstance.gmap["marker"+(marker.elementIndex)].myId + 
						" at (" + marker.dynomapInstance.gmap["marker"+(marker.elementIndex)].lat + 
						"," + marker.dynomapInstance.gmap["marker"+(marker.elementIndex)].lng + ")" ); 
		});
		GEvent.addListener(marker, "infowindowclose", function() {
			YAHOO.log("infowindowclose called on marker " + marker.elementIndex);
    		marker.dynomapInstance.hideOverlay();
			marker.dynomapInstance.gmap.returnToSavedPosition();
	    });
	    
	    return marker;
	};
	//CALL EXTERNAL INTERFACE ON MEDIA DISPLAY
	this.startDisplay = function() {
		if(null == this.flashOverlay) {
			YAHOO.log("Setting flashOverlay reference " + this.flashOverlayId);
			this.flashOverlay = YAHOO.util.Dom.get(this.flashOverlayId);
		}
		YAHOO.log("Calling flashOverlay");
		try {
			this.flashOverlay.startDisplay();
		} catch(e) {
			YAHOO.log("overlay.startDisplay() is not a function","error");
		}
  	};
  	
	this.callExternalInterface = function(_id) {
		if(null == this.flashNavigation) {
			YAHOO.log("Setting flashNavigation reference " + this.flashNavigationId);
			this.flashNavigation = YAHOO.util.Dom.get(this.flashNavigationId);
		}
		YAHOO.log("Calling flashNavigation reference releaseThumb for " + _id);
  		this.flashNavigation.releaseThumb(_id);
  	};
  	
  	this.moveToMarker = function(_id) { 
  		var marker = this.gmap["marker"+_id];
	    var markerLoc = new GLatLng(marker.lat, marker.lng);
	    YAHOO.log("Moving marker " + _id + " to (" + marker.lat + "," + marker.lng + ").");
	    this.gmap.panTo(markerLoc);
		GEvent.trigger(marker, "click");
  	};
  	
  	this.moveForInfo = function(_lat, _lng) {
	    this.gmap.panTo(this.getCenterForInfo(_lat, _lng));
  	};
  	
  	this.getCenterForInfo = function(_lat, _lng) {
  		var b     = this.gmap.getBounds();
	    var ne    = b.getNorthEast();
	    var sw    = b.getSouthWest();
	    var dlng  = ne.lng() - sw.lng();
	    var dlat  = sw.lat() - ne.lat(); 
	    newLat    = _lat - (dlat * this.anchorOffsetPercentageLat);
	    newLng    = _lng - (dlng * this.anchorOffsetPercentageLong);
	    return (new GLatLng(newLat, newLng));
	};
};
	// ]]>

