// vim: sw=4:ts=4:nu:nospell

/**
 * HyperCities mainMap Objects
 *
 * @author    Chen-Kuei Lee
 * @copyright (c) 2008, by HyperCities Tech Team
 * @date      2008-12-22
 * @version   0.7
 *
 */

// create applicatio namespace
HyperCities.mainMap = function() {

	// do NOT acces
        //
        // s javascript generated DOM from here; elements don't exist yet
	var DEFAULT_TYPE   = "GraphicsMagick";
	var QUAD_TYPE      = "MapCruncher";
	var _id            = "[HyperCities.mainMap] ";
	//var _defaultLat  = 25.482951;
	var _defaultLat    = 0;
	//var _defaultLng    = -37.265625;
	var _defaultLng    = 0;
	var _defaultZoom   = { world: 2, city: 14};
	//the view region should be shown when map is loaded first time
	var _defaultViewport = new GLatLngBounds(new GLatLng(-50, -140), new GLatLng(60, 150));
	var _mapTypes      = [G_SATELLITE_MAP, G_NORMAL_MAP, G_HYBRID_MAP, G_PHYSICAL_MAP, G_SATELLITE_3D_MAP];
	var _defaultMap    = G_SATELLITE_MAP;
	var _mainListeners = [];
	var _cityListeners = [];
	var _cityMarkers   = [];
	var _GInfoPanel    = new GInfoPanel();
	var _GProgressbar  = null;
	var _enableSync    = true;	//enable map auto refresh
	var _GAddMediaControl;// = new AddMediaControl();
	var _GClearMapControl;
        var _GSaveSnapshotControl;

	var _GMap;
	var _geocoder;
	var _lat;
	var _lng;
	var _center;
	var _zoom;
	var _minTime;
	var _maxTime;
	var _GMapUI;


	var _tileToQuadKey = function($x, $y, $zoom) {
		var mask, cell, quad = "";

		for (var i = $zoom ; i > 0 ; i--) {
			mask = 1 << (i - 1);
			cell = 0;
			if (($x & mask) != 0)
				cell++;
			if (($y & mask) != 0)
				cell += 2;
			quad += cell;
		}

		return quad;
	};

	var _getTileUrl = function($map) {
		var tileType = $map.tileType;
		var tileUrl  = $map.tileUrl;
		var tileHost = tileUrl.split(/\/+/g)[1];

		if ( tileType === DEFAULT_TYPE ) {
			return function ($GPoint, $zoom) {
				var newUrl = tileUrl;
				if ( tileHost === "tiles.ats.ucla.edu") {
					newUrl = newUrl.replace(/tiles\.ats/, "tiles" + ($GPoint.y + $GPoint.x) % 4 + ".ats");
				}

				return newUrl + "/" + $zoom + "/" + $GPoint.x + "/" + $GPoint.y + ".png";
			};
		} else {
			return function ($GPoint, $zoom) {
				var newUrl = tileUrl,
					key = _tileToQuadKey($GPoint.x, $GPoint.y, $zoom);

				if ( tileHost === "tiles.ats.ucla.edu") {
					newUrl = newUrl.replace(/tiles\.ats/, "tiles" + (key%10) % 4 + ".ats");
				}

				return newUrl + "/" + key + ".png";
			};
		}
	};

	// Add Basic Map Listeners to Map
	var _addMainListeners = function() {
		if ( _mainListeners.length != 0) 
			return;

		_mainListeners.push(GEvent.addListener(_GMap, 'dragend', function() {
					_center = _GMap.getCenter();

					if (_enableSync)
					HyperCities.syncSession();

					HyperCities.debug(_id + "Dragend Event: Current Center " + _center);
					}));

		/*        
				  _mainListeners.push(GEvent.addListener(_GMap, 'moveend', function() {
				  _center = _GMap.getCenter();
				  HyperCities.syncSession();
				  HyperCities.debug(_id + "Moveend Event: Current Center " + _center);
				  }));
		 */

		_mainListeners.push(GEvent.addListener(_GMap, 'zoomend', function($oldLevel, $newLevel) {
					_center = _GMap.getCenter();
					_zoom = _GMap.getZoom();

					if ( $oldLevel < HyperCities.config.ZOOM_THRESHOLD && $newLevel >= HyperCities.config.ZOOM_THRESHOLD) {
						//HyperCities.debug(_id + "Enable GoogleBar");
						//_GMap.enableGoogleBar();
						HyperCities.mainMap.removeCities();
					}

					if ( $oldLevel >= HyperCities.config.ZOOM_THRESHOLD && $newLevel < HyperCities.config.ZOOM_THRESHOLD) {
						//HyperCities.debug(_id + "Disable GoogleBar");
						//_GMap.disableGoogleBar();
						// HyperCities.mainMap.removeObjects();
						if ( HyperCities.session.get("mode") === HyperCities.config.MODE_MAP_LIST ) {
							HyperCities.mainMap.addCities(HyperCities.city.getCities());
							HyperCities.debug(_id + "Add City Icon");
						}

						$.each(HyperCities.session.get("map"), function () {
							HyperCities.session.removeMap(this);
						});

					}

					//TODO: show message when zoom level beyound the max/min zoom of tileOverlay
					HyperCities.debug(_id + "Zoomend Event: Current Zoomlevel " + _zoom);  

					//jay: this delay is for earth, so that the 
					//getBounds() and getZoom() can get the new values                  
					if (_enableSync)
						setTimeout("HyperCities.syncSession();", 500);
		}));

		_mainListeners.push(GEvent.addListener(_GMap, 'resize', function() {
					_center = _GMap.getCenter();
					_GInfoPanel.adjustLayout(false);
					HyperCities.debug(_id + "resize Event: Current Center " + _center);
					}));

		//add maptypechanged event listener, Jay
		_mainListeners.push(GEvent.addListener(_GMap, 'maptypechanged', function() {
			HyperCities.debug(_id + "Map type changed Event");
			if (HyperCities.mainMap.getCurrentMapType() === G_SATELLITE_3D_MAP)
			{
				HyperCities.debug("current map: 3d map");
				$("#mapPanelWrapper").hide();
				$("#earthPanelWrapper").show();
				if (HyperCities.earth.getEarth())
				{
					//set a short delay so that syncSession can get correct zoom level
					setTimeout(function() {HyperCities.syncSession()}, 200);
				}
			}
			else
			{
				HyperCities.debug("current map: not a 3d map");
				$("#mapPanelWrapper").show();
				$("#earthPanelWrapper").hide();
				HyperCities.syncSession();
			}
		}));

	};

	// Remove all the Basic Map Listeners
	var _removeMainListeners = function() {
		for (var i = _mainListeners.length - 1 ; i>=0 ; i--) {
			GEvent.removeListener( _mainListeners.pop());
		}
	};

	// Add City Listeners and Overlay to Map
	var _addCity = function($marker, $city, $center, $zoom) {
		//HyperCities.debug(_id + "Add Listener");

		_cityListeners.push(GEvent.addListener($marker, "click", function() {
					HyperCities.debug(_id + "Goto city " + $city.name);
					GEvent.trigger(HyperCities.city.getMarker($city.id), "click");
					}));

		_cityListeners.push(GEvent.addListener($marker, 'mouseover', function() {
					//jay
					$marker.setImage("images/markerCity_over.png");
					//$marker.setImage("images/markerCity.png");
					}));

		_cityListeners.push(GEvent.addListener($marker, 'mouseout', function() {
					$marker.setImage("images/markerCity.png");
					}));

		_cityMarkers.push($marker);
		_GMap.addOverlay($marker);
	};

	// Remove all the City Listeners
	var _removeCityListeners = function() {
		for (var i = _cityListeners.length - 1 ; i>=0 ; i--) {
			GEvent.removeListener( _cityListeners.pop());
		}
	};

	var _initMapPanel = function() {
		$("#mapAutoSync").click(function() {
			if ($("#mapAutoSync").attr('checked'))
			{
				HyperCities.debug(_id + "Enable map auto refresh");
				_enableSync = true;
			}
			else
			{
				HyperCities.debug(_id + "Disable map auto refresh");
				_enableSync = false;
			}
			});
	};

	return {

		// Initialize the Main Google Map
		// $context  : the element ID to render the Google Map
		// $options : are variables that provide initial location and zoom level
		// EX. HyperCities.mainMap.init("#map", {lat:34.070826, lng: -118.463646, zoom:7});
		init: function($context, $options) {

			if (typeof $options === 'undefined') {
				$options={};
			}

			_lat      = isNaN($options.lat) ? _defaultLat : $options.lat;
			_lng      = isNaN($options.lng) ? _defaultLng : $options.lng;
			//this zoom will be modified later
			_zoom     = isNaN($options.zoom) ? _defaultZoom.world : $options.zoom;
			_center   = new google.maps.LatLng( _lat, _lng);
			_GMap     = new google.maps.Map2($($context).get(0), {mapTypes: _mapTypes});
			_geocoder = new GClientGeocoder();

			_GMap.setCenter( _center, _zoom);
			_GProgressbar = new ProgressbarControl(_GMap);
			_GMap.addControl(_GInfoPanel);
			//_GMap.addControl(new GLargeMapControl());
			//_GMap.addControl(new GMenuMapTypeControl());
			
			//show addMediaControl button only if user logged in
			if (HyperCities.user.isLogin())
				HyperCities.mainMap.setAddMediaControl();
			else
				HyperCities.mainMap.removeAddMediaControl();

			_GClearMapControl = new ClearMapControl();
			_GMap.addControl(_GClearMapControl);
                        _GSaveSnapshotControl = new GSaveSnapshotControl();
                        _GMap.addControl(_GSaveSnapshotControl);

			//_GMap.enableScrollWheelZoom();

			_GMap.enableContinuousZoom();

			// Setup New GMap Control
			_GMapUI = _GMap.getDefaultUI();
			_GMapUI.controls.scalecontrol = false;
			_GMapUI.controls.maptypecontrol = false;
			_GMapUI.controls.menumaptypecontrol = true;
			_GMap.setUI(_GMapUI);

			//new GKeyboardHandler( _GMap);

			_GMap.setMapType( _defaultMap);
			_initMapPanel();

			// Put Shadow under Google Mark and Copyright
			$("#GInfoPanel").insertBefore(".gmnoprint:first");
			// Set LinkColor to white 
			/*
			   for ( var i in G_NORMAL_MAP ) {
			   if ( G_NORMAL_MAP[i] == "#7777cc")
			   G_NORMAL_MAP[i] = "#ffffff";
			   }
			 */
			_addMainListeners();

			//test if the GEPlugin is installed
			if (google.earth.isInstalled()) {
				_GMap.getEarthInstance(HyperCities.earth.getEarthInstanceCB);
			}

			//calculate zoom level according to default viewport 
			_zoom = _GMap.getBoundsZoomLevel(_defaultViewport);
			_GMap.setCenter(_center, _zoom);
		},

		// Reset the GMap Type Array to default state
		resetMapType: function() {

			var mapTypeArray = _GMap.getMapTypes();
			var totalTypes   = mapTypeArray.length;
			var initTypes    = _mapTypes.length;

			while ( totalTypes-- > initTypes ) 
				_GMap.removeMapType(mapTypeArray[totalTypes]);

			_GMap.addControl(new GMenuMapTypeControl());
		},

		// This function update _center with given value, but not pan to the new center
		updateCenter: function($center) {
			if ($center instanceof GLatLng) {
				// Set Map Center
				_center = $center;
				_lat    = $center.lat();
				_lng    = $center.lng();
			}
		},
		/**
		 * @method setCenter
		 * @description Center the map to the given GLatLng and Zoomlevel. 
		 * Also update the private variables of HyperCities.mainMap object.
		 * @param {GLatLng} $center The new center.
		 * @param {Number} $zoom (Optional) The new zoom level.
		 * @return {Void}
		 */
		setCenter: function($center, $zoom) {
			var mapType = _GMap.getCurrentMapType(),
				maxZoom = mapType.getMaximumResolution(),
				minZoom = mapType.getMinimumResolution();

			// Handle the optional value, don't change zoomlevel by default
			if (typeof $zoom === "undefined") {
				$zoom = _zoom;
			}

			// Validates params and centers the map 
			if (($center instanceof GLatLng) && (typeof $zoom === "number")) {
                            

				// Set Map Center
				_center = $center;
				_lat    = $center.lat();
				_lng    = $center.lng();

				// Set Map Zoom Level
				if ( $zoom > maxZoom ) {
					_zoom = maxZoom ;
				} 
				else if ( $zoom < minZoom ) {
					_zoom = minZoom ;
				}
				else {
					_zoom = $zoom;
				}

				// Only Zoom to the maximum zoom level at which imagery exists.
				if ( mapType === G_SATELLITE_MAP || mapType === G_HYBRID_MAP ) {
					mapType.getMaxZoomAtLatLng(_center, function (response) {
							if (response && response['status'] == G_GEO_SUCCESS) {
								if ( _zoom > response['zoom'] ) {
									_zoom = response['zoom'];
								}
								_GMap.setCenter(_center, _zoom);
							}
						});
				} else {
					_GMap.setCenter(_center, _zoom);
				}
			}
		},

        /**
         * @method getCenter
         * @description Returns the point at the center of the map.
         * @return {GLatLng}
         */
		getCenter: function() {
			return _center;
		},

		/**
		 * @method searchCenter
		 * @description Centers the map to the given address.
		 * @param {String} $address The location string.
		 * @return {Void}
		 */
		searchCenter: function($address) {
//			HyperCities.debug(_id + "GO Addr : " + $address);
			if (_geocoder) {
				_geocoder.getLocations($address, HyperCities.search.addAddressMarker);
			}
		},

		addMap: function($map, $opacity) {
			//HyperCities.debug(_id + "Add Maps Layer for map_" + $map.id);

			var bounds = new GLatLngBounds(new GLatLng($map.swLat, $map.swLon),
											new GLatLng($map.neLat, $map.neLon));

			// Create GCopyright and GCopyrightCollection 
			var copyright = new GCopyright($map.id, bounds, $map.minZoom, $map.copyright);

			var copyrightCollection = new GCopyrightCollection("HyperCities 2009");
			copyrightCollection.addCopyright(copyright);

			// Create GTileLayer 
			var tileLayer = new GTileLayer(copyrightCollection , $map.minZoom, $map.maxZoom);
			tileLayer.getTileUrl = _getTileUrl($map);
			//HyperCities.debug(_id + "Map URL = " + $map.tileUrl);
			tileLayer.isPng = function () { return true; };
			tileLayer.getOpacity = function () { return $opacity; };

			// Add the tileOverlay to the map
			var tileOverlay = new GTileLayerOverlay(tileLayer);

			HyperCities.mapList.setMapOverlay($map.id, tileOverlay, $opacity);
			_GMap.addOverlay(tileOverlay);

			// Earth does not do auto zoom, do it only on map mode
//			if (HyperCities.mainMap.getCurrentMapType() !== G_SATELLITE_3D_MAP)
//			{
//				if ( _zoom > $map.maxZoom ) {
//					_GMap.setCenter( bounds.getCenter(), parseInt($map.maxZoom) );
//					HyperCities.debug(_id + "Auto Zoom out to " + $map.maxZoom);
//				} else if ( _zoom < $map.minZoom ) {
//					_GMap.setCenter( bounds.getCenter(), parseInt($map.minZoom) );
//					HyperCities.debug(_id + "Auto Zoom in to " + $map.minZoom);
//				}
//			}

			//add map on google earth, Jay: 1/30/2009
			HyperCities.earth.addMap($map);
		},

		removeMap: function($map) {

			   if ( $map !== null && 
					   typeof($map.tileOverlay) !== 'undefined' && $map.tileOverlay !== null ) {
				   //HyperCities.debug(_id + "Remove Map " + $map.id);
				   _GMap.removeOverlay($map.tileOverlay);
				   $map.tileOverlay = null ;
			   }

			   //remove map on google earth, Jay: 1/30/2009
			   HyperCities.earth.removeMap($map.id);
		},

		refreshMap: function($map, $opacity) {
				if ( (typeof($map) === 'undefined') || ($map === null) || 
						(typeof($map.tileOverlay) === 'undefined') || ($map.tileOverlay === null))
					return;

				HyperCities.mainMap.removeMap($map);
				HyperCities.mainMap.addMap($map, $opacity);
		},

		// Add Blank MapType 
		addBlankMap: function() {

				 var mapTypeArray = _GMap.getMapTypes();
				 var totalTypes   = mapTypeArray.length;

				 // We already have blank Map
				 if ( mapTypeArray[totalTypes-1].getName() === "Blank" )
					 return ;

				 var bounds = new GLatLngBounds(new GLatLng(0, 0),
						 new GLatLng(0, 0));

				 // Create GCopyright and GCopyrightCollection
				 var copyright = new GCopyright("Blank", bounds, G_NORMAL_MAP.getMinimumResolution(), "");

				 var copyrightCollection = new GCopyrightCollection("HyperCities 2009");
				 copyrightCollection.addCopyright(copyright);

				 // Create GTileLayer
				 var tileLayers = [new GTileLayer(copyrightCollection , 
						 G_NORMAL_MAP.getMinimumResolution(), 
						 G_NORMAL_MAP.getMaximumResolution())];
				 tileLayers[0].getTileUrl = function () { return "images/transparent.png"; };

				 // Add the tileOverlay to the map
				 var projection = G_NORMAL_MAP.getProjection();
				 var blankMap = new GMapType(tileLayers, projection, "Blank");
				 _GMap.addMapType(blankMap);
				 _GMap.addControl(new GMenuMapTypeControl());
		},

		addMapsProxy: function($maps) {
				  HyperCities.debug(_id + "Add Maps Proxy");

				  var i, strokeColor, strokeWeight, strokeOpacity, fillColor, fillOpacity, polygon;

				  for ( i in $maps ) {
					  //HyperCities.debug(_id + $maps[i].id);

					  strokeColor   = "#f33f00";
					  strokeWeight  = 1;
					  strokeOpacity = 1;
					  fillColor     = "#ff0000";
					  fillOpacity   = 0.2;

					  if ( $maps[i].tileOverlay !== null )
						  fillOpacity = 0;

					  polygon = new GPolygon($maps[i].boundary, 
							  strokeColor, 
							  strokeWeight, 
							  strokeOpacity, 
							  fillColor,
							  fillOpacity,
							  {clickable: false});

					  HyperCities.mapList.setMapProxy($maps[i].id, polygon);

					  polygon.hide();
					  _GMap.addOverlay(polygon);
				  }
		},

		removeMapsProxy: function($maps) {
					 HyperCities.debug(_id + "Remove Maps Proxy");

					 var i ;

					 for ( i in $maps ) {
						 _GMap.removeOverlay($maps[i].proxy);
					 }
		},

		addOverlay: function($GOverlay) {
			if ($GOverlay instanceof GOverlay) {
				_GMap.addOverlay($GOverlay);
			}
		},

		removeOverlay: function($GOverlay) {
//			HyperCities.debug(_id + "Remove Overlay");
			if ($GOverlay instanceof GOverlay) {
				_GMap.removeOverlay($GOverlay);
			}
		},

		clearOverlays: function() {
//			HyperCities.debug(_id + "Clear Overlay");
			_GMap.clearOverlays();
		},

		addListener: function($event, $callback) {
				 _mainListeners.push(GEvent.addListener(_GMap, $event, $callback));
				 return _mainListeners.length - 1;
		},

		removeListener: function($listenerId) {
					var listener = _mainListeners.splice($listenerId, 1);
					GEvent.removeListener(listener[0]);
		},

		//do not call this function, use HyperCities.timebar.setTime() instead
		setTimespan: function($startTime, $endTime) {

			 HyperCities.debug(_id + "Set Timespan " + $startTime.getFullYear().toString() + " ~ " + $endTime.getFullYear().toString());

			 _minTime = ($startTime === "undefined" ) ? null : $startTime;
			 _maxTime = ($endTime === "undefined" ) ? null : $endTime;

			 _GInfoPanel.setTimespan(_minTime, _maxTime);
		},

		getTimespan: function() {
			if ( typeof(_minTime) === 'undefined' || _minTime === null ||
				 typeof(_maxTime) === 'undefined' || _maxTime === null ) {
				return;
			}

//			 HyperCities.debug(_id + "startTime" + _minTime.toString("yyyy-MM-ddTHH:mm:ssZ"));
//			 HyperCities.debug(_id + "endTime" + _maxTime.toString("yyyy-MM-ddTHH:mm:ssZ"));

			 return {min: _minTime, max: _maxTime};
		},

		setCity: function($city) {
			 if ( $city === null ) {
				 _GInfoPanel.setCity("");
				 //                HyperCities.debug(_id + "Set City to Null");
			 } else {
			 	//HyperCities.debug("$city.timespan.min="+$city.timespan.min);
			 	//HyperCities.debug("$city.timespan.max="+$city.timespan.max);
			 	//HyperCities.debug("_minTime="+_minTime);
			 	//HyperCities.debug("_maxTime="+_maxTime);
				 _GInfoPanel.setCity($city.name);
				 if ( typeof(HyperCities.mainMap.getTimespan()) === 'undefined' )
					//HyperCities.mainMap.setTimespan($city.timespan, false);
					HyperCities.timebar.setTime(null, $city.timespan.min, $city.timespan.max, null, false);
				 else
					//HyperCities.mainMap.setTimespan({min: _minTime, max: _maxTime}, false);
					HyperCities.timebar.setTime(null, _minTime, _maxTime, null, false);
				 //                HyperCities.debug(_id + "Set City to " + $city.name);
			 }
		},

		addCities: function($cities) {
				var isHidden = false, i;
				var swLatLng, neLatLng, bounds, zoom, center, icon, marker;

				//HyperCities.debug(_id + "Add Cities");
				for (i in $cities) {
					//HyperCities.debug(_id + $cities[i].id);
				   
					isHidden = ($.inArray($cities[i].id, HyperCities.config.HIDDEN_CITIES) >= 0 );

					if (!isHidden) { // Add Marker and Listener

						// Calculate zoomlevel and city center
						swLatLng = new GLatLng($cities[i].swLat, $cities[i].swLon);
						neLatLng = new GLatLng($cities[i].neLat, $cities[i].neLon);

						bounds = new GLatLngBounds(swLatLng, neLatLng);
						zoom   = _GMap.getBoundsZoomLevel(bounds);
						center = bounds.getCenter();

						// Set the zoomlevel and center of city
						// ( Enable after server return accuracy data)
						// HyperCities.city.setZoom($cities[i].id, zoom);
						// HyperCities.city.setCenter($cities[i].id, center);

						// Comment out this 2 lines after server return accuracy data
						zoom = $cities[i].zoom;
						center = $cities[i].defaultCenter;

						icon = new GIcon(G_DEFAULT_ICON, "images/markerCity.png");
						icon.iconSize = new GSize(25, 25);
						icon.shadowSize = new GSize(1, 1);
						icon.imageMap = [0, 0, 25, 0, 25, 25, 0, 25];
						icon.iconAnchor = new GPoint(icon.iconSize.width/2, icon.iconSize.height/2);

						marker = new GMarker($cities[i].defaultCenter, {title: $cities[i].name, icon: icon});

						_addCity(marker, $cities[i], center, zoom);
					} // end if
				} // end for
		},

		// remove the cityOverlay from map
		removeCities: function() {
				  HyperCities.debug(_id + "Remove Cities");

				  for( var i in _cityMarkers ) {
					  _GMap.removeOverlay(_cityMarkers[i]);
				  }

				  _removeCityListeners();
		},

			  // Check if given GLatLon is in Map View
		inMap: function($GLatLng, $bounds) {
		   var currentBounds;

		   //jay
		   if ($bounds !== 'undefined' && $bounds != null)
			   currentBounds = $bounds;
		   else
			   currentBounds = _GMap.getBounds();

		   return currentBounds.containsLatLng($GLatLng);
		},

	   // Retuen Boundary of Map Object
		getBounds: function() { 
			   var orgBound = _GMap.getBounds();
			   var temp1 = _GMap.fromContainerPixelToLatLng(new GPoint(100,100));
			   var temp2 = _GMap.fromContainerPixelToLatLng(new GPoint(140,180));

			   var offsetX = Math.abs(temp1.x - temp2.x);
			   var offsetY = Math.abs(temp1.y - temp2.y);
			   var newNorth = orgBound.getNorthEast().lat() - ( offsetX );
			   var newEast  = orgBound.getNorthEast().lng() - ( offsetY / 4 );
			   var newSouth = orgBound.getSouthWest().lat() + ( offsetX * 1.5);
			   var newWest  = orgBound.getSouthWest().lng() + ( offsetY );

			   var newBound = new GLatLngBounds(new GLatLng(newSouth,newWest), new GLatLng(newNorth,newEast));

			   if (HyperCities.mainMap.getCurrentMapType() === G_SATELLITE_3D_MAP) {
				   return HyperCities.earth.getBounds();
			   } else {
				   if ( _zoom > 4 )
					   return newBound;
				   else
					   return orgBound;
			   }
		},

		// Return Current zoomlevel of Map Object
		getZoom: function() {
			if ( _GMap.getCurrentMapType() === G_SATELLITE_3D_MAP ) {
				return HyperCities.earth.getZoom();
			} 

			return _zoom;
		},

		// Return Max Zoom Level of current Map type
		getMaximumResolution: function () {
			var mapType = _GMap.getCurrentMapType();

			return mapType.getMaximumResolution();
		},

		// Returns the zoom level at which the given rectangular region fits in the map view.
		getBoundsZoomLevel: function ($bounds) {
			if ($bounds instanceof GLatLngBounds) {
				return _GMap.getBoundsZoomLevel($bounds);
			}
			return false;
		},

		fromContainerPixelToLatLng: function ($pixel) {
			if ($pixel instanceof GPoint) {
				return _GMap.fromContainerPixelToLatLng($pixel);
			}
			return false;
		},

		panTo: function ($GLatLng) {
			if ($GLatLng instanceof GLatLng) {
				_GMap.panTo($GLatLng);
				HyperCities.mainMap.setCenter($GLatLng);		
			}
		},

		getMapInstance: function() {
			return _GMap;
		},

		checkResize: function () {
			_GMap.checkResize();
		},

		toggleOverlayControl: function() {
			_OverlayControl.toggleMode();
		},

		openInfoWindow: function($type, $GLatLng, $content, $options) {

					switch ($type) {
						case "node" : _GMap.openInfoWindow($GLatLng, $content, $options); break;
						case "html" : _GMap.openInfoWindowHtml($GLatLng, $content, $options); break;
						case "tabs" : _GMap.openInfoWindowTabs($GLatLng, $content, $options); break; 
						case "tabsHtml" : _GMap.openInfoWindowTabsHtml($GLatLng, $content, $options); break;
						default : return false;
					}

					return true;
		},

		getInfoWindow: function () {
			return _GMap.getInfoWindow();
		},

		closeInfoWindow: function () {
			if ( _GMap.infoWindowEnabled() )
				 _GMap.closeInfoWindow();
		},

		maximizeInfoWindow: function() {
						if ( _GMap.infoWindowEnabled() ) {

							var tmpListener = GEvent.addListener(_GMap.getInfoWindow(), "maximizeend", function() {
									var ImageSubId = 0;
									var ImagePanelObject = { id : $(".HCContentText").attr("id"),
									title : $(".HCContentTitle").html() };

									$(".HCContentText").find("img.Itemshockwave").replaceWith('<object></object>','shockwave');
									$(".HCContentText").find("img.Itemaudio").replaceWith('<object></object>','audio');

									$(".HCContentText img").each( function() {
										var imageId = ImagePanelObject.id + "_" + ImageSubId++;

										var imageObject = { id: imageId,
										title: ImagePanelObject.title,
										sourceURL: $(this).attr("src"),
										height: 200,
										width: 320
										};

										var image = new Image();
										image.onload = function () { imageObject.height = this.height;
										imageObject.width  = this.width; };
										image.src = $(this).attr("src");

										$(this).click(HyperCities.mainMap.overlayImageBox(imageObject));

										});

									$(".HCContentText a[target='_top']").attr('target','_blank');

									GEvent.removeListener(tmpListener);
							});

							_GMap.getInfoWindow().maximize();
						}
		},

		//get current map type, Jay: 1/31/2009
		getCurrentMapType: function() {
			return _GMap.getCurrentMapType();
		},

		isInView: function($obj) {

			var result = false;
				viewBounds = _GMap.getBounds();

//			HyperCities.debug(_id + "viewBounds="+viewBounds);

			if ( $obj instanceof GLatLng ) {
				result = viewBounds.containsLatLng($obj);
			}
			else if ( $obj instanceof GLatLngBounds ) {

				if (viewBounds.intersects($obj) || viewBounds.containsBounds($obj)) {
					result = true;
				}
			}

//			HyperCities.debug("_id + result="+result);

			return result;
		},

		clickGMarkerHandler: function($index) {
						 //HyperCities.debug("$index="+$index);
						 $("#intelliList .highlight").removeClass('highlight');
						 var item = $("#intelliItem_"+$index, "#intelliList").addClass('highlight');
						 HyperCities.debug(_id + "item.id="+item.attr("id"));
						 if ($("#intelliList .intelliItem").length > 1)
							 $("#intelliList")[0].scrollTo("#intelliItem_"+$index);
		},

		addEventListener: function($nodeObj) {
					  GEvent.addListener($nodeObj.obj, 'click', function(){
							  HyperCities.debug("index="+$nodeObj.id);
							  HyperCities.mainMap.clickGMarkerHandler($nodeObj.id);
							  });
		},

		overlayImageBox: function(object) {
					 return function() {

						 // Determin the minimize status of Panel
						 var isMinimized = function(targetIndex) {
							 return parseInt(HyperCities.dhtmlWindow[targetIndex].cfg.getProperty("height")) < 50 ? true : false ;
						 };

						 // Get Panel Index in HyperCities.dhtmlWindow Array by PanelId
						 var getWindowIndex = function(ObjectId) {
							 for(var i=HyperCities.dhtmlWindow.length-1; i>=0; i--)
								 if (HyperCities.dhtmlWindow[i].id == ObjectId)
									 return i;
							 return -1;
						 };

						 // Align the Stacked Area
						 var alignStack = function() {
							 var stackOffset = HyperCities.dhtmlStacked ;
							 for (var i=HyperCities.dhtmlWindow.length-1; i>=0; i--){
								 if ( isMinimized(i) ) {
									 HyperCities.dhtmlWindow[i].cfg.setProperty("context", ["map","bl","bl"]);
									 var new_y = HyperCities.dhtmlWindow[i].cfg.getProperty("y") - (35 * stackOffset--);
									 HyperCities.dhtmlWindow[i].cfg.setProperty("xy", [0, new_y]);
								 }
							 }
						 };

						 // Toggle the Photo Display Panel
						 var togglePanel = function(PanelId){
							 var targetIndex = getWindowIndex(PanelId);
							 var targetPanel = HyperCities.dhtmlWindow[targetIndex] || null;

							 if ( !targetPanel )
								 return;

							 if ( isMinimized(targetIndex) ) {
								 // Restore Panel Event
								 YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getElementsByClassName("bd","div",PanelId),"hidden");
								 YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getElementsByClassName("ft","div",PanelId),"hidden");
								 YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getElementsByClassName("yui-resize-handle","div",PanelId),"hidden");
								 YAHOO.util.Dom.replaceClass(YAHOO.util.Dom.getElementsByClassName("container-toggle","a",PanelId),"plus", "minus");

								 targetPanel.cfg.setProperty("width", targetPanel.org_width);
								 targetPanel.cfg.setProperty("height", targetPanel.org_height);
								 // Reset XY only when the panel is stacked at left
								 if ( targetPanel.cfg.getProperty("x") == 10 ) {
									 targetPanel.cfg.setProperty("xy", targetPanel.org_xy);
								 }
								 targetPanel.Resize.unlock(true);
								 HyperCities.dhtmlStacked--;
							 } else {
								 // Minimize Panel Event
								 // First save coordinate and size for restore
								 targetPanel.org_width = targetPanel.cfg.getProperty("width");
								 targetPanel.org_height = targetPanel.cfg.getProperty("height");
								 targetPanel.org_xy = targetPanel.cfg.getProperty("xy");

								 // Hide and minimize the Panel
								 YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("bd","div",PanelId),"hidden");
								 YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("ft","div",PanelId),"hidden");
								 YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("yui-resize-handle","div",PanelId),"hidden");
								 YAHOO.util.Dom.replaceClass(YAHOO.util.Dom.getElementsByClassName("container-toggle","a",PanelId),"minus", "plus");

								 targetPanel.cfg.setProperty("width", "200px");
								 targetPanel.cfg.setProperty("height", "30px");
								 targetPanel.Resize.lock(false);
								 HyperCities.dhtmlStacked++;
							 }
							 alignStack();
						 };

						 var PanelId = "ImgPanel_" + object.id;
						 var PanelIndex = getWindowIndex(PanelId);
						 var defaultWidth = 320;
						 var defaultHeight = parseInt(defaultWidth * ( object.height * 1.0 / object.width )) + 64;
						 var viewportHeight =  $(window).height();

						 if ( defaultHeight > ( viewportHeight - 120 ) )
							 defaultHeight = viewportHeight - 120;

						 HyperCities.debug("W " +defaultWidth + " H " + defaultHeight);

						 // If Panel already existed, just focus it.
						 if ( PanelIndex >= 0 ) {
							 if ( isMinimized(PanelIndex) )
								 togglePanel(PanelId);

							 HyperCities.dhtmlManager.bringToTop(HyperCities.dhtmlWindow[PanelIndex]);
							 HyperCities.dhtmlManager.focus(HyperCities.dhtmlWindow[PanelIndex]);
						 } else {
							 // Create Photo Display Panel
							 var ImagePanel = new YAHOO.widget.Panel(PanelId, {
									width: defaultWidth + "px",
									height: defaultHeight + "px",
									visible:false,
									constraintoviewport:true,
									draggable:true,
									close:true,
									autofillheight: "body",
									zIndex:998,
									context: ["map","tl","tl"]
								});

							 ImagePanel.setHeader(object.title);
							 ImagePanel.setBody("<img id=\"photo"+object.id+"\" src=\""+object.sourceURL+"\" style=\"width:100%;height:100%;min-width:"+defaultWidth+"px;min-height:"+(defaultHeight-64)+"px;\">");
							 ImagePanel.setFooter("Opacity: <div id=\""+PanelId+"_Slider_bg\" class=\"oSlider-bg\"tabindex=\"1\" title=\"Slider\" onfocus=\"blur(this);\"><div id=\""+PanelId+"_Slider_thumb\" class=\"oSlider-thumb\"><img src=\"images/thumb-n.gif\"></div></div>");

							 ImagePanel.render(document.body);
							 ImagePanel.show();

							 // Apply custom CSS to ImgPanel Object
							 var panelHeader = YAHOO.util.Dom.get(PanelId+"_h");
							 YAHOO.util.Dom.addClass(PanelId, "imgPanel");
							 YAHOO.util.Dom.addClass(panelHeader, "imgPanel");
							 YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("bd","div",PanelId),"imgPanel");
							 YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("ft","div",PanelId),"imgPanel");
							 ImagePanel.cfg.setProperty("width", defaultWidth + "px");
							 ImagePanel.cfg.setProperty("height", defaultHeight + "px");

							 // Create Toggle Button
							 var closeLink = YAHOO.util.Dom.getLastChild(PanelId);
							 var toggleLink = document.createElement("a");
							 toggleLink.setAttribute("class", "container-toggle minus");
							 toggleLink.setAttribute("href", "#");
							 toggleLink.innerHTML = "Toggle";
							 toggleLink.onclick = function(PanelId) {
								 return function() {
									 togglePanel(PanelId);
								 };} (PanelId);

							 // Add double click event trigger to Panel header
							 panelHeader.ondblclick = function(PanelId) {
								 return function() {
									 togglePanel(PanelId);
								 };} (PanelId);

							 // Destory Panel Object after close the panel
							 closeLink.onclick = function(PanelId) {
								 return function() {
									 var targetIndex = getWindowIndex(PanelId);
									 if ( targetIndex < 0 )
										 return;

									 var needAlign = isMinimized(targetIndex);
									 HyperCities.dhtmlManager.remove(HyperCities.dhtmlWindow[targetIndex]);
									 HyperCities.dhtmlWindow[targetIndex].Resize.destroy();
									 HyperCities.dhtmlWindow[targetIndex].destroy();
									 HyperCities.dhtmlWindow.splice(targetIndex,1);
									 if ( needAlign ) {
										 HyperCities.dhtmlStacked--;
										 alignStack();
									 }
								 };} (PanelId);

							 // Attach toggle button to Panel
							 YAHOO.util.Dom.insertBefore(toggleLink, closeLink);

							 // Generate the opacity Slider
							 ImagePanel.Slider = YAHOO.widget.Slider.getHorizSlider(PanelId+"_Slider_bg", PanelId+"_Slider_thumb", 0, 200, 1);
							 ImagePanel.Slider.setValue(200, true);
							 // Subscribe to the Slider instance's "change" event
							 ImagePanel.Slider.subscribe("change", function() {
									 var targetIndex = getWindowIndex(PanelId);
									 if ( targetIndex < 0 )
									 return;
									 var nValue = (Math.round(HyperCities.dhtmlWindow[targetIndex].Slider.getValue() * .5)),
									 nOpacity = (nValue * .01);
									 YAHOO.util.Dom.get(PanelId+"_Slider_bg").title = "Opacity: " + parseInt(nValue) + "%";
									 YAHOO.util.Dom.setStyle("photo"+object.id, "opacity", nOpacity);
									 });

							 // Generate the Resize Handler
							 ImagePanel.Resize = new YAHOO.util.Resize(PanelId, { handles: ['br'], autoRatio: true, minWidth: defaultWidth, minHeight: defaultHeight, status: false });

							 ImagePanel.Resize.on("startResize", function(args) {
									 if (this.cfg.getProperty("constraintoviewport")) {
									 var D = YAHOO.util.Dom;

									 var clientRegion = D.getClientRegion();
									 var elRegion = D.getRegion(this.element);

									 this.Resize.set("maxWidth", clientRegion.right - elRegion.left - YAHOO.widget.Overlay.VIEWPORT_OFFSET);
									 this.Resize.set("maxHeight", clientRegion.bottom - elRegion.top - YAHOO.widget.Overlay.VIEWPORT_OFFSET);
									 } else {
									 this.Resize.set("maxWidth", null);
									 this.Resize.set("maxHeight", null);
									 }
									 }, ImagePanel, true);

							 ImagePanel.Resize.on("resize", function(args) {
									 var panelHeight = args.height;
									 var panelWidth= args.width;
									 this.cfg.setProperty("height", panelHeight + "px");
									 this.cfg.setProperty("width", panelWidth + "px");
									 }, ImagePanel, true);

							 // Add new Panel to Overlay Manager
							 if ( HyperCities.dhtmlManager == null ) {
								 HyperCities.dhtmlManager = new YAHOO.widget.OverlayManager();
							 }
							 HyperCities.dhtmlManager.register(ImagePanel);
							 HyperCities.dhtmlManager.bringToTop(ImagePanel);
							 HyperCities.dhtmlManager.focus(ImagePanel);
							 HyperCities.dhtmlWindow.push(ImagePanel);
						 }

						 return false;
					 }; 
		},

            /*
             * Creates a citation panel, which floats over the map.
             * 
             */    
            showCitation: function ($objectId, $refId, $title, $content) {
                if (typeof($content) == 'undefined') $content = HyperCities.collectionList.getCitation($objectId, $refId);
                var objectId = $objectId + "_" + $refId;
                //HyperCities.debug(objectId);
                return function() {

                         // Determin the minimize status of Panel
                         var isMinimized = function(targetIndex) {
                                 return parseInt(HyperCities.dhtmlWindow[targetIndex].cfg.getProperty("height")) < 50 ? true : false ;
                         };

                         // Get Panel Index in HyperCities.dhtmlWindow Array by PanelId
                         var getWindowIndex = function(ObjectId) {
                                 for(var i=HyperCities.dhtmlWindow.length-1; i>=0; i--)
                                         if (HyperCities.dhtmlWindow[i].id == ObjectId)
                                                 return i;
                                 return -1;
                         };

                         // Align the Stacked Area
                         var alignStack = function() {
                                 var stackOffset = HyperCities.dhtmlStacked ;
                                 for (var i=HyperCities.dhtmlWindow.length-1; i>=0; i--){
                                         if ( isMinimized(i) ) {
                                                 HyperCities.dhtmlWindow[i].cfg.setProperty("context", ["map","bl","bl"]);
                                                 var new_y = HyperCities.dhtmlWindow[i].cfg.getProperty("y") - (35 * stackOffset--);
                                                 HyperCities.dhtmlWindow[i].cfg.setProperty("xy", [0, new_y]);
                                         }
                                 }
                         };

                         // Toggle the Photo Display Panel
                         var togglePanel = function(PanelId){
                                 var targetIndex = getWindowIndex(PanelId);
                                 var targetPanel = HyperCities.dhtmlWindow[targetIndex] || null;

                                 if ( !targetPanel )
                                         return;

                                 if ( isMinimized(targetIndex) ) {
                                         // Restore Panel Event
                                         YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getElementsByClassName("bd","div",PanelId),"hidden");
                                         YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getElementsByClassName("ft","div",PanelId),"hidden");
                                         YAHOO.util.Dom.removeClass(YAHOO.util.Dom.getElementsByClassName("yui-resize-handle","div",PanelId),"hidden");
                                         YAHOO.util.Dom.replaceClass(YAHOO.util.Dom.getElementsByClassName("container-toggle","a",PanelId),"plus", "minus");

                                         targetPanel.cfg.setProperty("width", targetPanel.org_width);
                                         targetPanel.cfg.setProperty("height", targetPanel.org_height);
                                         // Reset XY only when the panel is stacked at left
                                         if ( targetPanel.cfg.getProperty("x") == 10 ) {
                                                 targetPanel.cfg.setProperty("xy", targetPanel.org_xy);
                                         }
                                         targetPanel.Resize.unlock(true);
                                         HyperCities.dhtmlStacked--;
                                 } else {
                                         // Minimize Panel Event
                                         // First save coordinate and size for restore
                                         targetPanel.org_width = targetPanel.cfg.getProperty("width");
                                         targetPanel.org_height = targetPanel.cfg.getProperty("height");
                                         targetPanel.org_xy = targetPanel.cfg.getProperty("xy");

                                         // Hide and minimize the Panel
                                         YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("bd","div",PanelId),"hidden");
                                         YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("ft","div",PanelId),"hidden");
                                         YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("yui-resize-handle","div",PanelId),"hidden");
                                         YAHOO.util.Dom.replaceClass(YAHOO.util.Dom.getElementsByClassName("container-toggle","a",PanelId),"minus", "plus");

                                         targetPanel.cfg.setProperty("width", "200px");
                                         targetPanel.cfg.setProperty("height", "30px");
                                         targetPanel.Resize.lock(false);
                                         HyperCities.dhtmlStacked++;
                                 }
                                 alignStack();
                         };

                         

                         var PanelId = "RefPanel_" + objectId;
                         var PanelIndex = getWindowIndex(PanelId);
                         
                         var defaultWidth = 320;
                         var defaultHeight = 200; ;//parseInt(defaultWidth * ( object.height * 1.0 / object.width )) + 64;
                         var viewportHeight =  $(window).height();
                         

                         if ( defaultHeight > ( viewportHeight - 120 ) )
                                 defaultHeight = viewportHeight - 120;

                         //HyperCities.debug("W " +defaultWidth + " H " + defaultHeight);

                         // If Panel already existed, just focus it.
                         if ( PanelIndex >= 0 ) {
                                 if ( isMinimized(PanelIndex) )
                                         togglePanel(PanelId);

                                 HyperCities.dhtmlManager.bringToTop(HyperCities.dhtmlWindow[PanelIndex]);
                                 HyperCities.dhtmlManager.focus(HyperCities.dhtmlWindow[PanelIndex]);
                         } else {
                                 // Create Photo Display Panel
                                 var CitationPanel = new YAHOO.widget.Panel(PanelId, {
                                                width: defaultWidth + "px",
                                                height: defaultHeight + "px",
                                                visible:false,
                                                constraintoviewport:true,
                                                draggable:true,
                                                close:true,
                                                autofillheight: "body",
                                                zIndex:998,
                                                context: ["map","tl","tl"]
                                        });

                                 CitationPanel.setHeader("Reference: " + $title);
                                 //CitationPanel.setBody("<img id=\"photo"+object.id+"\" src=\""+object.sourceURL+"\" style=\"width:100%;height:100%;min-width:"+defaultWidth+"px;min-height:"+(defaultHeight-64)+"px;\">");
                                 //var body = document.createElement("div");
                                 CitationPanel.setBody($content);
                                 
                                 //CitationPanel.appendToBody($content);
                                 //HyperCities.debug($content);
                                 //CitationPanel.appendToBody($content);
                                 //HyperCities.debug(body);
                                 //HyperCities.debug($content);
                                 //CitationPanel.setFooter("Opacity: <div id=\""+PanelId+"_Slider_bg\" class=\"oSlider-bg\"tabindex=\"1\" title=\"Slider\" onfocus=\"blur(this);\"><div id=\""+PanelId+"_Slider_thumb\" class=\"oSlider-thumb\"><img src=\"images/thumb-n.gif\"></div></div>");

                                 CitationPanel.render(document.body);
                                 //HyperCities.debug("Showing refernece panel ...")
                                 CitationPanel.show();

                                 // Apply custom CSS to ImgPanel Object
                                 var panelHeader = YAHOO.util.Dom.get(PanelId+"_h");
                                 YAHOO.util.Dom.addClass(PanelId, "refPanel");
                                 YAHOO.util.Dom.addClass(panelHeader, "refPanel");
                                 YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("bd","div",PanelId),"refPanel");
                                 YAHOO.util.Dom.addClass(YAHOO.util.Dom.getElementsByClassName("ft","div",PanelId),"refPanel");
                                 CitationPanel.cfg.setProperty("width", defaultWidth + "px");
                                 CitationPanel.cfg.setProperty("height", defaultHeight + "px");
                                 CitationPanel.cfg.setProperty("xy", [viewportHeight - 140, window.width * (2/3)])

                                 // Create Toggle Button
                                 var closeLink = YAHOO.util.Dom.getLastChild(PanelId);
                                 var toggleLink = document.createElement("a");
                                 toggleLink.setAttribute("class", "container-toggle minus");
                                 toggleLink.setAttribute("href", "#");
                                 toggleLink.innerHTML = "Toggle";
                                 toggleLink.onclick = function(PanelId) {
                                         return function() {
                                                 togglePanel(PanelId);
                                         };} (PanelId);

                                 // Add double click event trigger to Panel header
                                 panelHeader.ondblclick = function(PanelId) {
                                         return function() {
                                                 togglePanel(PanelId);
                                         };} (PanelId);

                                 // Destory Panel Object after close the panel
                                 closeLink.onclick = function(PanelId) {
                                         return function() {
                                                 var targetIndex = getWindowIndex(PanelId);
                                                 if ( targetIndex < 0 )
                                                         return;

                                                 var needAlign = isMinimized(targetIndex);
                                                 HyperCities.dhtmlManager.remove(HyperCities.dhtmlWindow[targetIndex]);
                                                 HyperCities.dhtmlWindow[targetIndex].Resize.destroy();
                                                 HyperCities.dhtmlWindow[targetIndex].destroy();
                                                 HyperCities.dhtmlWindow.splice(targetIndex,1);
                                                 if ( needAlign ) {
                                                         HyperCities.dhtmlStacked--;
                                                         alignStack();
                                                 }
                                         };} (PanelId);

                                 // Attach toggle button to Panel
                                 YAHOO.util.Dom.insertBefore(toggleLink, closeLink);

                                 // Generate the Resize Handler
                                 CitationPanel.Resize = new YAHOO.util.Resize(PanelId, { handles: ['br'], autoRatio: true, minWidth: defaultWidth, minHeight: defaultHeight, status: false });

                                 CitationPanel.Resize.on("startResize", function(args) {
                                                 if (this.cfg.getProperty("constraintoviewport")) {
                                                 var D = YAHOO.util.Dom;

                                                 var clientRegion = D.getClientRegion();
                                                 var elRegion = D.getRegion(this.element);

                                                 this.Resize.set("maxWidth", clientRegion.right - elRegion.left - YAHOO.widget.Overlay.VIEWPORT_OFFSET);
                                                 this.Resize.set("maxHeight", clientRegion.bottom - elRegion.top - YAHOO.widget.Overlay.VIEWPORT_OFFSET);
                                                 } else {
                                                 this.Resize.set("maxWidth", null);
                                                 this.Resize.set("maxHeight", null);
                                                 }
                                                 }, CitationPanel, true);

                                 CitationPanel.Resize.on("resize", function(args) {
                                                 var panelHeight = args.height;
                                                 var panelWidth= args.width;
                                                 this.cfg.setProperty("height", panelHeight + "px");
                                                 this.cfg.setProperty("width", panelWidth + "px");
                                                 }, CitationPanel, true);

                                 // Add new Panel to Overlay Manager
                                 if ( HyperCities.dhtmlManager == null ) {
                                         HyperCities.dhtmlManager = new YAHOO.widget.OverlayManager();
                                 }
                                 HyperCities.dhtmlManager.register(CitationPanel);
                                 HyperCities.dhtmlManager.bringToTop(CitationPanel);
                                 HyperCities.dhtmlManager.focus(CitationPanel);
                                 HyperCities.dhtmlWindow.push(CitationPanel);
                         }

                         return false;
                     }();
                },

		enableSync: function($flag) {

			if ($flag)
				HyperCities.debug(_id + "Enable auto map refresh.");
			else
				HyperCities.debug(_id + "Disable auto map refresh.");

			_enableSync = $flag;	
		},

		isSync: function() {
			return _enableSync;
		},
		
		restoreSync: function()
		{
			if ($("#mapAutoSync").attr('checked'))
				HyperCities.mainMap.enableSync(true);
			else
				HyperCities.mainMap.enableSync(false);
		},
		
		setAddMediaControl: function() {
			_GAddMediaControl = new AddMediaControl();
			_GMap.addControl(_GAddMediaControl);
		},

		removeAddMediaControl: function() {
			_GMap.removeControl(_GAddMediaControl);
			_GAddMediaControl = null;
		},

		getAddMediaControl: function() {
			return _GAddMediaControl;
		},

		// Progressbar Control Function
		addProgressbarPending: function($total) {
			_GProgressbar.addPending($total);
		},

		addProgressbarFinished: function($step) {
			_GProgressbar.addFinished($step);
		},

		hideProgressbar: function() {
			_GProgressbar.remove();
		},

		// HyperCities InfoWindow Function
		closeHCInfoWindow: function($restore) {
			_GMap.closeHCInfoWindow($restore);
		},

		openHCInfoWindow: function($item, $opts) {
			_GMap.openHCInfoWindow($item, $opts);
		},
	};
}(); // end of Object

// end of file
