/**
 * Event Map - jquery.eventmap.js
 * 
 * Creates a Google map on the specified element and adds events
 * 
 * Dependencies: jQuery, Google Maps API
 * 
 * @project ShipServ Pages
 * @author Dave Starling dstarling@shipserv.com
 * @version 0.1
 */
(function($) {
	$.fn.eventMap = function(options) {
		var config = { speed : 5000,
					   messageBox : '#message',
					   eventUrl : '/events/fetch-recent-events/fetch/',
					   eventCount : 10,
					   mainTitleTag : 'h3',
					   subTitleTag : 'h4',
					   mapZoom : 2,
					   showTrails: false };
		
		if (options) $.extend(config, options);
		
		this.each(function() {
			var self = this,
				markers = new Array(),
				polylines = new Array(),
				gJSON,
				gCounter = 0,
				timerId,
				map;
			
			map = new GMap2(document.getElementById($(this)[0].id));
			map.setCenter(new GLatLng(0, 0), config.mapZoom);
			map.setMapType(G_HYBRID_MAP);
			map.disableDragging();
			
			$(config.messageBox).appendTo(map.getPane(G_MAP_FLOAT_SHADOW_PANE));
			
			function addLocation(location) {
				map.clearOverlays();
				
				var marker;
				
				if ((!location.lat || !location.lng) && 'address' in location) {
					var geocoder = new GClientGeocoder();
					
					geocoder.getLatLng(location.address.address1 + ', ' +
									   location.address.address2 + ', ' +
									   location.address.city + ', ' +
									   location.address.state + ', ' +
									   location.address.zip + ', ' +
									   location.address.country, function(point) {
											if (point) {
												var marker = new GMarker(point);
												map.addOverlay(marker);
												map.panTo(marker.getLatLng());
												showMessage(marker, location);
											}
									   });
				} else {
					var point = new GLatLng(location.lat, location.lng);
					marker = new GMarker(point);
					map.addOverlay(marker);
					map.panTo(marker.getLatLng());
					showMessage(marker, location);
				}
			}
			
			function addSpider(location) {
				map.clearOverlays();
				
				// add a marker for the sender
				if ((!location.sender.lat || !location.sender.lng) && 'address' in location.sender) {
					var geocoder = new GClientGeocoder();
					geocoder.getLatLng(location.sender.address.address1 + ', ' +
									   location.sender.address.address2 + ', ' +
									   location.sender.address.city + ', ' +
									   location.sender.address.state + ', ' +
									   location.sender.address.zip + ', ' +
									   location.sender.address.country, function(point) {
											if (point) {
												var marker = new GMarker(point);
												map.addOverlay(marker);
												map.panTo(marker.getLatLng());
												showMessage(marker, location);
												markers[gCounter] = marker;
												if (config.showTrails)
												{
													showTrails(point, location.recipients);
												}
											}
									   });
				} else {
					var point = new GLatLng(location.sender.lat, location.sender.lng);
					marker = new GMarker(point);
					map.addOverlay(marker);
					map.panTo(marker.getLatLng());
					showMessage(marker, location);
					markers[gCounter] = marker;
					if (config.showTrails)
					{
						showTrails(point, location.recipients);
					}
				}
			}
			
			function showTrails (point, recipients) {
				var polyOptions = {geodesic: true};
				
				for (r in recipients) {
					var recip = recipients[r];
					
					if ((!recip.lat || !recip.lng) && 'address' in recip) {
						var geocoder = new GClientGeocoder();
						
						geocoder.getLatLng(recip.address.address1 + ', ' +
										   recip.address.address2 + ', ' +
										   recip.address.city + ', ' +
										   recip.address.state + ', ' +
										   recip.address.zip + ', ' +
										   recip.address.country, function(rpoint) {
												if (rpoint) {
													var rmarker = new GMarker(rpoint);
													map.addOverlay(rmarker);
													var polyline = new GPolyline([ point, rpoint ],
																				 "#ffffff", 3, 0.7, polyOptions)
													map.addOverlay(polyline);
												}
										   });
					} else {
						var rpoint = new GLatLng(recip.lat, recip.lng);
						rmarker = new GMarker(rpoint);
						map.addOverlay(rmarker);
						var polyline = new GPolyline([ point, rpoint ],
													 "#ffffff", 3, 0.7, polyOptions);
						map.addOverlay(polyline);
					}
				}
			}
			
			function showMessage(marker, location) {
				var markerOffset = map.fromLatLngToDivPixel(marker.getPoint());
				
				var message = '<' + config.mainTitleTag + '>' + location.mainTitle + '</' + config.mainTitleTag + '>';
				message+= '<' + config.subTitleTag + '>' + location.subTitle + '</' + config.subTitleTag + '>';
				
				if ($.browser.msie && $.browser.version == 6.0) {
					var bg = 'url(/images/layout_v2/map/ie6/event-' + location.eventType + '-bg.gif) 0px 0px no-repeat'
				} else {
					var bg = 'url(/images/layout_v2/map/event-' + location.eventType + '-bg.png) 0px 0px no-repeat'
				}
				
				cursor = 'default';
				if (typeof(location.link) != 'undefined') {
					cursor = 'pointer';
				}
				
				$(config.messageBox).hide().fadeIn()
					.css({ top:markerOffset.y,
						   left:markerOffset.x,
						   background: bg,
						   cursor: cursor
					})
					.html(message)
					.click(function(){
						if (typeof(location.link) != 'undefined') {
							// IE doesn't pass through referrer information with JS triggers like this,
							// so we have to create a dummy anchor tag and trigger it manually.
							if (!jQuery.browser.msie) {
								window.location = location.link;
								return false;
							}
							
							var a = document.createElement("a");
							a.setAttribute("href", location.link);
							a.style.display = "none";
							$("body").append(a);
							a.click();
							
							return false;
						}
					});
			}
			
			function displayNextEvent() {
				if (typeof(gJSON) != 'undefined' && gJSON.Locations.length > gCounter) {
					var location = gJSON.Locations[gCounter];
					if ('sender' in location) {
						addSpider(location);
					} else {
						addLocation(location);
					}
					
					gCounter++;
					
					setTimeout(displayNextEvent, config.speed);
				} else {
					// run out of data - fetch some more
					gCounter = 0;
					
					$.getJSON(config.eventUrl + config.eventCount, function(json) {
						if (json.Locations.length > 0) {
							gJSON = json;
							setTimeout(displayNextEvent, 1);
						}
					});
				}
			}
			
			setTimeout(displayNextEvent, 1);
		});
		
		return this;
	}
})(jQuery);

