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

/**
 * HyperCities miniMap Objects
 *
 * @author    Chen-Kuei Lee
 * @copyright (c) 2008, by HyperCities Tech Team
 * @date      2008-12-22
 * @version   0.7
 *
 */
 
// create applicatio namespace
HyperCities.miniMap = function() {

    // do NOT access javascript generated DOM from here; elements don't exist yet
    var _id          = "[HyperCities.miniMap] ";
    var _defaultLat  = 40;
    var _defaultLon  = 5;
    var _defaultZoom = 0;
    var _mapTypes    = [G_SATELLITE_MAP];
    var _listeners   = new Array();
    var _GMap;
    var _lat;
    var _lon;
    var _center;
    var _zoom;

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

        _listeners.push(GEvent.addListener($marker, "click", function($event) {

                var oldZoomLevel = HyperCities.mainMap.getZoom();
                
                HyperCities.debug(_id + "Goto city " + $city.name);
                //HyperCities.debug("oldZoomLevel="+oldZoomLevel);
				
				//HyperCities.debug(_id + "$zoom = "+ $zoom);
                HyperCities.mainMap.setCenter($center, $zoom);

                HyperCities.session.set("city", $city);

				HyperCities.util.eventTracker(HyperCities.config.EVENT_VIEW_CITY, $city.name);
			
				//set timespan from 0 to current year to query all maps when click a city
				HyperCities.timebar.setTime(null, 0, new Date().getFullYear(), null, false);

				//setCenter will trigger syncSession if zoom level changed
				//trigger it manually here if zoom level does not change
                //if ( oldZoomLevel >= HyperCities.config.ZOOM_THRESHOLD )
                if ( oldZoomLevel === $zoom )
				//set a short delay to wait map changing to new location successfully
				//so that out program can get correct boundary
					setTimeout(function(){HyperCities.syncSession();}, 200);

				$.each(HyperCities.session.get("map"), function () {
                        HyperCities.session.removeMap(this);
                    });
				
				//bind ajaxSuccess event so that we can get correct timespan of all maps
				$().ajaxSuccess(function(){
		            //set timebar to the union of timespan of all maps
					var range = HyperCities.mapList.getMapRange();
					var startYear = null;
					var endYear = null;
					if (range.min !== null)
						startYear = range.min.getFullYear();
					if (range.max !== null)
						endYear = Math.max(range.max.getFullYear(), new Date().getFullYear());

					HyperCities.timebar.setTime(null, startYear, endYear, null, false);

					//unbind ajaxSuccess event
					$().unbind("ajaxSuccess");
				});
            }));

        _listeners.push(GEvent.addListener($marker, 'mouseover', function() {
                $marker.setImage("images/markerPoint.png");
            }));

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

        _GMap.addOverlay($marker); 
    };

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

    return {
        
        // Initialize the Mini 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;
            _lon = isNaN($options.lon) ? _defaultLon : $options.lon;
            _center = new google.maps.LatLng( _lat, _lon);
            _zoom = isNaN($options.zoom) ? _defaultZoom : $options.zoom;
            _GMap   = new google.maps.Map2($($context).get(0), {mapTypes: _mapTypes});

            _GMap.setCenter( _center, _zoom);
            _GMap.disableDragging();
        },

		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/markerPoint.png");
						icon.iconSize = new GSize(10, 10);
						icon.iconAnchor = new GPoint(5, 5);
						icon.shadowSize = new GSize(1, 1);

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

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

        // Center the map to the given Lat. Lon and Zoomlevel
        setCenter: function($options) {
            if(typeof($options) === 'undefined')
                return;

            _lat = isNaN($options.lat) ? _lat : $options.lat;
            _lon = isNaN($options.lon) ? _lon : $options.lon;
            _zoom = isNaN($options.zoom) ? _zoom : $options.zoom;

            _center = new google.maps.LatLng( _lat, _lon);
            _GMap.setCenter( _center, _zoom);
        }
    };
}(); // end of Object

// end of file
