var DirectMail = DirectMail || {};

$(document).ready(function() {
	DirectMail.map = {};
	
	window.DirectMail_googleMapsDidLoad = function() {		
		DirectMail.map.map = new google.maps.Map( 
			document.getElementById( "map-canvas" ),
			{
				backgroundColor: "white",
				zoom: 2,
				center: new google.maps.LatLng( 23.5215, -1.8155 ),
				mapTypeId: google.maps.MapTypeId.ROADMAP,
				disableDefaultUI: true,
				zoomControl: true,
				zoomControlOptions: {
					style: google.maps.ZoomControlStyle.LARGE
				},
				mapTypeControl: true,
				mapTypeControlOptions: {
					style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR
				},
				styles: [
					{
						featureType: "landscape",
						elementType: "labels",
						stylers: [
							{ visibility: "off" }
						]
					},
					{
						featureType: "poi",
						elementType: "labels",
						stylers: [
							{ visibility: "off" }
						]
					},
					{
						featureType: "road",
						elementType: "labels",
						stylers: [
							{ visibility: "off" }
						]
					},
					{
						featureType: "transit",
						elementType: "labels",
						stylers: [
							{ visibility: "off" }
						]
					},
					{
						featureType: "water",
						elementType: "labels",
						stylers: [
							{ visibility: "off" }
						]
					}
				]
			}
		);
		
		DirectMail.map.fractionalZoom = DirectMail.map.map.getZoom();
		
		google.maps.event.addListener( DirectMail.map.map, 'zoom_changed', function() {
			DirectMail.map.fractionalZoom = DirectMail.map.map.getZoom();
		});
				
		var imagesDirectoryURL = window.DirectMail_mapController.mapImagesDirectoryURL();
				
		DirectMail.map.markerIcon = new google.maps.MarkerImage( 
			imagesDirectoryURL + "map-pin.png",
			new google.maps.Size( 47, 37 )
		);
		
		var clustererStyles = new Array();
		
		for ( var i = 0; i < 5; i++ ) {
			clustererStyles.push({
				url: imagesDirectoryURL + "pin-cluster.png",
				height: 72,
				width: 46,
				anchor: [36, 0],
				textColor: "black",
				textSize: 18 + i
			});
		}
		
		function DirectMailMarkerClusterer( map, markers, options ) {
			MarkerClusterer.prototype.constructor.call( this, map, markers, options );
		};
		
		DirectMailMarkerClusterer.prototype   = MarkerClusterer.prototype;
		DirectMailMarkerClusterer.constructor = DirectMailMarkerClusterer;
		
		DirectMailMarkerClusterer.prototype.createClusters_ = function () {
			if ( this.ready_ ) {
				for ( var i = 0, marker; marker = this.markers_[i]; i++ ) {
					if ( !marker.isAdded ) {
						this.addToClosestCluster_( marker );
					}
				}
			}
		};
		
		ClusterIcon.prototype.DirectMail_originalOnAdd = ClusterIcon.prototype.onAdd;
		ClusterIcon.prototype.onAdd 				   = function() {
			ClusterIcon.prototype.DirectMail_originalOnAdd.call( this );
			
			var self = this;
			
			google.maps.event.addDomListener(this.div_, 'mouseover', function() {
				var markers        = self.cluster_.getMarkers();
				var jqDiv	       = $(self.div_);
				var topCenterPoint = new google.maps.Point( jqDiv.position().left + 0.5 * jqDiv.width(), jqDiv.position().top );
				var topCenter      = self.getProjection().fromDivPixelToLatLng( topCenterPoint );
				var span		   = self.cluster_.getBounds().toSpan();
				var shouldShow     = ( span.lat() <= 0.01 && span.lng() <= 0.01 );
												
				if ( shouldShow ) {
					self.DirectMail_infoWindow = DirectMail.createInfoWindowForMarkers( markers );
					self.DirectMail_infoWindow.setPosition( topCenter );
					DirectMail.setActiveMapInfoWindow( self.DirectMail_infoWindow );
					self.DirectMail_infoWindow.open( self.cluster_.getMap() );
				}
				else {
					DirectMail.setActiveMapInfoWindow( null );
				}
			});

			google.maps.event.addDomListener(this.div_, 'mouseout', function() {
				if ( self.DirectMail_infoWindow ) {
					self.DirectMail_infoWindow.close();
					self.DirectMail_infoWindow = null;
				}
			});
		};
		
		DirectMail.map.markerClusterer = new DirectMailMarkerClusterer( DirectMail.map.map, [], {
			averageCenter: true,
			gridSize: 40,
			styles: clustererStyles
		} );
		DirectMail.map.markerAnimations = new Array();
		DirectMail.map.markersToCluster = new Array();

		window.DirectMail_mapController.mapIsReady();
	};
	
	var mapsScriptURL = "http://maps.googleapis.com/maps/api/js?key=" + window.DirectMail_mapController.mapAPIKey() + "&v=3.12&sensor=false&callback=DirectMail_googleMapsDidLoad";
	
	$.getScript( mapsScriptURL );
});

DirectMail.clearMap = function() {
	for ( var i = 0; i < DirectMail.map.markerAnimations.length; i++ ) {
		var animationInfo = DirectMail.map.markerAnimations[i];
		
		if ( !animationInfo.dropped ) {
			clearTimeout( animationInfo.dropTimer );
		}
	}
	
	DirectMail.map.markerAnimations.length = 0;		
	DirectMail.map.markersToCluster.length = 0;
		
	if ( DirectMail.map.clusterTimer ) {
		clearTimeout( DirectMail.map.clusterTimer );
		DirectMail.map.clusterTimer = null;
	}
	
	DirectMail.map.markerClusterer.clearMarkers();
};

DirectMail.addMapMarkersForTrackingEvents = function( events ) {
	var shouldAnimate           = ( events.length < 200 );
	var shouldRedrawClusterer   = false;
	var shouldStartClusterTimer = ( DirectMail.map.markersToCluster.length == 0 );
	
	for ( var i = 0; i < events.length; i++ ) {
		var event     = events[i];
		var latitude  = event.valueForKeyPath( "location.latitude" );
		var longitude = event.valueForKeyPath( "location.longitude" );
		
		if ( latitude !== undefined && longitude !== undefined ) {
			var marker = new google.maps.Marker({
				position: new google.maps.LatLng( latitude, longitude ),
				icon: DirectMail.map.markerIcon,
				optimized: false
			});
			
			(function ( m, addressHistory ) {
				m.DirectMail_trackingEvent = event;
				
				google.maps.event.addListener( m, 'click', function() {
					window.DirectMail_mapController.didClickMarker( addressHistory );
				});
				
				google.maps.event.addListener( m, 'mouseover', function() {
					m.DirectMail_infoWindow = DirectMail.createInfoWindowForMarkers( [ m ] );
					DirectMail.setActiveMapInfoWindow( m.DirectMail_infoWindow );
					m.DirectMail_infoWindow.open( DirectMail.map.map, m );
				});
				
				google.maps.event.addListener( m, 'mouseout', function() {
					m.DirectMail_infoWindow.close();
					m.DirectMail_infoWindow = null;
				});
			})( marker, event.valueForKeyPath( "addressHistory") );
			
			if ( shouldAnimate ) {
				(function( m ){
					var animationInfo = { marker: m };

					animationInfo.dropTimer = setTimeout(function() {
						animationInfo.dropped = true;
						animationInfo.marker.setAnimation( google.maps.Animation.DROP );
						animationInfo.marker.setMap(DirectMail.map.map);
					}, 100 * i );
					
					DirectMail.map.markerAnimations.push( animationInfo );
				})( marker );
				
				DirectMail.map.markersToCluster.push( marker );
			}
			else {
				DirectMail.map.markerClusterer.addMarker( marker, true );
				shouldRedrawClusterer = true;
			}			
		}
	}
	
	if ( DirectMail.map.markersToCluster.length && shouldStartClusterTimer ) {
		DirectMail.map.clusterTimer = setTimeout( function() {
			for ( var i = 0; i < DirectMail.map.markersToCluster.length; i++ ) {
				var marker = DirectMail.map.markersToCluster[i];
				
				marker.setAnimation(null);
				marker.setMap(null);
				DirectMail.map.markerClusterer.addMarker( marker, true );
			}
			
			DirectMail.map.markersToCluster.length = 0;
			DirectMail.map.clusterTimer = null;
			DirectMail.map.markerClusterer.resetViewport();
			DirectMail.map.markerClusterer.redraw();
		}, 5 * 1000 );
	}
	
	if ( shouldRedrawClusterer ) {
		DirectMail.map.markerClusterer.resetViewport();
		DirectMail.map.markerClusterer.redraw();
	}
};

DirectMail.createInfoWindowForMarkers = function( markers ) {
	var content = $("<div><h1 class=recipient-name></h1><p class=recipient-email></p><p class=recipient-location></p><p class=recipient-view-date></p></div>" );
		
	if ( markers.length == 1 ) {
		var marker 		  = markers[0];
		var trackingEvent = marker.DirectMail_trackingEvent;
		
		$(".recipient-name", content).text( trackingEvent.valueForKeyPath( "addressHistory.archivedAddress.fullName" ) );
		$(".recipient-email", content).text( trackingEvent.valueForKeyPath( "addressHistory.archivedAddress.email" ) );
		$(".recipient-location", content).text( trackingEvent.valueForKeyPath( "location.localizedDescription" ) );
		$(".recipient-view-date", content).text( trackingEvent.valueForKeyPathWithFormatterName( "date", "MediumDateFormatter" ) );
	}
	else {
		var firstMarker = markers[0];
		var emailAddresses = [];
		
		for ( var i = 0; i < markers.length; i++ ) {
			emailAddresses.push( markers[i].DirectMail_trackingEvent.valueForKeyPath( "addressHistory.archivedAddress.email" ) );
		}
		
		$(".recipient-name", content).text( markers.length + " recipients" );
		$(".recipient-email", content).text( emailAddresses.join( ", " ) );
		$(".recipient-location", content).text( firstMarker.DirectMail_trackingEvent.valueForKeyPath( "location.localizedDescription" ) );
	}
	
	return new google.maps.InfoWindow({
		content: $(content).get(0)
	});
};

DirectMail.setActiveMapInfoWindow = function ( infoWindow ) {
	if ( infoWindow != DirectMail.activeMapInfoWindow ) {
		if ( DirectMail.activeMapInfoWindow ) {
			DirectMail.activeMapInfoWindow.close();
		}
		
		DirectMail.activeMapInfoWindow = infoWindow;
	}
};

DirectMail.magnifyMap = function ( magnification ) {
	DirectMail.map.fractionalZoom += ( magnification * 3.5 ); // Adjust constant up for faster zooms, down for slower
	
	var newZoom = Math.round( DirectMail.map.fractionalZoom );
	
	if ( newZoom != DirectMail.map.map.getZoom() ) {
		DirectMail.map.map.setZoom( newZoom );
	}
};