// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
(function(window) {
  'use strict';

  const BOTTOM_OFFSET = 7.2; // Height of the arrow in tooltip.

  window.Gerrit = window.Gerrit || {};

  /** @polymerBehavior Gerrit.TooltipBehavior */
  Gerrit.TooltipBehavior = {

    properties: {
      hasTooltip: {
        type: Boolean,
        observer: '_setupTooltipListeners',
      },

      _isTouchDevice: {
        type: Boolean,
        value() {
          return 'ontouchstart' in document.documentElement;
        },
      },
      _tooltip: Element,
      _titleText: String,
      _hasSetupTooltipListeners: {
        type: Boolean,
        value: false,
      },
    },

    detached() {
      this._handleHideTooltip();
      this.unlisten(window, 'scroll', '_handleWindowScroll');
    },

    _setupTooltipListeners() {
      if (this._hasSetupTooltipListeners || !this.hasTooltip) { return; }
      this._hasSetupTooltipListeners = true;

      this.addEventListener('mouseenter', this._handleShowTooltip.bind(this));
      this.addEventListener('mouseleave', this._handleHideTooltip.bind(this));
      this.addEventListener('tap', this._handleHideTooltip.bind(this));
      this.listen(window, 'scroll', '_handleWindowScroll');
    },

    _handleShowTooltip(e) {
      if (this._isTouchDevice) { return; }

      if (!this.hasAttribute('title') ||
          this.getAttribute('title') === '' ||
          this._tooltip) {
        return;
      }

      // Store the title attribute text then set it to an empty string to
      // prevent it from showing natively.
      this._titleText = this.getAttribute('title');
      this.setAttribute('title', '');

      const tooltip = document.createElement('gr-tooltip');
      tooltip.text = this._titleText;
      tooltip.maxWidth = this.getAttribute('max-width');

      // Set visibility to hidden before appending to the DOM so that
      // calculations can be made based on the element’s size.
      tooltip.style.visibility = 'hidden';
      Gerrit.getRootElement().appendChild(tooltip);
      this._positionTooltip(tooltip);
      tooltip.style.visibility = null;

      this._tooltip = tooltip;
    },

    _handleHideTooltip(e) {
      if (this._isTouchDevice) { return; }
      if (!this.hasAttribute('title') ||
          this._titleText == null) {
        return;
      }

      this.setAttribute('title', this._titleText);
      if (this._tooltip && this._tooltip.parentNode) {
        this._tooltip.parentNode.removeChild(this._tooltip);
      }
      this._tooltip = null;
    },

    _handleWindowScroll(e) {
      if (!this._tooltip) { return; }

      this._positionTooltip(this._tooltip);
    },

    _positionTooltip(tooltip) {
      const rect = this.getBoundingClientRect();
      const boxRect = tooltip.getBoundingClientRect();
      const parentRect = tooltip.parentElement.getBoundingClientRect();
      const top = rect.top - parentRect.top;
      const left =
          rect.left - parentRect.left + (rect.width - boxRect.width) / 2;
      const right = parentRect.width - left - boxRect.width;
      if (left < 0) {
        tooltip.updateStyles({
          '--gr-tooltip-arrow-center-offset': left + 'px',
        });
      } else if (right < 0) {
        tooltip.updateStyles({
          '--gr-tooltip-arrow-center-offset': (-0.5 * right) + 'px',
        });
      }
      tooltip.style.left = Math.max(0, left) + 'px';
      tooltip.style.top = Math.max(0, top) + 'px';
      tooltip.style.transform = 'translateY(calc(-100% - ' + BOTTOM_OFFSET +
          'px))';
    },
  };
})(window);
