text: /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
   * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
   * full text of the license. */
  
  /**
   * @requires OpenLayers/Control/ZoomBox.js
   * @requires OpenLayers/Control/DragPan.js
   * @requires OpenLayers/Handler/MouseWheel.js
   * @requires OpenLayers/Handler/Click.js
   */
  
  /**
   * Class: OpenLayers.Control.Navigation
   * The navigation control handles map browsing with mouse events (dragging,
   *     double-clicking, and scrolling the wheel).  Create a new navigation 
   *     control with the <OpenLayers.Control.Navigation> control.  
   * 
   *     Note that this control is added to the map by default (if no controls 
   *     array is sent in the options object to the <OpenLayers.Map> 
   *     constructor).
   * 
   * Inherits:
   *  - <OpenLayers.Control>
   */
  OpenLayers.Control.Navigation = OpenLayers.Class(OpenLayers.Control, {
  
      /** 
       * Property: dragPan
       * {<OpenLayers.Control.DragPan>} 
       */
      dragPan: null,
  
      /**
       * APIProprety: dragPanOptions
       * {Object} Options passed to the DragPan control.
       */
      dragPanOptions: null,
  
      /**
       * APIProperty: documentDrag
       * {Boolean} Allow panning of the map by dragging outside map viewport.
       *     Default is false.
       */
      documentDrag: false,
  
      /** 
       * Property: zoomBox
       * {<OpenLayers.Control.ZoomBox>}
       */
      zoomBox: null,
  
      /**
       * APIProperty: zoomBoxEnabled
       * {Boolean} Whether the user can draw a box to zoom
       */
      zoomBoxEnabled: true, 
  
      /**
       * APIProperty: zoomWheelEnabled
       * {Boolean} Whether the mousewheel should zoom the map
       */
      zoomWheelEnabled: true,
      
      /**
       * Property: mouseWheelOptions
       * {Object} Options passed to the MouseWheel control (only useful if
       *     <zoomWheelEnabled> is set to true)
       */
      mouseWheelOptions: null,
  
      /**
       * APIProperty: handleRightClicks
       * {Boolean} Whether or not to handle right clicks. Default is false.
       */
      handleRightClicks: false,
  
      /**
       * APIProperty: zoomBoxKeyMask
       * {Integer} <OpenLayers.Handler> key code of the key, which has to be
       *    pressed, while drawing the zoom box with the mouse on the screen. 
       *    You should probably set handleRightClicks to true if you use this
       *    with MOD_CTRL, to disable the context menu for machines which use
       *    CTRL-Click as a right click.
       * Default: <OpenLayers.Handler.MOD_SHIFT
       */
      zoomBoxKeyMask: OpenLayers.Handler.MOD_SHIFT,
      
      /**
       * APIProperty: autoActivate
       * {Boolean} Activate the control when it is added to a map.  Default is
       *     true.
       */
      autoActivate: true,
  
      /**
       * Constructor: OpenLayers.Control.Navigation
       * Create a new navigation control
       * 
       * Parameters:
       * options - {Object} An optional object whose properties will be set on
       *                    the control
       */
      initialize: function(options) {
          this.handlers = {};
          OpenLayers.Control.prototype.initialize.apply(this, arguments);
      },
  
      /**
       * Method: destroy
       * The destroy method is used to perform any clean up before the control
       * is dereferenced.  Typically this is where event listeners are removed
       * to prevent memory leaks.
       */
      destroy: function() {
          this.deactivate();
  
          if (this.dragPan) {
              this.dragPan.destroy();
          }
          this.dragPan = null;
  
          if (this.zoomBox) {
              this.zoomBox.destroy();
          }
          this.zoomBox = null;
          OpenLayers.Control.prototype.destroy.apply(this,arguments);
      },
      
      /**
       * Method: activate
       */
      activate: function() {
          this.dragPan.activate();
          if (this.zoomWheelEnabled) {
              this.handlers.wheel.activate();
          }    
          this.handlers.click.activate();
          if (this.zoomBoxEnabled) {
              this.zoomBox.activate();
          }
          return OpenLayers.Control.prototype.activate.apply(this,arguments);
      },
  
      /**
       * Method: deactivate
       */
      deactivate: function() {
          this.zoomBox.deactivate();
          this.dragPan.deactivate();
          this.handlers.click.deactivate();
          this.handlers.wheel.deactivate();
          return OpenLayers.Control.prototype.deactivate.apply(this,arguments);
      },
      
      /**
       * Method: draw
       */
      draw: function() {
          // disable right mouse context menu for support of right click events
          if (this.handleRightClicks) {
              this.map.viewPortDiv.oncontextmenu = OpenLayers.Function.False;
          }
  
          var clickCallbacks = { 
              'dblclick': this.defaultDblClick, 
              'dblrightclick': this.defaultDblRightClick 
          };
          var clickOptions = {
              'double': true, 
              'stopDouble': true
          };
          this.handlers.click = new OpenLayers.Handler.Click(
              this, clickCallbacks, clickOptions
          );
          this.dragPan = new OpenLayers.Control.DragPan(
              OpenLayers.Util.extend({
                  map: this.map,
                  documentDrag: this.documentDrag
              }, this.dragPanOptions)
          );
          this.zoomBox = new OpenLayers.Control.ZoomBox(
                      {map: this.map, keyMask: this.zoomBoxKeyMask});
          this.dragPan.draw();
          this.zoomBox.draw();
          this.handlers.wheel = new OpenLayers.Handler.MouseWheel(
                                      this, {"up"  : this.wheelUp,
                                             "down": this.wheelDown},
                                      this.mouseWheelOptions );
      },
  
      /**
       * Method: defaultDblClick 
       * 
       * Parameters:
       * evt - {Event} 
       */
      defaultDblClick: function (evt) {
          var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); 
          this.map.setCenter(newCenter, this.map.zoom + 1);
      },
  
      /**
       * Method: defaultDblRightClick 
       * 
       * Parameters:
       * evt - {Event} 
       */
      defaultDblRightClick: function (evt) {
          var newCenter = this.map.getLonLatFromViewPortPx( evt.xy ); 
          this.map.setCenter(newCenter, this.map.zoom - 1);
      },
      
      /**
       * Method: wheelChange  
       *
       * Parameters:
       * evt - {Event}
       * deltaZ - {Integer}
       */
      wheelChange: function(evt, deltaZ) {
          var currentZoom = this.map.getZoom();
          var newZoom = this.map.getZoom() + Math.round(deltaZ);
          newZoom = Math.max(newZoom, 0);
          newZoom = Math.min(newZoom, this.map.getNumZoomLevels());
          if (newZoom === currentZoom) {
              return;
          }
          var size    = this.map.getSize();
          var deltaX  = size.w/2 - evt.xy.x;
          var deltaY  = evt.xy.y - size.h/2;
          var newRes  = this.map.baseLayer.getResolutionForZoom(newZoom);
          var zoomPoint = this.map.getLonLatFromPixel(evt.xy);
          var newCenter = new OpenLayers.LonLat(
                              zoomPoint.lon + deltaX * newRes,
                              zoomPoint.lat + deltaY * newRes );
          this.map.setCenter( newCenter, newZoom );
      },
  
      /** 
       * Method: wheelUp
       * User spun scroll wheel up
       * 
       * Parameters:
       * evt - {Event}
       * delta - {Integer}
       */
      wheelUp: function(evt, delta) {
          this.wheelChange(evt, delta || 1);
      },
  
      /** 
       * Method: wheelDown
       * User spun scroll wheel down
       * 
       * Parameters:
       * evt - {Event}
       * delta - {Integer}
       */
      wheelDown: function(evt, delta) {
          this.wheelChange(evt, delta || -1);
      },
      
      /**
       * Method: disableZoomBox
       */
      disableZoomBox : function() {
          this.zoomBoxEnabled = false;
          this.zoomBox.deactivate();       
      },
      
      /**
       * Method: enableZoomBox
       */
      enableZoomBox : function() {
          this.zoomBoxEnabled = true;
          if (this.active) {
              this.zoomBox.activate();
          }    
      },
      
      /**
       * Method: disableZoomWheel
       */
      
      disableZoomWheel : function() {
          this.zoomWheelEnabled = false;
          this.handlers.wheel.deactivate();       
      },
      
      /**
       * Method: enableZoomWheel
       */
      
      enableZoomWheel : function() {
          this.zoomWheelEnabled = true;
          if (this.active) {
              this.handlers.wheel.activate();
          }    
      },
  
      CLASS_NAME: "OpenLayers.Control.Navigation"
  });
  