goog.provide('ol.interaction.Pointer');

goog.require('goog.asserts');
goog.require('goog.functions');
goog.require('goog.object');
goog.require('ol.MapBrowserEvent');
goog.require('ol.MapBrowserEvent.EventType');
goog.require('ol.MapBrowserPointerEvent');
goog.require('ol.Pixel');
goog.require('ol.ViewHint');
goog.require('ol.interaction.Interaction');



/**
 * Base class for pointer interactions.
 * @constructor
 * @extends {ol.interaction.Interaction}
 */
ol.interaction.Pointer = function() {

  goog.base(this);

  /**
   * @type {boolean}
   * @private
   */
  this.handlingDownUpSequence_ = false;

  /**
   * @type {Object.<number, ol.pointer.PointerEvent>}
   * @private
   */
  this.trackedPointers_ = {};

  /**
   * @type {Array.<ol.pointer.PointerEvent>}
   * @protected
   */
  this.targetPointers = [];

};
goog.inherits(ol.interaction.Pointer, ol.interaction.Interaction);


/**
 * @param {Array.<ol.pointer.PointerEvent>} pointerEvents
 * @return {ol.Pixel} Centroid pixel.
 */
ol.interaction.Pointer.centroid = function(pointerEvents) {
  var length = pointerEvents.length;
  var clientX = 0;
  var clientY = 0;
  for (var i = 0; i < length; i++) {
    clientX += pointerEvents[i].clientX;
    clientY += pointerEvents[i].clientY;
  }
  return [clientX / length, clientY / length];
};


/**
 * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
 * @return {boolean} Whether the event is a pointerdown, pointerdrag
 *     or pointerup event.
 * @private
 */
ol.interaction.Pointer.prototype.isPointerDraggingEvent_ =
    function(mapBrowserEvent) {
  var type = mapBrowserEvent.type;
  return (
      type === ol.MapBrowserEvent.EventType.POINTERDOWN ||
      type === ol.MapBrowserEvent.EventType.POINTERDRAG ||
      type === ol.MapBrowserEvent.EventType.POINTERUP);
};


/**
 * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
 * @private
 */
ol.interaction.Pointer.prototype.updateTrackedPointers_ =
    function(mapBrowserEvent) {
  if (this.isPointerDraggingEvent_(mapBrowserEvent)) {
    var event = mapBrowserEvent.pointerEvent;

    if (mapBrowserEvent.type == ol.MapBrowserEvent.EventType.POINTERUP) {
      delete this.trackedPointers_[event.pointerId];
    } else if (mapBrowserEvent.type ==
        ol.MapBrowserEvent.EventType.POINTERDOWN) {
      this.trackedPointers_[event.pointerId] = event;
    } else if (event.pointerId in this.trackedPointers_) {
      // update only when there was a pointerdown event for this pointer
      this.trackedPointers_[event.pointerId] = event;
    }
    this.targetPointers = goog.object.getValues(this.trackedPointers_);
  }
};


/**
 * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
 * @protected
 */
ol.interaction.Pointer.prototype.handlePointerDrag =
    goog.nullFunction;


/**
 * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
 * @protected
 * @return {boolean} Capture dragging.
 */
ol.interaction.Pointer.prototype.handlePointerUp =
    goog.functions.FALSE;


/**
 * @param {ol.MapBrowserPointerEvent} mapBrowserEvent Event.
 * @protected
 * @return {boolean} Capture dragging.
 */
ol.interaction.Pointer.prototype.handlePointerDown =
    goog.functions.FALSE;


/**
 * @inheritDoc
 */
ol.interaction.Pointer.prototype.handleMapBrowserEvent =
    function(mapBrowserEvent) {
  if (!(mapBrowserEvent instanceof ol.MapBrowserPointerEvent)) {
    return true;
  }

  var mapBrowserPointerEvent =
      /** @type {ol.MapBrowserPointerEvent} */ (mapBrowserEvent);

  var stopEvent = false;
  var view = mapBrowserEvent.map.getView();
  this.updateTrackedPointers_(mapBrowserPointerEvent);
  if (this.handlingDownUpSequence_) {
    if (mapBrowserPointerEvent.type ==
        ol.MapBrowserEvent.EventType.POINTERDRAG) {
      this.handlePointerDrag(mapBrowserEvent);
    } else if (mapBrowserPointerEvent.type ==
        ol.MapBrowserEvent.EventType.POINTERUP) {
      this.handlingDownUpSequence_ =
          this.handlePointerUp(mapBrowserPointerEvent);
      if (!this.handlingDownUpSequence_) {
        view.setHint(ol.ViewHint.INTERACTING, -1);
      }
    }
  }
  if (mapBrowserPointerEvent.type == ol.MapBrowserEvent.EventType.POINTERDOWN) {
    var handled = this.handlePointerDown(mapBrowserPointerEvent);
    if (!this.handlingDownUpSequence_ && handled) {
      view.setHint(ol.ViewHint.INTERACTING, 1);
    }
    this.handlingDownUpSequence_ = handled;
    stopEvent = this.shouldStopEvent(handled);
  }
  return !stopEvent;
};


/**
 * This method allows inheriting classes to stop the event from being
 * passed to further interactions. For example, this is required for
 * interaction `DragRotateAndZoom`.
 *
 * @protected
 * @param {boolean} handled Was the event handled by the interaction?
 * @return {boolean} Should the event be stopped?
 */
ol.interaction.Pointer.prototype.shouldStopEvent =
    goog.functions.FALSE;

@@ -543,37 +543,39 @@
 oolean%7D%0A   * @pr
-ivate
+otected
 %0A   */%0A  this.ha
@@ -594,17 +594,16 @@
 Sequence
-_
  = false
@@ -3630,29 +3630,28 @@
 wnUpSequence
-_
 ) %7B%0A
+
     if (mapB
@@ -3905,17 +3905,16 @@
 Sequence
-_
  =%0A     
@@ -4002,17 +4002,16 @@
 Sequence
-_
 ) %7B%0A    
@@ -4258,17 +4258,16 @@
 Sequence
-_
  && hand
@@ -4319,32 +4319,32 @@
 TING, 1);%0A    %7D%0A
+
     this.handlin
@@ -4358,17 +4358,16 @@
 Sequence
-_
  = handl

Change a property from private to protected