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

/**
 * @fileoverview Bubble implementation.
 */

// TODO(xiyuan): Move this into shared.
cr.define('cr.ui', function() {
  /**
   * Creates a bubble div.
   * @constructor
   * @extends {HTMLDivElement}
   */
  var Bubble = cr.ui.define('div');

  /**
   * Bubble key codes.
   * @enum {number}
   */
  var Keys = {
    TAB: 'Tab',
    ENTER: 'Enter',
    ESC: 'Escape',
    SPACE: ' '
  };

  /**
   * Bubble attachment side.
   * @enum {number}
   */
  Bubble.Attachment = {
    RIGHT: 0,
    LEFT: 1,
    TOP: 2,
    BOTTOM: 3
  };

  Bubble.prototype = {
    __proto__: HTMLDivElement.prototype,

    // Anchor element for this bubble.
    anchor_: undefined,

    // If defined, sets focus to this element once bubble is closed. Focus is
    // set to this element only if there's no any other focused element.
    elementToFocusOnHide_: undefined,

    // With help of these elements we create closed artificial tab-cycle through
    // bubble elements.
    firstBubbleElement_: undefined,
    lastBubbleElement_: undefined,

    // Whether to hide bubble when key is pressed.
    hideOnKeyPress_: true,

    persistent_: false,

    /** @override */
    decorate: function() {
      this.docKeyDownHandler_ = this.handleDocKeyDown_.bind(this);
      this.selfClickHandler_ = this.handleSelfClick_.bind(this);
      this.ownerDocument.addEventListener('click',
                                          this.handleDocClick_.bind(this));
      // Set useCapture to true because scroll event does not bubble.
      this.ownerDocument.addEventListener('scroll',
                                          this.handleScroll_.bind(this),
                                          true);
      this.ownerDocument.addEventListener('keydown',
                                          this.docKeyDownHandler_);
      window.addEventListener('blur', this.handleWindowBlur_.bind(this));
      this.addEventListener('transitionend',
                            this.handleTransitionEnd_.bind(this));
      // Guard timer for 200ms + epsilon.
      ensureTransitionEndEvent(this, 250);
    },

    /**
     * Element that should be focused on hide.
     * @type {HTMLElement}
     */
    set elementToFocusOnHide(value) {
      this.elementToFocusOnHide_ = value;
    },

    /**
     * Element that should be focused on shift-tab of first bubble element
     * to create artificial closed tab-cycle through bubble.
     * Usually close-button.
     * @type {HTMLElement}
     */
    set lastBubbleElement(value) {
      this.lastBubbleElement_ = value;
    },

    /**
     * Whether the bubble should remain shown on user action events (e.g. on
     * user clicking, or scrolling outside the bubble). Note that
     * {@code this.hideOnKeyPress} has precedence.
     * @type {boolean}
     */
    set persistent(value) {
      this.persistent_ = value
    },

    /**
     * If set, the element at which the bubble is anchored.
     * @type {HTMLElement|undefined}
     */
    get anchor() {
      return this.anchor_;
    },

    /**
     * Element that should be focused on tab of last bubble element
     * to create artificial closed tab-cycle through bubble.
     * Same element as first focused on bubble opening.
     * @type {HTMLElement}
     */
    set firstBubbleElement(value) {
      this.firstBubbleElement_ = value;
    },

    /**
     * Whether to hide bubble when key is pressed.
     * @type {boolean}
     */
    set hideOnKeyPress(value) {
      this.hideOnKeyPress_ = value;
    },

    /**
     * Whether to hide bubble when clicked inside bubble element.
     * Default is true.
     * @type {boolean}
     */
    set hideOnSelfClick(value) {
      if (value)
        this.removeEventListener('click', this.selfClickHandler_);
      else
        this.addEventListener('click', this.selfClickHandler_);
    },

    /**
     * Handler for click event which prevents bubble auto hide.
     * @private
     */
    handleSelfClick_: function(e) {
      // Allow clicking on [x] button.
      if (e.target && e.target.classList.contains('close-button'))
        return;
      e.stopPropagation();
    },

    /**
     * Sets the attachment of the bubble.
     * @param {!Attachment} attachment Bubble attachment.
     */
    setAttachment_: function(attachment) {
      var styleClassList = ['bubble-right', 'bubble-left',
                            'bubble-top', 'bubble-bottom'];
      for (var i = 0; i < styleClassList.length; ++i)
        this.classList.toggle(styleClassList[i], i == attachment);
    },

    /**
     * Shows the bubble for given anchor element.
     * @param {!Object} pos Bubble position (left, top, right, bottom in px).
     * @param {HTMLElement} opt_content Content to show in bubble.
     *     If not specified, bubble element content is shown.
     * @param {Attachment=} opt_attachment Bubble attachment (on which side of
     *     the element it should be displayed).
     * @param {boolean=} opt_oldstyle Optional flag to force old style bubble,
     *     i.e. pre-MD-style.
     * @private
     */
    showContentAt_: function(pos, opt_content, opt_attachment, opt_oldstyle) {
      this.style.top = this.style.left = this.style.right = this.style.bottom =
          'auto';
      for (var k in pos) {
        if (typeof pos[k] == 'number')
          this.style[k] = pos[k] + 'px';
      }
      if (opt_content !== undefined)
        this.replaceContent(opt_content);

      if (opt_oldstyle) {
        this.setAttribute('oldstyle', '');
        this.setAttachment_(opt_attachment);
      }

      this.hidden = false;
      this.classList.remove('faded');
    },

    /**
     * Replaces error message content with the given DOM element.
     * @param {HTMLElement} content Content to show in bubble.
     */
    replaceContent: function(content) {
      this.innerHTML = '';
      this.appendChild(content);
    },

    /**
     * Shows the bubble for given anchor element. Bubble content is not cleared.
     * @param {!HTMLElement} el Anchor element of the bubble.
     * @param {!Attachment} attachment Bubble attachment (on which side of the
     *     element it should be displayed).
     * @param {number=} opt_offset Offset of the bubble.
     * @param {number=} opt_padding Optional padding of the bubble.
     */
    showForElement: function(el, attachment, opt_offset, opt_padding) {
      /* showForElement() is used only to display Accessibility popup in
       * oobe_screen_welcome*. It requires old-style bubble, so it is safe
       * to always set this flag here.
       */
      this.showContentForElement(
          el, attachment, undefined, opt_offset, opt_padding, undefined, true);
    },

    /**
     * Shows the bubble for given anchor element.
     * @param {!HTMLElement} el Anchor element of the bubble.
     * @param {!Attachment} attachment Bubble attachment (on which side of the
     *     element it should be displayed).
     * @param {HTMLElement} opt_content Content to show in bubble.
     *     If not specified, bubble element content is shown.
     * @param {number=} opt_offset Offset of the bubble attachment point from
     *     left (for vertical attachment) or top (for horizontal attachment)
     *     side of the element. If not specified, the bubble is positioned to
     *     be aligned with the left/top side of the element but not farther than
     *     half of its width/height.
     * @param {number=} opt_padding Optional padding of the bubble.
     * @param {boolean=} opt_match_width Optional flag to force the bubble have
     *     the same width as the element it it attached to.
     * @param {boolean=} opt_oldstyle Optional flag to force old style bubble,
     *     i.e. pre-MD-style.
     */
    showContentForElement: function(
        el, attachment, opt_content, opt_offset, opt_padding, opt_match_width,
        opt_oldstyle) {
      /** @const */ var ARROW_OFFSET = 25;
      /** @const */ var DEFAULT_PADDING = 18;

      if (opt_padding == undefined)
        opt_padding = DEFAULT_PADDING;

      if (!opt_oldstyle)
        opt_padding += 10;

      var origin = cr.ui.login.DisplayManager.getPosition(el);
      var offset = opt_offset == undefined ?
          [Math.min(ARROW_OFFSET, el.offsetWidth / 2),
           Math.min(ARROW_OFFSET, el.offsetHeight / 2)] :
          [opt_offset, opt_offset];

      var pos = {};
      if (isRTL()) {
        switch (attachment) {
          case Bubble.Attachment.TOP:
            pos.right = origin.right + offset[0] - ARROW_OFFSET;
            pos.bottom = origin.bottom + el.offsetHeight + opt_padding;
            break;
          case Bubble.Attachment.RIGHT:
            pos.top = origin.top + offset[1] - ARROW_OFFSET;
            pos.right = origin.right + el.offsetWidth + opt_padding;
            break;
          case Bubble.Attachment.BOTTOM:
            pos.right = origin.right + offset[0] - ARROW_OFFSET;
            pos.top = origin.top + el.offsetHeight + opt_padding;
            break;
          case Bubble.Attachment.LEFT:
            pos.top = origin.top + offset[1] - ARROW_OFFSET;
            pos.left = origin.left + el.offsetWidth + opt_padding;
            break;
        }
      } else {
        switch (attachment) {
          case Bubble.Attachment.TOP:
            pos.left = origin.left + offset[0] - ARROW_OFFSET;
            pos.bottom = origin.bottom + el.offsetHeight + opt_padding;
            break;
          case Bubble.Attachment.RIGHT:
            pos.top = origin.top + offset[1] - ARROW_OFFSET;
            pos.left = origin.left + el.offsetWidth + opt_padding;
            break;
          case Bubble.Attachment.BOTTOM:
            pos.left = origin.left + offset[0] - ARROW_OFFSET;
            pos.top = origin.top + el.offsetHeight + opt_padding;
            break;
          case Bubble.Attachment.LEFT:
            pos.top = origin.top + offset[1] - ARROW_OFFSET;
            pos.right = origin.right + el.offsetWidth + opt_padding;
            break;
        }
      }
      this.style.width = '';
      this.removeAttribute('match-width');
      if (opt_match_width) {
        this.setAttribute('match-width', '');
        var elWidth =
            window.getComputedStyle(el, null).getPropertyValue('width');
        var paddingLeft = parseInt(window.getComputedStyle(this, null)
            .getPropertyValue('padding-left'));
        var paddingRight = parseInt(window.getComputedStyle(this, null)
            .getPropertyValue('padding-right'));
        if (elWidth)
          this.style.width =
              (parseInt(elWidth) - paddingLeft - paddingRight) + 'px';
      }

      this.anchor_ = el;
      this.showContentAt_(pos, opt_content, attachment, opt_oldstyle);
    },

    /**
     * Shows the bubble for given anchor element.
     * @param {!HTMLElement} el Anchor element of the bubble.
     * @param {string} text Text content to show in bubble.
     * @param {!Attachment} attachment Bubble attachment (on which side of the
     *     element it should be displayed).
     * @param {number=} opt_offset Offset of the bubble attachment point from
     *     left (for vertical attachment) or top (for horizontal attachment)
     *     side of the element. If not specified, the bubble is positioned to
     *     be aligned with the left/top side of the element but not farther than
     *     half of its weight/height.
     * @param {number=} opt_padding Optional padding of the bubble.
     */
    showTextForElement: function(
        el, text, attachment, opt_offset, opt_padding) {
      var span = this.ownerDocument.createElement('span');
      span.textContent = text;
      this.showContentForElement(el, attachment, span, opt_offset, opt_padding);
    },

    /**
     * Hides the bubble.
     */
    hide: function() {
      if (!this.classList.contains('faded'))
        this.classList.add('faded');
    },

    /**
     * Hides the bubble anchored to the given element (if any).
     * @param {!Object} el Anchor element.
     */
    hideForElement: function(el) {
      if (!this.hidden && this.anchor_ == el)
        this.hide();
    },

    /**
     * Handler for faded transition end.
     * @private
     */
    handleTransitionEnd_: function(e) {
      if (this.classList.contains('faded')) {
        this.hidden = true;
        if (this.elementToFocusOnHide_)
          this.elementToFocusOnHide_.focus();
      }
    },

    /**
     * Handler of scroll event.
     * @private
     */
    handleScroll_: function(e) {
      if (!this.hidden && !this.persistent_)
        this.hide();
    },

    /**
     * Handler of document click event.
     * @private
     */
    handleDocClick_: function(e) {
      // Ignore clicks on anchor element.
      if (e.target == this.anchor_)
        return;

      if (!this.hidden && !this.persistent_)
        this.hide();
    },

    /**
     * Handle of document keydown event.
     * @private
     */
    handleDocKeyDown_: function(e) {
      if (this.hidden)
        return;

      if (this.hideOnKeyPress_) {
        this.hide();
        return;
      }
      // Artificial tab-cycle.

      if (e.key == Keys.TAB && e.shiftKey == true &&
          e.target == this.firstBubbleElement_) {
        this.lastBubbleElement_.focus();
        e.preventDefault();
      }
      if (e.key == Keys.TAB && e.shiftKey == false &&
          e.target == this.lastBubbleElement_) {
        this.firstBubbleElement_.focus();
        e.preventDefault();
      }
      // Close bubble on ESC or on hitting spacebar or Enter at close-button.
      if ((e.key == Keys.ESC && !this.persistent_) ||
          ((e.key == Keys.ENTER || e.key == Keys.SPACE) && e.target &&
           e.target.classList.contains('close-button')))
        this.hide();
    },

    /**
     * Handler of window blur event.
     * @private
     */
    handleWindowBlur_: function(e) {
      if (!this.hidden && !this.persistent_)
        this.hide();
    }
  };

  return {
    Bubble: Bubble
  };
});
