/**
 * jQuery gMap
 *
 * @url		http://gmap.nurtext.de/
 * @author	Cedric Kastner <cedric@nur-text.de>
 * @version	1.1.0
 */
(function($)
{
	// Main plugin function
	$.fn.gMap = function(options)
	{
		// Check if the browser is compatible
		if (!window.GBrowserIsCompatible || !GBrowserIsCompatible()) return this;
		
		// Build main options before element iteration
		var opts = $.extend({}, $.fn.gMap.defaults, options);
    	
		// Iterate through each element
		return this.each(function()
		{
			// Create map and set initial options
			$gmap = new GMap2(this);
			
			// Create new object to geocode addresses
			$geocoder = new GClientGeocoder();
			
			// Check for address to center on
			if (opts.address)
			{ 
				// Get coordinates for given address and center the map
				$geocoder.getLatLng(opts.address, function(gpoint){ $gmap.setCenter(gpoint, opts.zoom); });
				
			}
			else
			{
				// Check for coordinates to center on
				if (opts.latitude && opts.longitude)
				{
					// Center map to coordinates given by option
					$gmap.setCenter(new GLatLng(opts.latitude, opts.longitude), opts.zoom);
					
				}
				else
				{
					// Check for a marker to center on (if no coordinates given)
					if ($.isArray(opts.markers) && opts.markers.length > 0)
					{
						// Check if the marker has an address
						if (opts.markers[0].latitude && opts.markers[0].longitude)
						{
							// Center the map to coordinates given by marker
							$gmap.setCenter(new GLatLng(opts.markers[0].latitude, opts.markers[0].longitude), opts.zoom);							
						}
						else if (opts.markers[0].address)
						{
							// Get the coordinates for given marker address and center
							$geocoder.getLatLng(opts.markers[0].address, function(gpoint){ 
								$gmap.setCenter(gpoint, opts.zoom);
							});							
						}
						else
						{
							// Revert back to world view
							$gmap.setCenter(new GLatLng(34.885931, 9.84375), opts.zoom);
							
						}
						
						
					}
					else
					{
						// Revert back to world view
						$gmap.setCenter(new GLatLng(34.885931, 9.84375), opts.zoom);
						
					}
					
				}
				
			}
						
			// Set the preferred map type
			$gmap.setMapType(opts.maptype);
			
			// Check for map controls
			if (opts.controls.length == 0)
			{
				// Default map controls
				$gmap.setUIToDefault();
				
			}
			else
			{
				// Add custom map controls
				for (var i = 0; i < opts.controls.length; i++)
				{
					// Eval is evil
					eval('$gmap.addControl(new ' + opts.controls[i] + '());');
					
				}
				
			}
						
			// Check if scrollwheel should be enabled
			if (opts.scrollwheel == true && opts.controls.length != 0) { $gmap.enableScrollWheelZoom(); }
			
			var minLat = 0;
			var maxLat = 0;
			var minLon = 0;
			var maxLon = 0;
			
			var checkBack = [];
									
			// Loop through marker array
			for (var j = 0; j < opts.markers.length; j++)
			{
				// Get the options from current marker
				marker = opts.markers[j];
								
				// Create new icon
				gicon = new GIcon();
				
				// Set icon properties from global options
				gicon.image = opts.icon.image;
				gicon.shadow = opts.icon.shadow;
				gicon.iconSize = ($.isArray(opts.icon.iconsize)) ? new GSize(opts.icon.iconsize[0], opts.icon.iconsize[1]) : opts.icon.iconsize;
				gicon.shadowSize = ($.isArray(opts.icon.shadowsize)) ? new GSize(opts.icon.shadowsize[0], opts.icon.shadowsize[1]) : opts.icon.shadowsize;
				gicon.iconAnchor = ($.isArray(opts.icon.iconanchor)) ? new GPoint(opts.icon.iconanchor[0], opts.icon.iconanchor[1]) : opts.icon.iconanchor;
				gicon.infoWindowAnchor = ($.isArray(opts.icon.infowindowanchor)) ? new GPoint(opts.icon.infowindowanchor[0], opts.icon.infowindowanchor[1]) : opts.icon.infowindowanchor;
				
				if (marker.icon)
				{
					// Overwrite global options
					gicon.image = marker.icon.image;
					gicon.shadow = marker.icon.shadow;
					gicon.iconSize = ($.isArray(marker.icon.iconsize)) ? new GSize(marker.icon.iconsize[0], marker.icon.iconsize[1]) : marker.icon.iconsize;
					gicon.shadowSize = ($.isArray(marker.icon.shadowsize)) ? new GSize(marker.icon.shadowsize[0], marker.icon.shadowsize[1]) : marker.icon.shadowsize;
					gicon.iconAnchor = ($.isArray(marker.icon.iconanchor)) ? new GPoint(marker.icon.iconanchor[0], marker.icon.iconanchor[1]) : marker.icon.iconanchor;
					gicon.infoWindowAnchor = ($.isArray(marker.icon.infowindowanchor)) ? new GPoint(marker.icon.infowindowanchor[0], marker.icon.infowindowanchor[1]) : marker.icon.infowindowanchor;
					
				}

				checkBack[j] = true;
				
				// Check if address is available
				if (marker.address)
				{
					continue;
					
					// Check for reference to the marker's address
					if (marker.html == '_address') { marker.html = marker.address; }
					
					checkBack[j] = false;

					// Get the point for a given address
					$.ajax({
						url: "googlemapsgeocoderpassthrough.php",
						data: $.extend(marker.data, {send: "json?address="+marker.address.replace(/ /gi,'+')+"&sensor=false"}),
						dataType: "json",
						type: 'post',
						success: function(){ 
							var tmarker = marker;
							var tj = j;
							return function(data) {
								if(data!=null && data.latitude!=null && data.longitude!=null) {
//								if(data!=null && data.status=="OK") {
								
									tmarker.latitude = data.latitude;
									tmarker.longitude = data.longitude;
									//tmarker.latitude = data.results[0].geometry.location.lat;
									//tmarker.longitude = data.results[0].geometry.location.lng;
									
									// Check for reference to the marker's latitude/longitude
									if (tmarker.html == '_latlng') { tmarker.html = tmarker.latitude + ', ' + tmarker.longitude; }
									
									if( minLat == 0 || tmarker.latitude < minLat ) {
										minLat = tmarker.latitude;
									}
									if( minLon == 0 || tmarker.longitude < minLon ) {
										minLon = tmarker.longitude;
									}
									if( tmarker.latitude > maxLat ) {
										maxLat = tmarker.latitude;
									}
									if( tmarker.longitude > maxLon ) {
										maxLon = tmarker.longitude;
									}
									
									// Create marker
									gmarker = new GMarker(new GPoint(tmarker.longitude, tmarker.latitude), gicon);
									
									// Set HTML and check if info window should be opened
									// if (tmarker.html) { gmarker.bindInfoWindowHtml(opts.html_prepend + tmarker.html + opts.html_append); }
									// if (tmarker.html && tmarker.popup) { gmarker.openInfoWindowHtml(opts.html_prepend + tmarker.html + opts.html_append); }
									// GEvent.addListener(gmarker, "click", function() {
										//var myHtml = opp['opp_title'] + "<br/>" + place.address;
										//map.openInfoWindowHtml(point, myHtml);
										//show_opp_info(tmarker.data);
									//});
										
									// Add marker to map
									if (gmarker) { $gmap.addOverlay(gmarker); }
									
									//checkBack[tj]=true;
									//testCheckBack = true;
									//for (var x = 0; x < opts.markers.length; x++)
									//{
									//	if(!checkBack[x]) {
									//		testCheckBack = false;
									//	}
									//}
									//if(testCheckBack) {
									//	while(waiting.length > 0){
									//		waiting.pop()();
									//	}
									//}
														
								}
								else {
									checkBack[tj]=true;
								}
							};
						}() 
					});
					
					/*
					$geocoder.getLatLng(marker.address, function(gicon, marker)
					{
						// Since we're in a loop, we need a closure when dealing with event handlers, return functions, etc.
						// See <http://www.mennovanslooten.nl/blog/post/62> for more information about closures
						return function(gpoint)
						{
							if(gpoint!=null) {
								// Create marker
								gmarker = new GMarker(gpoint, gicon);
								
								var lat = gpoint.lat();
								var lng = gpoint.lng();
	
								if( minLat == 0 || lat < minLat ) {
									minLat = lat;
								}
								if( minLon == 0 || lng < minLon ) {
									minLon = lng;
								}
								if( maxLat == 0 || lat > maxLat ) {
									maxLat = lat;
								}
								if( maxLon == 0 || lng > maxLon ) {
									maxLon = lng;
								}
								
								// Set HTML and check if info window should be opened
								if (marker.html) { gmarker.bindInfoWindowHtml(opts.html_prepend + marker.html + opts.html_append); }
								if (marker.html && marker.popup) { gmarker.openInfoWindowHtml(opts.html_prepend + marker.html + opts.html_append); }
								
								// Add marker to map
								if (gmarker) { $gmap.addOverlay(gmarker); }
							}
						}
						
					}(gicon, marker));
					*/
					
				}
				else
				{
					// Check for reference to the marker's latitude/longitude
					if (marker.html == '_latlng') { marker.html = marker.latitude + ', ' + marker.longitude; }
					
					if( minLat == 0 || marker.latitude < minLat ) {
						minLat = marker.latitude;
					}
					if( minLon == 0 || marker.longitude < minLon ) {
						minLon = marker.longitude;
					}
					if( maxLat == 0 || marker.latitude > maxLat ) {
						maxLat = marker.latitude;
					}
					if( maxLon == 0 || marker.longitude > maxLon ) {
						maxLon = marker.longitude;
					}
					
					// Create marker
					gmarker = new GMarker(new GPoint(marker.longitude, marker.latitude), gicon);
					
					// Set HTML and check if info window should be opened
					if (marker.html) { gmarker.bindInfoWindowHtml(opts.html_prepend + marker.html + opts.html_append); }
					if (marker.html && marker.popup) { gmarker.openInfoWindowHtml(opts.html_prepend + marker.html + opts.html_append); }
						
					// Add marker to map
					if (gmarker) { $gmap.addOverlay(gmarker); }
					
				}
				
			}
			
			/*
			if (opts.autozoom == true) {
				waiting.push(function(){
					var zoom = 9;
					var miles = (3958.75 * Math.acos(Math.sin(minLat / 57.2958) * Math.sin(maxLat / 57.2958) + Math.cos(minLat / 57.2958) * Math.cos(maxLat / 57.2958) * Math.cos(maxLon / 57.2958 - minLon / 57.2958)));
		            if (miles < 0.2) {
		                zoom = 16;
		            }
		            else if (miles < 0.5) {
		                zoom = 15;
		            }
		            else if (miles < 1) {
		                zoom = 14;
		            }
		            else if (miles < 2) {
		                zoom = 13;
		            }
		            else if (miles < 3) {
		                zoom = 12;
		            }
		            else if (miles < 7) {
		                zoom = 11;
		            }
		            else if (miles < 15) {
		                zoom = 10;
		            }
		            $gmap.setCenter(new GLatLng((maxLat+minLat)/2, (maxLon+minLon)/2), 7);
				});
			}
			//*/
			
		});
		
	}
		
	// Default settings
	$.fn.gMap.defaults =
	{
		address:				'',
		latitude:				0,
		longitude:				0,
		zoom:					1,
		markers:				[],
		controls:				[],
		scrollwheel:			true,
		maptype:				G_NORMAL_MAP,
		html_prepend:			'<div class="gmap_marker">',
		html_append:			'</div>',
		icon:
		{
			image:				"http://www.google.com/mapfiles/marker.png",
			shadow:				"http://www.google.com/mapfiles/shadow50.png",
			iconsize:			[20, 34],
			shadowsize:			[37, 34],
			iconanchor:			[9, 34],
			infowindowanchor:	[9, 2]
			
		}
		
	}
	
})(jQuery);