(function($, g){

	var geo = new google.maps.Geocoder();

	function resolve_address( address, callback ) {
		if( address == null || address.trim() == '' ) {
			return false;
		}

		/* matches a valid lat/long value */
		var position = address.match( /^([-+]?[1-8]?\d(\.\d+)?|90(\.0+)?),?\s*([-+]?180(\.0+)?|[-+]?((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$/ );
		if( $.isArray( position ) ) {
			callback( new google.maps.LatLng( position[1], position[4] ) );
		} else {
			geo.geocode( { 'address': address }, function( results, status ) {
				if (status == google.maps.GeocoderStatus.OK) {
					callback( results[0].geometry.location );
				}
				return null;
			});
		}
	}

	function add_new_marker( address, title, image, map ) {
		resolve_address( address, function( position ) {
			var marker = new google.maps.Marker({
				map : map,
				position: position,
				icon : image
			});

			if( title.trim() != '' ) {
				var infowindow = new google.maps.InfoWindow({
					content: '<div class="maps-pro-content">' + title + '</div>'
				});
				google.maps.event.addListener( marker, 'click', function() {
					infowindow.open( map, marker );
				});
			}
		} );
	}

	function do_maps( context ) {
		$( '.module.module-maps-pro' ).each(function(){
			if( $( this ).find( '.maps-pro-canvas' ).length < 1 ) {
				return;
			}

			var $this = $( this ),
				config = $this.data( 'config' ),
				map_options = {};

			map_options.zoom = parseInt( config.zoom );
			map_options.center = new google.maps.LatLng( -34.397, 150.644 );
			map_options.mapTypeId = google.maps.MapTypeId[ config.type ];
			map_options.scrollwheel = config.scrollwheel == 'enable';
			map_options.draggable = config.draggable == 'enable';
			map_options.disableDefaultUI = config.disable_map_ui == 'yes';

			if( config.style_map != '' ) {
				map_options.styles = map_pro_styles[config.style_map];
			}
			var node = $this.find( '.maps-pro-canvas' );
			var map = new google.maps.Map( node[0], map_options );

			/* store a copy of the map object in the dom node, for future reference */
			node.data( 'gmap_object', map );

			resolve_address( config.address, function( position ) {
				map.setCenter( position );
			} );

			/* add map markers */
			var markers = $this.find( '.maps-pro-marker' );
			function setup_markers( i ) {
				var marker = $( markers[i] ); // get single marker
				add_new_marker( marker.data( 'address' ), marker.html(), marker.data( 'image' ), map );
				if ( i < markers.length ) {
					setTimeout( function(){
						i++;
						setup_markers( i );
					}, 350 ); /* wait 350ms before loading the new marker */
				}
			}
			setup_markers( 0 );
		});
	}

	$( window ).load( do_maps );
	$( 'body' ).on( 'builder_load_module_partial', do_maps );
	$( 'body' ).on( 'builder_toggle_frontend', do_maps );

	/* reload the map when switching tabs (Builder Tabs module) */
	$( 'body' ).on( 'tf_tabs_switch', function( e, activeTab, tabs ){
		if ( $(activeTab).find( '.module-maps-pro' ).length > 0 ) {
			$(activeTab).find( '.module-maps-pro' ).each(function(){
				var mapInit = $(this).find( '.map-container' ).data( 'gmap_object' ),
					center = mapInit.getCenter();
				google.maps.event.trigger( mapInit, 'resize' );
				mapInit.setCenter(center);
			});
		}
	} );

})(jQuery);