/* http://www.dyve.net/jquery/?googlemaps */

$.googleMap = {
	maps: {},
	marker: function(m, t) {
		if (!m) {
			return null;
		} else if (m.lat == null && m.lng == null) {
			return $.googleMap.marker($.googleMap.readFromGeo(m, t));
		} else {
			var marker = new GMarker(new GLatLng(m.lat, m.lng));
			if (m.txt) {
				GEvent.addListener(marker, "click", function() {
    				marker.openInfoWindowHtml(m.txt);
  				});
			}
			return marker;
		}
	},
	readFromGeo: function(el, listtype) {
		var $el = $(el);
		var $latElem = $(".latitude:first", el);
		var $lngElem = $(".longitude:first", el);
		
		if(listtype == "multi"){
			var $vcard = $el.parent();
	
			if ($latElem && $lngElem) {
				//todo: fix this part up a bit:
				var txtInfo = '<strong>'+$('.storeName', $vcard).text() +'</strong><br />'+ $(".storeAdr",$vcard).html()+'<br /><br />'+$(".storeTel",$vcard).html();
				return { lat:parseFloat($latElem.attr("title")), lng:parseFloat($lngElem.attr("title")), txt:txtInfo }
			} else {
				return null;
			}
		}else {
			var $vcard = $el.parent().siblings();
			if ($latElem && $lngElem) {
				//todo: fix this part up a bit:
				var txtInfo = '<strong>'+$vcard.filter(".storeName").text() +'</strong><br />'+ $vcard.filter(".storeAdr").html()+'<br /><br />'+$vcard.filter(".storeTel").html();
				return { lat:parseFloat($latElem.attr("title")), lng:parseFloat($lngElem.attr("title")), txt:txtInfo }
			} else {
				return null;
			}
		}
	},
	mapNum: 1
};

$.fn.googleMap = function(lat, lng, zoom, options) {
	// If we aren't supported, we're done
	if (!window.GBrowserIsCompatible || !GBrowserIsCompatible()) return this;
	
	// Default values make for easy debugging
	/*
	if (lat == null) lat = 37.4419;
	if (lng == null) lng = -122.1419;
	if (!zoom) zoom = 13;
	*/
	if(lat==null) {
	
		var minLat=false;
		var maxLat, minLng, maxLng;
		
		$(options.markers).each(function(){
			myLat = parseFloat($(".latitude:first", this).text())
			myLng = parseFloat($(".longitude:first", this).text())
			if(!minLat) {
				minLat = myLat;
				maxLat = myLat;
				minLng = myLng;
				maxLng = myLng;
			} 
			if (myLat < minLat) minLat = myLat;
			if (myLat > maxLat) maxLat = myLat;
			if (myLng < minLng) minLng = myLng;
			if (myLng > maxLng) maxLng = myLng;
		})
	}
	lat = minLat + (maxLat - minLat)/2;
	lng = minLng + (maxLng - minLng)/2;
	
	
	var R = 6371; // 6371 = km, 3958.75 = miles

	/* formula
		http://www.movable-type.co.uk/scripts/latlong.html
		http://www.daftlogic.com/projects-google-maps-distance-calculator.htm
		http://www.meridianworlddata.com/Distance-Calculation.asp
		http://www.codedblog.com/2007/09/28/how-to-auto-zoom-and-auto-center-google-maps/
		
		based on the Great Circle Distance Formula using decimal degrees
		www.meridianworlddata.com/Distance-Calculation.asp... use 3963.0 for value in miles.
	*/
	dist = 6378.7 * Math.acos(Math.sin(minLat/57.2958) * Math.sin(maxLat/57.2958) + Math.cos(minLat/57.2958) * Math.cos(maxLat/57.2958) *  Math.cos(maxLng/57.2958 -minLng/57.2958));

	//todo: adjust these settings a bit
	if (dist< 0.5) 		zoom=16;
	else if (dist < 2)	zoom=15;
	else if (dist < 3)	zoom=14;
	else if (dist < 4)	zoom=13;
	else if (dist < 6)	zoom=12;
	else if (dist < 12) zoom=11;
	else if (dist < 26) zoom=10;
	else if (dist < 50) zoom=9;
	else zoom=8;

	//debugging:
	//console.log('lat:'+lat+', lng:'+lng +', zoom:'+zoom+', distance:' +dist+' km');
	//console.log('zoom:'+zoom+', distance:' +dist+' km');

	// Sanitize options
	if (!options || typeof options != 'object')	options = {};
	options.mapOptions = options.mapOptions || {};
	options.markers = options.markers || [];
	options.controls = options.controls || {};

	// Map all our elements
	return this.each(function() {
		// Make sure we have a valid id
		if (!this.id) this.id = "gMap" + $.googleMap.mapNum++;
		// Create a map and a shortcut to it at the same time
		var map = $.googleMap.maps[this.id] = new GMap2(this, options.mapOptions);
		// Center and zoom the map
       	map.setCenter(new GLatLng(lat, lng), zoom);
       	// Add controls to our map
       	for (var i = 0; i < options.controls.length; i++) {
	       	var c = options.controls[i];
	       	eval("map.addControl(new " + c + "());");
       	}
       	// If we have markers, put them on the map
       	var marker = null;
       	for (var i = 0; i < options.markers.length; i++) {
	       	if (marker = $.googleMap.marker(options.markers[i], options.listtype)) map.addOverlay(marker);
       	}
    });
	
	//clean up when leaving the page. GUnload() resides in the remote google script.
	$(window).unload(GUnload);

};
