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

/**
 * @typedef {{
 *   top: (number|undefined),
 *   left: (number|undefined),
 *   width: (number|undefined),
 *   height: (number|undefined),
 *   anchorAlignmentX: (number|undefined),
 *   anchorAlignmentY: (number|undefined),
 *   minX: (number|undefined),
 *   minY: (number|undefined),
 *   maxX: (number|undefined),
 *   maxY: (number|undefined),
 * }}
 */
let ShowAtConfig;

/**
 * @typedef {{
 *   top: number,
 *   left: number,
 *   width: (number|undefined),
 *   height: (number|undefined),
 *   anchorAlignmentX: (number|undefined),
 *   anchorAlignmentY: (number|undefined),
 *   minX: (number|undefined),
 *   minY: (number|undefined),
 *   maxX: (number|undefined),
 *   maxY: (number|undefined),
 * }}
 */
let ShowAtPositionConfig;

/**
 * @enum {number}
 * @const
 */
const AnchorAlignment = {
  BEFORE_START: -2,
  AFTER_START: -1,
  CENTER: 0,
  BEFORE_END: 1,
  AFTER_END: 2,
};

/** @const {string} */
const DROPDOWN_ITEM_CLASS = 'dropdown-item';

(function() {

/** @const {number} */
const AFTER_END_OFFSET = 10;

/**
 * Returns the point to start along the X or Y axis given a start and end
 * point to anchor to, the length of the target and the direction to anchor
 * in. If honoring the anchor would force the menu outside of min/max, this
 * will ignore the anchor position and try to keep the menu within min/max.
 * @private
 * @param {number} start
 * @param {number} end
 * @param {number} menuLength
 * @param {AnchorAlignment} anchorAlignment
 * @param {number} min
 * @param {number} max
 * @return {number}
 */
function getStartPointWithAnchor(
    start, end, menuLength, anchorAlignment, min, max) {
  let startPoint = 0;
  switch (anchorAlignment) {
    case AnchorAlignment.BEFORE_START:
      startPoint = -menuLength;
      break;
    case AnchorAlignment.AFTER_START:
      startPoint = start;
      break;
    case AnchorAlignment.CENTER:
      startPoint = (start + end - menuLength) / 2;
      break;
    case AnchorAlignment.BEFORE_END:
      startPoint = end - menuLength;
      break;
    case AnchorAlignment.AFTER_END:
      startPoint = end;
      break;
  }

  if (startPoint + menuLength > max) {
    startPoint = end - menuLength;
  }
  if (startPoint < min) {
    startPoint = start;
  }

  startPoint = Math.max(min, Math.min(startPoint, max - menuLength));

  return startPoint;
}

/**
 * @private
 * @return {!ShowAtPositionConfig}
 */
function getDefaultShowConfig() {
  const doc = document.scrollingElement;
  return {
    top: 0,
    left: 0,
    height: 0,
    width: 0,
    anchorAlignmentX: AnchorAlignment.AFTER_START,
    anchorAlignmentY: AnchorAlignment.AFTER_START,
    minX: 0,
    minY: 0,
    maxX: 0,
    maxY: 0,
  };
}

Polymer({
  is: 'cr-action-menu',

  /**
   * The element which the action menu will be anchored to. Also the element
   * where focus will be returned after the menu is closed. Only populated if
   * menu is opened with showAt().
   * @private {?Element}
   */
  anchorElement_: null,

  /**
   * Bound reference to an event listener function such that it can be removed
   * on detach.
   * @private {?Function}
   */
  boundClose_: null,

  /** @private {boolean} */
  hasMousemoveListener_: false,

  /** @private {?PolymerDomApi.ObserveHandle} */
  contentObserver_: null,

  /** @private {?ResizeObserver} */
  resizeObserver_: null,

  /** @private {?ShowAtPositionConfig} */
  lastConfig_: null,

  properties: {
    // Setting this flag will make the menu listen for content size changes and
    // reposition to its anchor accordingly.
    autoReposition: {
      type: Boolean,
      value: false,
    },

    open: {
      type: Boolean,
      value: false,
    },

    ariaLabel: String,
  },

  listeners: {
    'keydown': 'onKeyDown_',
    'mouseover': 'onMouseover_',
    'tap': 'onTap_',
  },

  /** override */
  detached: function() {
    this.removeListeners_();
  },

  /**
   * Exposing internal <dialog> elements for tests.
   * @return {!HTMLDialogElement}
   */
  getDialog: function() {
    return this.$.dialog;
  },

  /** @private */
  removeListeners_: function() {
    window.removeEventListener('resize', this.boundClose_);
    window.removeEventListener('popstate', this.boundClose_);
    if (this.contentObserver_) {
      Polymer.dom(this.$.contentNode).unobserveNodes(this.contentObserver_);
      this.contentObserver_ = null;
    }

    if (this.resizeObserver_) {
      this.resizeObserver_.disconnect();
      this.resizeObserver_ = null;
    }
  },

  /**
   * @param {!Event} e
   * @private
   */
  onNativeDialogClose_: function(e) {
    // Ignore any 'close' events not fired directly by the <dialog> element.
    if (e.target !== this.$.dialog) {
      return;
    }

    // TODO(dpapad): This is necessary to make the code work both for Polymer 1
    // and Polymer 2. Remove once migration to Polymer 2 is completed.
    e.stopPropagation();

    // Catch and re-fire the 'close' event such that it bubbles across Shadow
    // DOM v1.
    this.fire('close');
  },

  /**
   * @param {!Event} e
   * @private
   */
  onTap_: function(e) {
    if (e.target == this) {
      this.close();
      e.stopPropagation();
    }
  },

  /**
   * @param {!KeyboardEvent} e
   * @private
   */
  onKeyDown_: function(e) {
    e.stopPropagation();

    if (e.key == 'Tab' || e.key == 'Escape') {
      this.close();
      e.preventDefault();
      return;
    }

    let selectNext = e.key == 'ArrowDown';
    if (e.key == 'Enter') {
      // If a menu item has focus, don't change focus or close menu on 'Enter'.
      const options = this.querySelectorAll('.dropdown-item');
      const focusedIndex =
          Array.prototype.indexOf.call(options, getDeepActiveElement());
      if (focusedIndex != -1) {
        return;
      }

      if (cr.isWindows || cr.isMac) {
        this.close();
        e.preventDefault();
        return;
      }
      selectNext = true;
    }

    if (e.key !== 'ArrowUp' && !selectNext) {
      return;
    }

    const nextOption = this.getNextOption_(selectNext ? 1 : -1);
    if (nextOption) {
      if (!this.hasMousemoveListener_) {
        this.hasMousemoveListener_ = true;
        listenOnce(this, 'mousemove', e => {
          this.onMouseover_(e);
          this.hasMousemoveListener_ = false;
        });
      }
      nextOption.focus();
    }

    e.preventDefault();
  },

  /**
   * @param {!Event} e
   * @private
   */
  onMouseover_: function(e) {
    // TODO(scottchen): Using "focus" to determine selected item might mess
    // with screen readers in some edge cases.
    let i = 0;
    let target;
    do {
      target = e.path[i++];
      if (target.classList && target.classList.contains('dropdown-item') &&
          !target.disabled) {
        target.focus();
        return;
      }
    } while (this != target);

    // The user moved the mouse off the options. Reset focus to the dialog.
    this.$.dialog.focus();
  },

  /**
   * @param {number} step -1 for getting previous option (up), 1 for getting
   *     next option (down).
   * @return {?Element} The next focusable option, taking into account
   *     disabled/hidden attributes, or null if no focusable option exists.
   * @private
   */
  getNextOption_: function(step) {
    // Using a counter to ensure no infinite loop occurs if all elements are
    // hidden/disabled.
    let counter = 0;
    let nextOption = null;
    const options = this.querySelectorAll('.dropdown-item');
    const numOptions = options.length;
    let focusedIndex =
        Array.prototype.indexOf.call(options, getDeepActiveElement());

    // Handle case where nothing is focused and up is pressed.
    if (focusedIndex === -1 && step === -1) {
      focusedIndex = 0;
    }

    do {
      focusedIndex = (numOptions + focusedIndex + step) % numOptions;
      nextOption = options[focusedIndex];
      if (nextOption.disabled || nextOption.hidden) {
        nextOption = null;
      }
      counter++;
    } while (!nextOption && counter < numOptions);

    return nextOption;
  },

  close: function() {
    // Removing 'resize' and 'popstate' listeners when dialog is closed.
    this.removeListeners_();
    this.$.dialog.close();
    this.open = false;
    if (this.anchorElement_) {
      cr.ui.focusWithoutInk(assert(this.anchorElement_));
      this.anchorElement_ = null;
    }
    if (this.lastConfig_) {
      this.lastConfig_ = null;
    }
  },

  /**
   * Shows the menu anchored to the given element.
   * @param {!Element} anchorElement
   * @param {ShowAtConfig=} opt_config
   */
  showAt: function(anchorElement, opt_config) {
    this.anchorElement_ = anchorElement;
    // Scroll the anchor element into view so that the bounding rect will be
    // accurate for where the menu should be shown.
    this.anchorElement_.scrollIntoViewIfNeeded();

    const rect = this.anchorElement_.getBoundingClientRect();

    let height = rect.height;
    if (opt_config &&
        opt_config.anchorAlignmentY == AnchorAlignment.AFTER_END) {
      // When an action menu is positioned after the end of an element, the
      // action menu can appear too far away from the anchor element, typically
      // because anchors tend to have padding. So we offset the height a bit
      // so the menu shows up slightly closer to the content of anchor.
      height -= AFTER_END_OFFSET;
    }

    this.showAtPosition(/** @type {ShowAtPositionConfig} */ (Object.assign(
        {
          top: rect.top,
          left: rect.left,
          height: height,
          width: rect.width,
          // Default to anchoring towards the left.
          anchorAlignmentX: AnchorAlignment.BEFORE_END,
        },
        opt_config)));
  },

  /**
   * Shows the menu anchored to the given box. The anchor alignment is
   * specified as an X and Y alignment which represents a point in the anchor
   * where the menu will align to, which can have the menu either before or
   * after the given point in each axis. Center alignment places the center of
   * the menu in line with the center of the anchor. Coordinates are relative to
   * the top-left of the viewport.
   *
   *            y-start
   *         _____________
   *         |           |
   *         |           |
   *         |   CENTER  |
   * x-start |     x     | x-end
   *         |           |
   *         |anchor box |
   *         |___________|
   *
   *             y-end
   *
   * For example, aligning the menu to the inside of the top-right edge of
   * the anchor, extending towards the bottom-left would use a alignment of
   * (BEFORE_END, AFTER_START), whereas centering the menu below the bottom
   * edge of the anchor would use (CENTER, AFTER_END).
   *
   * @param {!ShowAtPositionConfig} config
   */
  showAtPosition: function(config) {
    // Save the scroll position of the viewport.
    const doc = document.scrollingElement;
    const scrollLeft = doc.scrollLeft;
    const scrollTop = doc.scrollTop;

    // Reset position so that layout isn't affected by the previous position,
    // and so that the dialog is positioned at the top-start corner of the
    // document.
    this.resetStyle_();
    this.$.dialog.showModal();
    this.open = true;

    config.top += scrollTop;
    config.left += scrollLeft;

    this.positionDialog_(/** @type {ShowAtPositionConfig} */ (Object.assign(
        {
          minX: scrollLeft,
          minY: scrollTop,
          maxX: scrollLeft + doc.clientWidth,
          maxY: scrollTop + doc.clientHeight,
        },
        config)));

    // Restore the scroll position.
    doc.scrollTop = scrollTop;
    doc.scrollLeft = scrollLeft;
    this.addListeners_();
  },

  /** @private */
  resetStyle_: function() {
    this.$.dialog.style.left = '';
    this.$.dialog.style.right = '';
    this.$.dialog.style.top = '0';
  },

  /**
   * Position the dialog using the coordinates in config. Coordinates are
   * relative to the top-left of the viewport when scrolled to (0, 0).
   * @param {!ShowAtPositionConfig} config
   * @private
   */
  positionDialog_: function(config) {
    this.lastConfig_ = config;
    const c = Object.assign(getDefaultShowConfig(), config);

    const top = c.top;
    const left = c.left;
    const bottom = top + c.height;
    const right = left + c.width;

    // Flip the X anchor in RTL.
    const rtl = getComputedStyle(this).direction == 'rtl';
    if (rtl) {
      c.anchorAlignmentX *= -1;
    }

    const offsetWidth = this.$.dialog.offsetWidth;
    const menuLeft = getStartPointWithAnchor(
        left, right, offsetWidth, c.anchorAlignmentX, c.minX, c.maxX);

    if (rtl) {
      const menuRight =
          document.scrollingElement.clientWidth - menuLeft - offsetWidth;
      this.$.dialog.style.right = menuRight + 'px';
    } else {
      this.$.dialog.style.left = menuLeft + 'px';
    }

    const menuTop = getStartPointWithAnchor(
        top, bottom, this.$.dialog.offsetHeight, c.anchorAlignmentY, c.minY,
        c.maxY);
    this.$.dialog.style.top = menuTop + 'px';
  },

  /**
   * @private
   */
  addListeners_: function() {
    this.boundClose_ = this.boundClose_ || function() {
      if (this.$.dialog.open) {
        this.close();
      }
    }.bind(this);
    window.addEventListener('resize', this.boundClose_);
    window.addEventListener('popstate', this.boundClose_);

    this.contentObserver_ =
        Polymer.dom(this.$.contentNode).observeNodes((info) => {
          info.addedNodes.forEach((node) => {
            if (node.classList &&
                node.classList.contains(DROPDOWN_ITEM_CLASS) &&
                !node.getAttribute('role')) {
              node.setAttribute('role', 'menuitem');
            }
          });
        });

    if (this.autoReposition) {
      this.resizeObserver_ = new ResizeObserver(() => {
        if (this.lastConfig_) {
          this.positionDialog_(this.lastConfig_);
          this.fire('cr-action-menu-repositioned');  // For easier testing.
        }
      });

      this.resizeObserver_.observe(this.$.dialog);
    }
  },
});
})();
