// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/**
 * @unrestricted
 */
export default class ResizerWidget extends Common.Object {
  constructor() {
    super();

    this._isEnabled = true;
    this._elements = [];
    this._installDragOnMouseDownBound = this._installDragOnMouseDown.bind(this);
    this._cursor = 'nwse-resize';
  }

  /**
   * @return {boolean}
   */
  isEnabled() {
    return this._isEnabled;
  }

  /**
   * @param {boolean} enabled
   */
  setEnabled(enabled) {
    this._isEnabled = enabled;
    this.updateElementCursors();
  }

  /**
   * @return {!Array.<!Element>}
   */
  elements() {
    return this._elements.slice();
  }

  /**
   * @param {!Element} element
   */
  addElement(element) {
    if (this._elements.indexOf(element) !== -1) {
      return;
    }

    this._elements.push(element);
    element.addEventListener('mousedown', this._installDragOnMouseDownBound, false);
    this._updateElementCursor(element);
  }

  /**
   * @param {!Element} element
   */
  removeElement(element) {
    if (this._elements.indexOf(element) === -1) {
      return;
    }

    this._elements.remove(element);
    element.removeEventListener('mousedown', this._installDragOnMouseDownBound, false);
    element.style.removeProperty('cursor');
  }

  updateElementCursors() {
    this._elements.forEach(this._updateElementCursor.bind(this));
  }

  /**
   * @param {!Element} element
   */
  _updateElementCursor(element) {
    if (this._isEnabled) {
      element.style.setProperty('cursor', this.cursor());
    } else {
      element.style.removeProperty('cursor');
    }
  }

  /**
   * @return {string}
   */
  cursor() {
    return this._cursor;
  }

  /**
   * @param {string} cursor
   */
  setCursor(cursor) {
    this._cursor = cursor;
    this.updateElementCursors();
  }

  /**
   * @param {!Event} event
   */
  _installDragOnMouseDown(event) {
    // Only handle drags of the nodes specified.
    if (this._elements.indexOf(event.target) === -1) {
      return false;
    }
    UI.elementDragStart(
        /** @type {!Element} */ (event.target), this._dragStart.bind(this), this._drag.bind(this),
        this._dragEnd.bind(this), this.cursor(), event);
  }

  /**
   * @param {!MouseEvent} event
   * @return {boolean}
   */
  _dragStart(event) {
    if (!this._isEnabled) {
      return false;
    }
    this._startX = event.pageX;
    this._startY = event.pageY;
    this.sendDragStart(this._startX, this._startY);
    return true;
  }

  /**
   * @param {number} x
   * @param {number} y
   */
  sendDragStart(x, y) {
    this.dispatchEventToListeners(Events.ResizeStart, {startX: x, currentX: x, startY: y, currentY: y});
  }

  /**
   * @param {!MouseEvent} event
   * @return {boolean}
   */
  _drag(event) {
    if (!this._isEnabled) {
      this._dragEnd(event);
      return true;  // Cancel drag.
    }

    this.sendDragMove(this._startX, event.pageX, this._startY, event.pageY, event.shiftKey);
    event.preventDefault();
    return false;  // Continue drag.
  }

  /**
   * @param {number} startX
   * @param {number} currentX
   * @param {number} startY
   * @param {number} currentY
   * @param {boolean} shiftKey
   */
  sendDragMove(startX, currentX, startY, currentY, shiftKey) {
    this.dispatchEventToListeners(
        Events.ResizeUpdate,
        {startX: startX, currentX: currentX, startY: startY, currentY: currentY, shiftKey: shiftKey});
  }

  /**
   * @param {!MouseEvent} event
   */
  _dragEnd(event) {
    this.dispatchEventToListeners(Events.ResizeEnd);
    delete this._startX;
    delete this._startY;
  }
}

/** @enum {symbol} */
export const Events = {
  ResizeStart: Symbol('ResizeStart'),
  ResizeUpdate: Symbol('ResizeUpdate'),
  ResizeEnd: Symbol('ResizeEnd')
};

/**
 * @unrestricted
 */
export class SimpleResizerWidget extends ResizerWidget {
  constructor() {
    super();
    this._isVertical = true;
  }

  /**
   * @return {boolean}
   */
  isVertical() {
    return this._isVertical;
  }

  /**
   * Vertical widget resizes height (along y-axis).
   * @param {boolean} vertical
   */
  setVertical(vertical) {
    this._isVertical = vertical;
    this.updateElementCursors();
  }

  /**
   * @override
   * @return {string}
   */
  cursor() {
    return this._isVertical ? 'ns-resize' : 'ew-resize';
  }

  /**
   * @override
   * @param {number} x
   * @param {number} y
   */
  sendDragStart(x, y) {
    const position = this._isVertical ? y : x;
    this.dispatchEventToListeners(Events.ResizeStart, {startPosition: position, currentPosition: position});
  }

  /**
   * @override
   * @param {number} startX
   * @param {number} currentX
   * @param {number} startY
   * @param {number} currentY
   * @param {boolean} shiftKey
   */
  sendDragMove(startX, currentX, startY, currentY, shiftKey) {
    if (this._isVertical) {
      this.dispatchEventToListeners(
          Events.ResizeUpdate, {startPosition: startY, currentPosition: currentY, shiftKey: shiftKey});
    } else {
      this.dispatchEventToListeners(
          Events.ResizeUpdate, {startPosition: startX, currentPosition: currentX, shiftKey: shiftKey});
    }
  }
}

/* Legacy exported object*/
self.UI = self.UI || {};

/* Legacy exported object*/
UI = UI || {};

/** @constructor */
UI.ResizerWidget = ResizerWidget;

/** @enum {symbol} */
UI.ResizerWidget.Events = Events;

/** @constructor */
UI.SimpleResizerWidget = SimpleResizerWidget;
