function AdfRepositionable(floatingElement, handle) {
  this.Init(floatingElement, handle)
}
AdfObject.createSubclass(AdfRepositionable);
AdfRepositionable.InitClass = function() {
  var prototype = this.prototype;
  prototype.NORMAL = 0;
  prototype.START_DRAGGING = 1;
  prototype.DRAGGING = 2
};
AdfRepositionable.prototype.Init = function(floatingElement, handle) {
  AdfRepositionable.superclass.Init.call(this);
  this._floatingElement = floatingElement;
  this._handle = handle;
  var agent = AdfAgent.AGENT;
  this._mousedownStub = this.createCallback(this._mouseDownHandler);
  this._mousemoveStub = this.createCallback(this._mouseMoveHandler);
  this._mouseupStub = this.createCallback(this._stopDragging);
  var cap = agent.getCapabilities();
  agent.addBubbleEventListener(this._handle, "touchstart", this._mousedownStub);
  agent.addBubbleEventListener(this._handle, "mousedown", this._mousedownStub);
  agent.disableUserSelect(handle);
  this._originalTopPosition = null;
  this._originalLeftPosition = null;
  this._mouseStartX = null;
  this._mouseStartY = null;
  this._state = this.NORMAL
};
AdfRepositionable.prototype.destroy = function() {
  var agent = AdfAgent.AGENT;
  agent.removeBubbleEventListener(this._handle, "touchstart", this._mousedownStub);
  agent.removeBubbleEventListener(this._handle, "mousedown", this._mousedownStub);
  if(this._state != this.NORMAL) {
    AdfPage.PAGE.stopDrag()
  }
};
AdfRepositionable.prototype.getElement = function() {
  return this._floatingElement.getElement()
};
AdfRepositionable.prototype._mouseDownHandler = function(evt) {
  var page = AdfPage.PAGE;
  if(page.isDragging()) {
    return
  }
  var agent = AdfAgent.AGENT;
  evt = evt || agent.getDomWindow().event;
  var isMouseEvent = evt instanceof MouseEvent;
  if(isMouseEvent && !agent.isLeftButton(evt)) {
    return
  }
  this._state = this.START_DRAGGING;
  agent.preventDefault(evt);
  var target = agent.getEventTarget(evt);
  var dismissalManager = AdfPage.PAGE.getAutoDismissalManager();
  dismissalManager.dismiss(target);
  if(agent.getPlatform() == AdfAgent.IE_PLATFORM) {
    var handle = this._handle;
    try {
      handle.setActive()
    }catch(e) {
      AdfLogger.LOGGER.fine("Could not restore focus to handle:", handle.id ? handle.id : "unknown")
    }
  }
  page.startDrag(evt, this._mousemoveStub, this._mouseupStub, null, true)
};
AdfRepositionable.prototype._mouseMoveHandler = function(evt, deltaX, deltaY) {
  var agent = AdfAgent.AGENT;
  var pos = agent.getMousePosition(evt);
  if(this._state == this.START_DRAGGING) {
    this._onDragStart.apply(this._floatingElement);
    this._state = this.DRAGGING;
    this._mouseStartX = pos.x;
    this._mouseStartY = pos.y;
    this._originalLeftPosition = parseInt(this._floatingElement.getLeft());
    this._originalTopPosition = parseInt(this._floatingElement.getTop());
    this._moveDeltaX = 0;
    this._moveDeltaY = 0;
    if(!this._originalLeftPosition) {
      this._originalLeftPosition = 0
    }
    if(!this._originalTopPosition) {
      this._originalTopPosition = 0
    }
    var domDocument = AdfPage.PAGE.getDomDocument();
    var documentElement = domDocument.documentElement;
    var isIE = agent.getPlatform() == AdfAgent.IE_PLATFORM;
    var isRTL = AdfPage.PAGE.getLocaleContext().isRightToLeft();
    var domWindow = agent.getDomWindow();
    var windowWidth = agent.getWindowScrollWidth(domWindow);
    var windowHeight = agent.getWindowScrollHeight(domWindow);
    var shadowSize = AdfDhtmlShadowDecorator.getShadowSize();
    var minLeft = isRTL ? shadowSize : 0;
    if(isIE && isRTL) {
      var adjustment = documentElement.scrollWidth - documentElement.clientWidth;
      minLeft -= adjustment;
      windowWidth -= adjustment
    }
    this._minLeft = minLeft;
    var el = this.getElement();
    this._wiggleWidth = windowWidth - el.offsetWidth - 2 * shadowSize;
    this._wiggleHeight = windowHeight - el.offsetHeight - 2 * shadowSize
  }
  if(this._state == this.DRAGGING) {
    var moveDeltaX = this._moveDeltaX += deltaX;
    var moveDeltaY = this._moveDeltaY += deltaY;
    this._move(moveDeltaX, moveDeltaY)
  }
};
AdfRepositionable.prototype._stopDragging = function(evt, deltaX, deltaY) {
  this._originalLeftPosition = null;
  this._originalTopPosition = null;
  this._mouseStartX = null;
  this._mouseStartY = null;
  if(this._state == this.DRAGGING) {
    this._onDragEnd.apply(this._floatingElement)
  }
  this._state = this.NORMAL
};
AdfRepositionable.prototype._move = function(deltaX, deltaY) {
  var newLeft = this._originalLeftPosition + deltaX;
  var newTop = this._originalTopPosition + deltaY;
  var minLeft = this._minLeft;
  var wiggleWidth = this._wiggleWidth;
  var wiggleHeight = this._wiggleHeight;
  if(newLeft > minLeft) {
    newLeft = Math.min(newLeft, wiggleWidth)
  }else {
    newLeft = minLeft
  }
  if(newTop > 0) {
    newTop = Math.min(newTop, wiggleHeight)
  }else {
    newTop = 0
  }
  this._floatingElement.setPosition(newTop, newLeft);
  this._onDrag()
};
AdfRepositionable.prototype.setDragStartHandler = function(handler) {
  this._onDragStart = handler
};
AdfRepositionable.prototype.setDragEndHandler = function(handler) {
  this._onDragEnd = handler
};
AdfRepositionable.prototype.setDragHandler = function(handler) {
  this._onDrag = handler
};
AdfRepositionable.prototype._onDragStart = function() {
};
AdfRepositionable.prototype._onDragEnd = function() {
};
AdfRepositionable.prototype._onDrag = function() {
};
