/*
 ### jQuery Google Maps Plugin v1.01 ###
 * Home: http://www.mayzes.org/googlemaps.jquery.html
 * Code: http://www.mayzes.org/js/jquery.googlemaps1.01.js
 * Date: 2010-01-14 (Thursday, 14 Jan 2010)
 * 
 * Dual licensed under the MIT and GPL licenses.
 *   http://www.gnu.org/licenses/gpl.html
 *   http://www.opensource.org/licenses/mit-license.php
 ###
*/
(function($) {
  jQuery.fn.googleMaps = function(options) {
  
  	if (!window.GBrowserIsCompatible || !GBrowserIsCompatible())  {
  	   return this;
  	}
  
  	// Fill default values where not set by instantiation code
  	var opts = $.extend({}, $.googleMaps.defaults, options);
  	
  	//$.fn.googleMaps.includeGoogle(opts.key, opts.sensor);
  	return this.each(function() {
  		// Create Map
  		$.googleMaps.gMap = new GMap2(this, opts);
  		$.googleMaps.mapsConfiguration(opts);
  	});
  };
  
  $.googleMaps = {
  	mapsConfiguration: function(opts) {
  		// GEOCODE
  		if ( opts.geocode ) {
  			geocoder = new GClientGeocoder();
  			geocoder.getLatLng(opts.geocode, function(center) {
  				if (!center) {
  					alert(address + " not found");
  				}
  				else {
      	      		$.googleMaps.gMap.setCenter(center, opts.depth);
  					$.googleMaps.latitude = center.x;
  					$.googleMaps.longitude = center.y;
  				}
        });
  		}
  		else {
  			// Latitude & Longitude Center Point
  			var center 	= $.googleMaps.mapLatLong(opts.latitude, opts.longitude);
  			// Set the center of the Map with the new Center Point and Depth
  			$.googleMaps.gMap.setCenter(center, opts.depth);
  		}
  		
  		// POLYLINE
  		if ( opts.polyline )
  			// Draw a PolyLine on the Map
  			$.googleMaps.gMap.addOverlay($.googleMaps.mapPolyLine(opts.polyline));
  		// GEODESIC 
  		if ( opts.geodesic ) {
  			$.googleMaps.mapGeoDesic(opts.geodesic);
  		}
  		// PAN
  		if ( opts.pan ) {
  			// Set Default Options
  			opts.pan = $.googleMaps.mapPanOptions(opts.pan);
  			// Pan the Map
  			window.setTimeout(function() {
  				$.googleMaps.gMap.panTo($.googleMaps.mapLatLong(opts.pan.panLatitude, opts.pan.panLongitude));
  			}, opts.pan.timeout);
  		}
  		
  		// LAYER
  		if ( opts.layer )
  			// Set the Custom Layer
  			$.googleMaps.gMap.addOverlay(new GLayer(opts.layer));
  		
  		// MARKERS
  		if ( opts.markers )
  			$.googleMaps.mapMarkers(center, opts.markers);
  
  		// CONTROLS
  		if ( opts.controls.type || opts.controls.zoom ||  opts.controls.mapType ) {
  			$.googleMaps.mapControls(opts.controls);
  		}
  		else {
  			if ( !opts.controls.hide ) 
  				$.googleMaps.gMap.setUIToDefault();
  		}
      
      // MAP TYPE
      if ( opts.type )
        $.googleMaps.gMap.setMapType($.googleMaps.mapTypeControl(opts.type));
  		
  		// SCROLL
  		if ( opts.scroll ) 
  			$.googleMaps.gMap.enableScrollWheelZoom();
  		else if ( !opts.scroll )
  			$.googleMaps.gMap.disableScrollWheelZoom();
  		
  		// LOCAL SEARCH
  		if ( opts.controls.localSearch )
  			$.googleMaps.gMap.enableGoogleBar();
  		else 
  			$.googleMaps.gMap.disableGoogleBar();
  
  		// FEED (RSS/KML)
  		if ( opts.feed ) 
  			$.googleMaps.gMap.addOverlay(new GGeoXml(opts.feed));
  		
  		// TRAFFIC INFO
  		if ( opts.trafficInfo ) {
  			var trafficOptions = {incidents:true};
  			trafficInfo = new GTrafficOverlay(trafficOptions);
  			$.googleMaps.gMap.addOverlay(trafficInfo);	
  		}
  		
  		// DIRECTIONS
  		if ( opts.directions ) {
  			$.googleMaps.directions = new GDirections($.googleMaps.gMap, opts.directions.panel);
    			$.googleMaps.directions.load(opts.directions.route);
  		}
  		
  		if ( opts.streetViewOverlay ) {
  			svOverlay = new GStreetviewOverlay();
      		$.googleMaps.gMap.addOverlay(svOverlay);	
  		}
  	},
  	mapGeoDesic: function(options) {
  		// Default GeoDesic Options
  		geoDesicDefaults = {
  			startLatitude: 	37.4419,
  			startLongitude: -122.1419,
  			endLatitude:	37.4519,
  			endLongitude:	-122.1519,
  			color: 			'#ff0000',
  			pixels: 		2,
  			opacity: 		10
  		}
  		// Merge the User & Default Options
  		options = $.extend({}, geoDesicDefaults, options);
  		var polyOptions = {geodesic:true};
  		var polyline = new GPolyline([ 
  			new GLatLng(options.startLatitude, options.startLongitude),
  			new GLatLng(options.endLatitude, options.endLongitude)], 
  			options.color, options.pixels, options.opacity, polyOptions
  		);
  		$.googleMaps.gMap.addOverlay(polyline);
  	},
  	localSearchControl: function(options) {
  		var controlLocation = $.googleMaps.mapControlsLocation(options.location);
  		$.googleMaps.gMap.addControl(new $.googleMaps.gMap.LocalSearch(), new GControlPosition(controlLocation, new GSize(options.x,options.y)));
  	},
  	getLatitude: function() {
  		return $.googleMaps.latitude;
  	},
  	getLongitude: function() {
  		return $.googleMaps.longitude;
  	},
  	directions: {},
  	latitude: '',
  	longitude: '',
  	latlong: {},
  	maps: {},
  	marker: {},
  	gMap: {},
  	defaults: {
  	// Default Map Options
  		latitude: 	37.4419,
  		longitude: 	-122.1419,
  		depth: 		13,
  		scroll: 	true,
  		trafficInfo: false,
  		streetViewOverlay: false,
  		controls: {
  			hide: false,
  			localSearch: false
  		},
  		layer:		null
  	},
  	mapPolyLine: function(options) {
  		// Default PolyLine Options
  		polylineDefaults = {
  			startLatitude: 	37.4419,
  			startLongitude: -122.1419,
  			endLatitude:	37.4519,
  			endLongitude:	-122.1519,
  			color: 			'#ff0000',
  			pixels: 		2
  		}
  		// Merge the User & Default Options
  		options = $.extend({}, polylineDefaults, options);
  		//Return the New Polyline
  		return new GPolyline([
  			$.googleMaps.mapLatLong(options.startLatitude, options.startLongitude),
  			$.googleMaps.mapLatLong(options.endLatitude, options.endLongitude)], 
  			options.color, 
  			options.pixels
  		);
  	},
  	mapLatLong: function(latitude, longitude) {
  		// Returns Latitude & Longitude Center Point
  		return new GLatLng(latitude, longitude);
  	},
  	mapPanOptions: function(options) {
  		// Returns Panning Options
  		var panDefaults = {
  			panLatitude:	37.4569, 	
  			panLongitude:	-122.1569,
  			timeout: 		0
  		}
  		return options = $.extend({}, panDefaults, options);
  	},
  	mapMarkersOptions: function(icon) {
  		//Define an icon
  		var gIcon = new GIcon(G_DEFAULT_ICON);	
  		if ( icon.image ) 
  			// Define Icons Image
  			gIcon.image = icon.image;
  		if ( icon.shadow )
  			// Define Icons Shadow
  			gIcon.shadow = icon.shadow;
  		if ( icon.iconSize )
  			// Define Icons Size
  			gIcon.iconSize = new GSize(icon.iconSize);
  		if ( icon.shadowSize )
  			// Define Icons Shadow Size
  			gIcon.shadowSize = new GSize(icon.shadowSize);
  		if ( icon.iconAnchor )
  			// Define Icons Anchor
  			gIcon.iconAnchor = new GPoint(icon.iconAnchor);
  		if ( icon.infoWindowAnchor )
  			// Define Icons Info Window Anchor
  			gIcon.infoWindowAnchor = new GPoint(icon.infoWindowAnchor);
  		if ( icon.dragCrossImage ) 
  			// Define Drag Cross Icon Image
  			gIcon.dragCrossImage = icon.dragCrossImage;
  		if ( icon.dragCrossSize )
  			// Define Drag Cross Icon Size
  			gIcon.dragCrossSize = new GSize(icon.dragCrossSize);
  		if ( icon.dragCrossAnchor )
  			// Define Drag Cross Icon Anchor
  			gIcon.dragCrossAnchor = new GPoint(icon.dragCrossAnchor);
  		if ( icon.maxHeight )
  			// Define Icons Max Height
  			gIcon.maxHeight = icon.maxHeight;
  		if ( icon.PrintImage )
  			// Define Print Image
  			gIcon.PrintImage = icon.PrintImage;
  		if ( icon.mozPrintImage )
  			// Define Moz Print Image
  			gIcon.mozPrintImage = icon.mozPrintImage;
  		if ( icon.PrintShadow )
  			// Define Print Shadow
  			gIcon.PrintShadow = icon.PrintShadow;
  		if ( icon.transparent )
  			// Define Transparent
  			gIcon.transparent = icon.transparent;
  		return gIcon;
  	},
  	mapMarkers: function(center, markers) {
          if ( typeof(markers.length) == 'undefined' )
          	// One marker only. Parse it into an array for consistency.
              markers = [markers];
  		
  		var j = 0;
  		for ( i = 0; i<markers.length; i++) {
  			var gIcon = null;
  			if ( markers[i].icon ) {
  				gIcon = $.googleMaps.mapMarkersOptions(markers[i].icon);
  			}
  			
  			if ( markers[i].geocode ) {
  				var geocoder = new GClientGeocoder();
  				geocoder.getLatLng(markers[i].geocode, function(center) {										
  					if (!center) 
  						alert(address + " not found");
  					else 
  						$.googleMaps.marker[i] = new GMarker(center, {draggable: markers[i].draggable, icon: gIcon});
  				});
  			}
  			else if ( markers[i].latitude && markers[i].longitude ) {
  				// Latitude & Longitude Center Point
  				center = $.googleMaps.mapLatLong(markers[i].latitude, markers[i].longitude);
  				$.googleMaps.marker[i] = new GMarker(center, {draggable: markers[i].draggable, icon: gIcon});
  			}
  			$.googleMaps.gMap.addOverlay($.googleMaps.marker[i]);
  			if ( markers[i].info ) {
  				// Hide Div Layer With Info Window HTML
  				$(markers[i].info.layer).hide();
  				// Marker Div Layer Exists
  				if ( markers[i].info.popup )
  					// Map Marker Shows an Info Box on Load
  					$.googleMaps.marker[i].openInfoWindowHtml($(markers[i].info.layer).html());
  				else
  					$.googleMaps.marker[i].bindInfoWindowHtml( $(markers[i].info.layer).html().toString() );
  			}
  		}
  	},
  	mapControlsLocation: function(location) {
  		switch (location) {
  			case 'G_ANCHOR_TOP_RIGHT' :
  				return G_ANCHOR_TOP_RIGHT;
  			break;
  			case 'G_ANCHOR_BOTTOM_RIGHT' :
  				return G_ANCHOR_BOTTOM_RIGHT;
  			break;
  			case 'G_ANCHOR_TOP_LEFT' :
  				return G_ANCHOR_TOP_LEFT;
  			break;
  			case 'G_ANCHOR_BOTTOM_LEFT' :
  				return G_ANCHOR_BOTTOM_LEFT;
  			break;
  		}
  		return;
  	},
  	mapControl: function(control) {
  		switch (control) {
  			case 'GLargeMapControl3D' :
  				return new GLargeMapControl3D();
  			break;
  			case 'GLargeMapControl' :
  				return new GLargeMapControl();
  			break;
  			case 'GSmallMapControl' :
  				return new GSmallMapControl();
  			break;
  			case 'GSmallZoomControl3D' :
  				return new GSmallZoomControl3D();
  			break;
  			case 'GSmallZoomControl' :
  				return new GSmallZoomControl();
  			break;
  			case 'GScaleControl' :
  				return new GScaleControl();
  			break;
  			case 'GMapTypeControl' :
  				return new GMapTypeControl();
  			break;
  			case 'GHierarchicalMapTypeControl' :
  				return new GHierarchicalMapTypeControl();
  			break;
  			case 'GOverviewMapControl' :
  				return new GOverviewMapControl();
  			break;
  			case 'GNavLabelControl' :
  				return new GNavLabelControl();
  			break;
  		}
  		return;
  	},
  	mapTypeControl: function(type) {
  		switch ( type ) {
  			case 'G_NORMAL_MAP' :
  				return G_NORMAL_MAP;
  			break;
  			case 'G_SATELLITE_MAP' :
  				return G_SATELLITE_MAP;
  			break;
  			case 'G_HYBRID_MAP' :
  				return G_HYBRID_MAP;
  			break;
  		}
  		return;
  	},
  	mapControls: function(options) {
  		// Default Controls Options
  		controlsDefaults = {
  			type: {
  				location: 'G_ANCHOR_TOP_RIGHT',
  				x: 10,
  				y: 10,
  				control: 'GMapTypeControl'
  			},
  			zoom: {
  				location: 'G_ANCHOR_TOP_LEFT',
  				x: 10,
  				y: 10,
  				control: 'GLargeMapControl3D'
  			}
  		};
  		// Merge the User & Default Options
  		options = $.extend({}, controlsDefaults, options);
  		options.type = $.extend({}, controlsDefaults.type, options.type);
  		options.zoom = $.extend({}, controlsDefaults.zoom, options.zoom);
  		
  		if ( options.type ) {
  			var controlLocation = $.googleMaps.mapControlsLocation(options.type.location);
  			var controlPosition = new GControlPosition(controlLocation, new GSize(options.type.x, options.type.y));
  			$.googleMaps.gMap.addControl($.googleMaps.mapControl(options.type.control), controlPosition);
  		}
  		if ( options.zoom ) {
  			var controlLocation = $.googleMaps.mapControlsLocation(options.zoom.location);
  			var controlPosition = new GControlPosition(controlLocation, new GSize(options.zoom.x, options.zoom.y))
  			$.googleMaps.gMap.addControl($.googleMaps.mapControl(options.zoom.control), controlPosition);
  		}
  		if ( options.mapType ) {
  			if ( options.mapType.length >= 1 ) {
  				for ( i = 0; i<options.mapType.length; i++) {
  					if ( options.mapType[i].remove )
  						$.googleMaps.gMap.removeMapType($.googleMaps.mapTypeControl(options.mapType[i].remove));
  					if ( options.mapType[i].add )
  						$.googleMaps.gMap.addMapType($.googleMaps.mapTypeControl(options.mapType[i].add));
  				}
  			} 
  			else {
  				if ( options.mapType.add )
  					$.googleMaps.gMap.addMapType($.googleMaps.mapTypeControl(options.mapType.add));
  				if ( options.mapType.remove )
  					$.googleMaps.gMap.removeMapType($.googleMaps.mapTypeControl(options.mapType.remove));
  			}
  		}
  	},
  	geoCode: function(options) {
  		geocoder = new GClientGeocoder();
  		
  		geocoder.getLatLng(options.address, function(point) {
  			if (!point)
  				alert(address + " not found");
  			else
            		$.googleMaps.gMap.setCenter(point, options.depth);
        	});
  	}
  };
})(jQuery); // Call and execute the function immediately passing the jQuery object
