/*
 * 
 * Google_mapper 1.0 - Simple Google maps.
 * Version 1.0
 * @requires jQuery v1.3.2
 * 
 * Copyright (c) 2009 Dana Woodman
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 * 
 */
/**
 *
 * @description         Create a google map on a page with one or many addresses. 
 *                      Can also add in an info window popup with configurable structure.
 * 
 * @example $(document).google_mapper({ addresses: [  latlng: { lat: 30, lng: 120 } ] });
 * @desc Creates a basic map.
 * 
 * @type jQuery
 *
 * @name google_mapper
 * 
 * @cat Plugins/Interface
 * 
 * @author Dana Woodman/woodman.dana@gmail.com
 */

(function($) {
    
    // The main function.
    $.fn.google_mapper = function(options) {
        var opts = $.extend({}, $.fn.google_mapper.defaults, options);
        return this.each(function() {
            
            var obj = $(this);
            
            // build element specific options
            obj.o = $.meta ? $.extend({}, opts, $this.data()) : opts;
            
            // Configure controls
            var options = {mapTypeId: google.maps.MapTypeId.ROADMAP};
            if (obj.o.controls['GSmallMapControl'] == true) {
                options['mapTypeControlOptions'] = {
                    style: google.maps.MapTypeControlStyle.DROPDOWN_MENU
                };
            }
            if (obj.o.controls['GMapTypeControl'] == false) {
                options['mapTypeControl'] = false;
            }

            // Create a new map object.
            var map = new google.maps.Map(document.getElementById(obj.o.map_container_id),
                options);
            
            if (obj.o.debug) {
                $.fn.google_mapper.debug('There are a total of ' + obj.o.addresses.length + ' address(es).');
            };
            
            if (obj.o.addresses.length == 1) { // Set map center, if there is only one locaiton.     
                if (obj.o.debug) { 
                    $.fn.google_mapper.debug('Centering map on lat: "' + obj.o.addresses[0].latlng.lat + '", lng: "' +  obj.o.addresses[0].latlng.lng + '" at default zoom level of ' + obj.o.default_zoom_level)
                };
                
                if (obj.o.addresses[0].latlng.lat && obj.o.addresses[0].latlng.lng) {
                    map.setCenter(new google.maps.LatLng(obj.o.addresses[0].latlng.lat, obj.o.addresses[0].latlng.lng));
                    map.setZoom(obj.o.default_zoom_level);
                }
            } else { // Set map center, if there is more than one locaiton.
                var bounds = new google.maps.LatLngBounds();
                
                // Extend the bounds for each address till they are each in view.
                for (i in obj.o.addresses) {
                    var loc = obj.o.addresses[i].latlng;
                    var latlng = new google.maps.LatLng(loc.lat, loc.lng);
                    bounds.extend(latlng);
                };
                
                // Zoom to bounds of items.
                map.fitBounds(bounds);
            };
            
            // Create info window
            var infowindow = new google.maps.InfoWindow({
                content: ''
            });
            
            // Loop through each address and map it.
            $.each(obj.o.addresses, function(index) {
                var add = this;
                if (obj.o.debug) {
                    $.fn.google_mapper.debug('Address ' + index + ': lat: "' + add.latlng.lat + '", lng: "' + add.latlng.lng + '"');
                };
                
                // Lat-lng pair was supplied, map it.
                if (add.latlng.lat && add.latlng.lng) {
                    if (obj.o.debug) {
                        $.fn.google_mapper.debug('Mapping address ' + index);
                    };
                    var point = new google.maps.LatLng(add.latlng.lat, add.latlng.lng);
                    var marker = new google.maps.Marker({position: point, map: map});
                    if (add.info_window_data) {
                        if (obj.o.debug) {
                            $.fn.google_mapper.debug('Address ' + index + ' has info window data.');
                            $.fn.google_mapper.debug('Adding event listener for address ' + index + '. Waiting for a "' + obj.o.info_window_event + '" event.');
                        };
                        google.maps.event.addListener(marker, 'click', function() {
                            if (obj.o.debug) {
                                $.fn.google_mapper.debug('Address ' + index + ' has info window data.');
                            };
                            infowindow.close();
                            infowindow.setContent($.fn.google_mapper.make_info_window(add));
                            infowindow.open(map, marker);
                        });
                    };
                }
            });
        });
    };
    
    // Constructs the "Info Window" popup that is show when a marker is clicked.
    $.fn.google_mapper.make_info_window = function(address_object) {
        var add = address_object;
        var html = '<div class="map-popup-cont">' + 
            '<h6 class="mtn"><a href="' + add.info_window_data.url + '" title="View ' + add.info_window_data.name + '\'s page">' + add.info_window_data.name + '</a></h6>' + 
            '<address>' + add.info_window_data.add1 + ' ' + add.info_window_data.add2 + '<br />' + add.info_window_data.city + ', ' + add.info_window_data.state + '<br />' + add.info_window_data.zip +
            '</address>' + 
            '</div>';
        return html;
    };
    
    // A debug function for the google_mapper that checks to see if the console is available for writing. If it's not, default to an alert.
    $.fn.google_mapper.debug = function(string) {
        if (window.console && window.console.log) {
            console.log(string);
        }
        else {
            alert(string);
        };
    };
    
    // The google_mapper defaults, can be overridden in the function itself.
    $.fn.google_mapper.defaults = {
        map_container_id: 'google-map-container',
        controls: {
            GSmallMapControl: true,
            GMapTypeControl: true
        },
        addresses: [
            {
                real_address: null,
                latlng: {
                    lat: null, // The latitude of the address.
                    lng: null // The lngititude of the address.
                },
                info_window_data: {} // An Object containing the content to display in the "Info Window" popup.
            }
        ],
        default_zoom_level: 14,
        info_window_event: 'click', // Can be any valid jQuery event: 'click', 'hover', etc...
        debug: false
    };
    
})(jQuery);

