// $Id$

Drupal.onlinemap = {
  map: null,
  markers: [],
  icons: [],
  ajax_filter: '',
  ajax_request: null,
  // JSON response field mapping.
  fields: {
    ID: 0,
    LATITUDE: 1,
    LONGITUDE: 2,
    ICON: 3,
    TITLE: 4
  },

  /**
   * Load and display the map.
   */
  initialize: function(filter) {
    var self = this;
    this.ajax_filter = filter;
    this.markers = [];
    // FIXME: Used for ExtLargeMapControl.
    //this.mapsLoaded();
    google.load('maps', '2', { 'callback': function() {
      self.mapsLoaded();
    }});
  },

  /**
   * Initialize map after the Google maps code has been loaded.
   */
  mapsLoaded: function() {
    var self = this;
    var i;

    $(window).unload(google.maps.Unload);

    // @todo Setting
    var centerLatitude = 30;
    var centerLongitude = 0;
    var startZoom = 2;
    this.map = new google.maps.Map2(document.getElementById('onlinemap-gmap'), { mapTypes: [G_PHYSICAL_MAP] });
    this.map.addControl(new google.maps.LargeMapControl());
    //this.map.addControl(new google.maps.MapTypeControl());
    //var extLargeMapControl = new ExtLargeMapControl();
    //this.map.addControl(extLargeMapControl);
    this.map.setCenter(new google.maps.LatLng(centerLatitude, centerLongitude), startZoom);

    var mapTypes = this.map.getMapTypes();
    for (i = 0; i < mapTypes.length; i++) {
      mapTypes[i].getMinimumResolution = function() {
        return 2;
      }
      if (Drupal.settings.onlinemap && Drupal.settings.onlinemap.max_resolution) {
        mapTypes[i].getMaximumResolution = function() {
          return Drupal.settings.onlinemap.max_resolution;
        }
      }
    }

    // @todo Setting
    var iconWidth = 6;
    for (i = 1; i <= 10; i++) {
      this.icons[i] = new google.maps.Icon();
      this.icons[i].image = '/sites/all/modules/onlinemap/images/dotm' + i + '.png';
      this.icons[i].iconSize = new google.maps.Size(iconWidth, iconWidth);
      this.icons[i].iconAnchor = new google.maps.Point(iconWidth / 2, iconWidth / 2);
    }

    google.maps.Event.addListener(this.map, 'moveend', function() {
      self.newViewport();
    });

    this.newViewport();

    // Fix Safari offset issue.
    if ($.browser.safari) {
      window.scrollTo(0, 0);
    }
  },

  /**
   * Request new markers for current viewport dimensions.
   */
  newViewport: function() {
    var self = this;
    var viewport = this.map.getBounds();

    // Extend the bounds by a proportion in each direction.
    // @todo Setting
    var extend_proportion = .1;
    var extend_lat_range = (viewport.getNorthEast().lat() - viewport.getSouthWest().lat()) * extend_proportion;
    var extend_lng_range = (viewport.getNorthEast().lng() - viewport.getSouthWest().lng()) * extend_proportion;

    viewport.extend(new google.maps.LatLng(viewport.getSouthWest().lat() - extend_lat_range, viewport.getSouthWest().lng() - extend_lng_range));
    viewport.extend(new google.maps.LatLng(viewport.getNorthEast().lat() + extend_lat_range, viewport.getNorthEast().lng() + extend_lng_range));

    if (this.ajax_request) {
      this.ajax_request.abort();
    }
    this.ajax_request = $.ajax({
      url: '/js/onlinemap/json',
      data: 'sw=' + viewport.getSouthWest().toUrlValue(4) + '&ne=' + viewport.getNorthEast().toUrlValue(4) + (self.ajax_filter ? '&' + self.ajax_filter : ''),
      dataType: 'json',
      success: function(data) {
        if (data) {
          self.setMarkers(data);
        }
      }
    });
  },

  /**
   * Add new markers to map.
   */
  setMarkers: function(data) {
    var i;
    var old_markers = [];

    for (i in this.markers) {
      old_markers[i] = i;
    }

    for (i = 0; i < data.length; i++) {
      var id = data[i][Drupal.onlinemap.fields.ID];
      if (old_markers[id]) {
        // Marker already on the map.
        delete old_markers[id];
      } else {
        this.map.addOverlay(this.markers[id] = this.createMarker(data[i]));
      }
    }

    // Zap remaining old markers.
    for (i in old_markers) {
      this.map.removeOverlay(this.markers[i]);
      delete this.markers[i];
    }
  },

  /**
   * Create a marker from received point data.
   */
  createMarker: function(pointData) {
    var loc = new google.maps.LatLng(pointData[Drupal.onlinemap.fields.LATITUDE], pointData[Drupal.onlinemap.fields.LONGITUDE]);
    return new google.maps.Marker(loc, { icon: this.icons[pointData[Drupal.onlinemap.fields.ICON]], title: pointData[Drupal.onlinemap.fields.TITLE], clickable: false });
  }
};
// $Id$

Drupal.behaviors = Drupal.behaviors || {};

/**
 * This function looks for swfobject class items and loads them
 * as swfobjects.
 */
Drupal.behaviors.SWFObject = function(context) {
  // get each swf div that needs to be processed
  $('.swfobject:not(.swfobjectInit-processed)', context).each(function () {     
    var config = Drupal.settings.swfobject_api['files'][$(this).attr('id')];
    swfobject.embedSWF(config.url, $(this).attr('id'), config.width, config.height, config.version, config.express_redirect, config.flashVars, config.params, config.attributes);
    // set this item to processed
    $(this).addClass('swfobjectInit-processed');
  });
}

$(document).ready( function () {
  Drupal.behaviors.SWFObject(document);
});
