/*
 ### 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
 ###
*/
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();
        }
        
        // 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);
        });
    }
};
