// Copyright 2017 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.

export default class GlassPane {
  constructor() {
    this._widget = new UI.Widget(true);
    this._widget.markAsRoot();
    this.element = this._widget.element;
    this.contentElement = this._widget.contentElement;
    this._arrowElement = UI.Icon.create('', 'arrow hidden');
    this.element.shadowRoot.appendChild(this._arrowElement);

    this.registerRequiredCSS('ui/glassPane.css');
    this.setPointerEventsBehavior(GlassPane.PointerEventsBehavior.PierceGlassPane);

    this._onMouseDownBound = this._onMouseDown.bind(this);
    /** @type {?function(!Event)} */
    this._onClickOutsideCallback = null;
    /** @type {?UI.Size} */
    this._maxSize = null;
    /** @type {?number} */
    this._positionX = null;
    /** @type {?number} */
    this._positionY = null;
    /** @type {?AnchorBox} */
    this._anchorBox = null;
    this._anchorBehavior = GlassPane.AnchorBehavior.PreferTop;
    this._sizeBehavior = GlassPane.SizeBehavior.SetExactSize;
    this._marginBehavior = GlassPane.MarginBehavior.DefaultMargin;
  }

  /**
   * @return {boolean}
   */
  isShowing() {
    return this._widget.isShowing();
  }

  /**
   * @param {string} cssFile
   */
  registerRequiredCSS(cssFile) {
    this._widget.registerRequiredCSS(cssFile);
  }

  /**
   * @param {?Element} element
   */
  setDefaultFocusedElement(element) {
    this._widget.setDefaultFocusedElement(element);
  }

  /**
   * @param {boolean} dimmed
   */
  setDimmed(dimmed) {
    this.element.classList.toggle('dimmed-pane', dimmed);
  }

  /**
   * @param {!GlassPane.PointerEventsBehavior} pointerEventsBehavior
   */
  setPointerEventsBehavior(pointerEventsBehavior) {
    this.element.classList.toggle(
        'no-pointer-events', pointerEventsBehavior !== GlassPane.PointerEventsBehavior.BlockedByGlassPane);
    this.contentElement.classList.toggle(
        'no-pointer-events', pointerEventsBehavior === GlassPane.PointerEventsBehavior.PierceContents);
  }

  /**
   * @param {?function(!Event)} callback
   */
  setOutsideClickCallback(callback) {
    this._onClickOutsideCallback = callback;
  }

  /**
   * @param {?UI.Size} size
   */
  setMaxContentSize(size) {
    this._maxSize = size;
    this._positionContent();
  }

  /**
   * @param {!GlassPane.SizeBehavior} sizeBehavior
   */
  setSizeBehavior(sizeBehavior) {
    this._sizeBehavior = sizeBehavior;
    this._positionContent();
  }

  /**
   * @param {?number} x
   * @param {?number} y
   * Position is relative to root element.
   */
  setContentPosition(x, y) {
    this._positionX = x;
    this._positionY = y;
    this._positionContent();
  }

  /**
   * @param {?AnchorBox} anchorBox
   * Anchor box is relative to the document.
   */
  setContentAnchorBox(anchorBox) {
    this._anchorBox = anchorBox;
    this._positionContent();
  }

  /**
   * @param {!GlassPane.AnchorBehavior} behavior
   */
  setAnchorBehavior(behavior) {
    this._anchorBehavior = behavior;
  }

  /**
   * @param {!GlassPane.MarginBehavior} behavior
   */
  setMarginBehavior(behavior) {
    this._marginBehavior = behavior;
    this._arrowElement.classList.toggle('hidden', behavior !== GlassPane.MarginBehavior.Arrow);
  }

  /**
   * @param {!Document} document
   */
  show(document) {
    if (this.isShowing()) {
      return;
    }
    // TODO(crbug.com/1006759): Extract the magic number
    // Deliberately starts with 3000 to hide other z-indexed elements below.
    this.element.style.zIndex = 3000 + 1000 * _panes.size;
    document.body.addEventListener('mousedown', this._onMouseDownBound, true);
    this._widget.show(document.body);
    _panes.add(this);
    this._positionContent();
  }

  hide() {
    if (!this.isShowing()) {
      return;
    }
    _panes.delete(this);
    this.element.ownerDocument.body.removeEventListener('mousedown', this._onMouseDownBound, true);
    this._widget.detach();
  }

  /**
   * @param {!Event} event
   */
  _onMouseDown(event) {
    if (!this._onClickOutsideCallback) {
      return;
    }
    const node = event.deepElementFromPoint();
    if (!node || this.contentElement.isSelfOrAncestor(node)) {
      return;
    }
    this._onClickOutsideCallback.call(null, event);
  }

  _positionContent() {
    if (!this.isShowing()) {
      return;
    }

    const showArrow = this._marginBehavior === GlassPane.MarginBehavior.Arrow;
    const gutterSize = showArrow ? 8 : (this._marginBehavior === GlassPane.MarginBehavior.NoMargin ? 0 : 3);
    const scrollbarSize = UI.measuredScrollbarWidth(this.element.ownerDocument);
    const arrowSize = 10;

    const container = _containers.get(/** @type {!Document} */ (this.element.ownerDocument));
    if (this._sizeBehavior === GlassPane.SizeBehavior.MeasureContent) {
      this.contentElement.positionAt(0, 0);
      this.contentElement.style.width = '';
      this.contentElement.style.maxWidth = '';
      this.contentElement.style.height = '';
      this.contentElement.style.maxHeight = '';
    }

    const containerWidth = container.offsetWidth;
    const containerHeight = container.offsetHeight;

    let width = containerWidth - gutterSize * 2;
    let height = containerHeight - gutterSize * 2;
    let positionX = gutterSize;
    let positionY = gutterSize;

    if (this._maxSize) {
      width = Math.min(width, this._maxSize.width);
      height = Math.min(height, this._maxSize.height);
    }

    if (this._sizeBehavior === GlassPane.SizeBehavior.MeasureContent) {
      const measuredRect = this.contentElement.getBoundingClientRect();
      const widthOverflow = height < measuredRect.height ? scrollbarSize : 0;
      const heightOverflow = width < measuredRect.width ? scrollbarSize : 0;
      width = Math.min(width, measuredRect.width + widthOverflow);
      height = Math.min(height, measuredRect.height + heightOverflow);
    }

    if (this._anchorBox) {
      const anchorBox = this._anchorBox.relativeToElement(container);
      let behavior = this._anchorBehavior;
      this._arrowElement.classList.remove('arrow-none', 'arrow-top', 'arrow-bottom', 'arrow-left', 'arrow-right');

      if (behavior === GlassPane.AnchorBehavior.PreferTop || behavior === GlassPane.AnchorBehavior.PreferBottom) {
        const top = anchorBox.y - 2 * gutterSize;
        const bottom = containerHeight - anchorBox.y - anchorBox.height - 2 * gutterSize;
        if (behavior === GlassPane.AnchorBehavior.PreferTop && top < height && bottom > top) {
          behavior = GlassPane.AnchorBehavior.PreferBottom;
        }
        if (behavior === GlassPane.AnchorBehavior.PreferBottom && bottom < height && top > bottom) {
          behavior = GlassPane.AnchorBehavior.PreferTop;
        }

        let arrowY;
        let enoughHeight = true;
        if (behavior === GlassPane.AnchorBehavior.PreferTop) {
          positionY = Math.max(gutterSize, anchorBox.y - height - gutterSize);
          const spaceTop = anchorBox.y - positionY - gutterSize;
          if (this._sizeBehavior === GlassPane.SizeBehavior.MeasureContent) {
            if (height > spaceTop) {
              this._arrowElement.classList.add('arrow-none');
              enoughHeight = false;
            }
          } else {
            height = Math.min(height, spaceTop);
          }
          this._arrowElement.setIconType('mediumicon-arrow-bottom');
          this._arrowElement.classList.add('arrow-bottom');
          arrowY = anchorBox.y - gutterSize;
        } else {
          positionY = anchorBox.y + anchorBox.height + gutterSize;
          const spaceBottom = containerHeight - positionY - gutterSize;
          if (this._sizeBehavior === GlassPane.SizeBehavior.MeasureContent) {
            if (height > spaceBottom) {
              this._arrowElement.classList.add('arrow-none');
              positionY = containerHeight - gutterSize - height;
              enoughHeight = false;
            }
          } else {
            height = Math.min(height, spaceBottom);
          }
          this._arrowElement.setIconType('mediumicon-arrow-top');
          this._arrowElement.classList.add('arrow-top');
          arrowY = anchorBox.y + anchorBox.height + gutterSize;
        }

        positionX = Math.max(gutterSize, Math.min(anchorBox.x, containerWidth - width - gutterSize));
        if (!enoughHeight) {
          positionX = Math.min(positionX + arrowSize, containerWidth - width - gutterSize);
        } else if (showArrow && positionX - arrowSize >= gutterSize) {
          positionX -= arrowSize;
        }
        width = Math.min(width, containerWidth - positionX - gutterSize);
        if (2 * arrowSize >= width) {
          this._arrowElement.classList.add('arrow-none');
        } else {
          let arrowX = anchorBox.x + Math.min(50, Math.floor(anchorBox.width / 2));
          arrowX = Number.constrain(arrowX, positionX + arrowSize, positionX + width - arrowSize);
          this._arrowElement.positionAt(arrowX, arrowY, container);
        }
      } else {
        const left = anchorBox.x - 2 * gutterSize;
        const right = containerWidth - anchorBox.x - anchorBox.width - 2 * gutterSize;
        if (behavior === GlassPane.AnchorBehavior.PreferLeft && left < width && right > left) {
          behavior = GlassPane.AnchorBehavior.PreferRight;
        }
        if (behavior === GlassPane.AnchorBehavior.PreferRight && right < width && left > right) {
          behavior = GlassPane.AnchorBehavior.PreferLeft;
        }

        let arrowX;
        let enoughWidth = true;
        if (behavior === GlassPane.AnchorBehavior.PreferLeft) {
          positionX = Math.max(gutterSize, anchorBox.x - width - gutterSize);
          const spaceLeft = anchorBox.x - positionX - gutterSize;
          if (this._sizeBehavior === GlassPane.SizeBehavior.MeasureContent) {
            if (width > spaceLeft) {
              this._arrowElement.classList.add('arrow-none');
              enoughWidth = false;
            }
          } else {
            width = Math.min(width, spaceLeft);
          }
          this._arrowElement.setIconType('mediumicon-arrow-right');
          this._arrowElement.classList.add('arrow-right');
          arrowX = anchorBox.x - gutterSize;
        } else {
          positionX = anchorBox.x + anchorBox.width + gutterSize;
          const spaceRight = containerWidth - positionX - gutterSize;
          if (this._sizeBehavior === GlassPane.SizeBehavior.MeasureContent) {
            if (width > spaceRight) {
              this._arrowElement.classList.add('arrow-none');
              positionX = containerWidth - gutterSize - width;
              enoughWidth = false;
            }
          } else {
            width = Math.min(width, spaceRight);
          }
          this._arrowElement.setIconType('mediumicon-arrow-left');
          this._arrowElement.classList.add('arrow-left');
          arrowX = anchorBox.x + anchorBox.width + gutterSize;
        }

        positionY = Math.max(gutterSize, Math.min(anchorBox.y, containerHeight - height - gutterSize));
        if (!enoughWidth) {
          positionY = Math.min(positionY + arrowSize, containerHeight - height - gutterSize);
        } else if (showArrow && positionY - arrowSize >= gutterSize) {
          positionY -= arrowSize;
        }
        height = Math.min(height, containerHeight - positionY - gutterSize);
        if (2 * arrowSize >= height) {
          this._arrowElement.classList.add('arrow-none');
        } else {
          let arrowY = anchorBox.y + Math.min(50, Math.floor(anchorBox.height / 2));
          arrowY = Number.constrain(arrowY, positionY + arrowSize, positionY + height - arrowSize);
          this._arrowElement.positionAt(arrowX, arrowY, container);
        }
      }
    } else {
      positionX = this._positionX !== null ? this._positionX : (containerWidth - width) / 2;
      positionY = this._positionY !== null ? this._positionY : (containerHeight - height) / 2;
      width = Math.min(width, containerWidth - positionX - gutterSize);
      height = Math.min(height, containerHeight - positionY - gutterSize);
      this._arrowElement.classList.add('arrow-none');
    }

    this.contentElement.style.width = width + 'px';
    if (this._sizeBehavior === GlassPane.SizeBehavior.SetExactWidthMaxHeight) {
      this.contentElement.style.maxHeight = height + 'px';
    } else {
      this.contentElement.style.height = height + 'px';
    }

    this.contentElement.positionAt(positionX, positionY, container);
    this._widget.doResize();
  }

  /**
   * @protected
   * @return {!UI.Widget}
   */
  widget() {
    return this._widget;
  }

  /**
   * @param {!Element} element
   */
  static setContainer(element) {
    _containers.set(/** @type {!Document} */ (element.ownerDocument), element);
    GlassPane.containerMoved(element);
  }

  /**
   * @param {!Document} document
   * @return {!Element}
   */
  static container(document) {
    return _containers.get(document);
  }

  /**
   * @param {!Element} element
   */
  static containerMoved(element) {
    for (const pane of _panes) {
      if (pane.isShowing() && pane.element.ownerDocument === element.ownerDocument) {
        pane._positionContent();
      }
    }
  }
}

/** @enum {symbol} */
export const PointerEventsBehavior = {
  BlockedByGlassPane: Symbol('BlockedByGlassPane'),
  PierceGlassPane: Symbol('PierceGlassPane'),
  PierceContents: Symbol('PierceContents')
};

/** @enum {symbol} */
export const AnchorBehavior = {
  PreferTop: Symbol('PreferTop'),
  PreferBottom: Symbol('PreferBottom'),
  PreferLeft: Symbol('PreferLeft'),
  PreferRight: Symbol('PreferRight'),
};

/** @enum {symbol} */
export const SizeBehavior = {
  SetExactSize: Symbol('SetExactSize'),
  SetExactWidthMaxHeight: Symbol('SetExactWidthMaxHeight'),
  MeasureContent: Symbol('MeasureContent')
};

/** @enum {symbol} */
export const MarginBehavior = {
  Arrow: Symbol('Arrow'),
  DefaultMargin: Symbol('DefaultMargin'),
  NoMargin: Symbol('NoMargin')
};

/** @type {!Map<!Document, !Element>} */
const _containers = new Map();

/** @type {!Set<!GlassPane>} */
const _panes = new Set();

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

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

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

/** @enum {symbol} */
UI.GlassPane.PointerEventsBehavior = PointerEventsBehavior;

/** @enum {symbol} */
UI.GlassPane.AnchorBehavior = AnchorBehavior;

/** @enum {symbol} */
UI.GlassPane.SizeBehavior = SizeBehavior;

/** @enum {symbol} */
UI.GlassPane.MarginBehavior = MarginBehavior;

/** @type {!Set<!GlassPane>} */
UI.GlassPane._panes = _panes;
