/*
 * DesalData Specific jQuery Google Maps Plugin
 *
 * 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 = {

    // Returns the bounds of the map view
    bounds: function() {
      return $.googleMaps.gMap.getBounds();
    },

    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(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(markers) {
      if ( typeof(markers.length) == 'undefined' ) {
        // One marker only. Parse it into an array for consistency.
        markers = [markers];
      }

      var gmarkers = [];
      $.each(markers, function(marker) {
        marker = markers[marker];
        var gIcon = null;
        if ( marker.icon ) {
          gIcon = $.googleMaps.mapMarkersOptions(marker.icon);
        }

        var gmarker = null;
        if ( marker.geocode ) {
          var geocoder = new GClientGeocoder();
          geocoder.getLatLng(marker.geocode, function(center) {
            if (!center) {
              alert(address + " not found");
            } else {
              gmarker = new GMarker(center, {draggable: marker.draggable, icon: gIcon});
            }
          });
        } else if ( marker.latitude && marker.longitude ) {
          // Latitude & Longitude Center Point
          var center = $.googleMaps.mapLatLong(marker.latitude, marker.longitude);
          gmarker = new GMarker(center, {draggable: marker.draggable, icon: gIcon});
        }

        $.googleMaps.gMap.addOverlay(gmarker);
        if ( marker.info ) {
          // Hide Div Layer With Info Window HTML
          $(marker.info.layer).hide();
          // Marker Div Layer Exists
          if ( marker.info.popup ) {
            // Map Marker Shows an Info Box on Load
            gmarker.openInfoWindowHtml($(marker.info.layer).html());
          } else {
            gmarker.bindInfoWindowHtml( $(marker.info.layer).html().toString() );
          }
        }

        gmarkers.push(gmarker);
      });
      return gmarkers;
    },

    click: function(gObject, click_function) {
      GEvent.addListener(gObject, 'click', click_function);
    },

    hover: function(gObject, mouseover_function, mouseout_function) {
      GEvent.addListener(gObject, 'mouseover', mouseover_function);
      GEvent.addListener(gObject, 'mouseout', mouseout_function);
    },

    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);
