/**
 * @license
 * 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.
 */
import '../../elements/shared/gr-tooltip/gr-tooltip.js';
import {flush} from '@polymer/polymer/lib/legacy/polymer.dom.js';
import {getRootElement} from '../../scripts/rootElement.js';

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

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

  properties: {
    hasTooltip: {
      type: Boolean,
      observer: '_setupTooltipListeners',
    },
    positionBelow: {
      type: Boolean,
      value: false,
      reflectToAttribute: true,
    },

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

  /** @override */
  detached() {
    // NOTE: if you define your own `detached` in your component
    // then this won't take affect (as its not a class yet)
    this._handleHideTooltip();
    this.removeEventListener('mouseenter', this._mouseenterHandler);
  },

  _setupTooltipListeners() {
    if (!this._mouseenterHandler) {
      this._mouseenterHandler = this._handleShowTooltip.bind(this);
    }

    if (!this.hasTooltip) {
      // if attribute set to false, remove the listener
      this.removeEventListener('mouseenter', this._mouseenterHandler);
      this._hasSetupTooltipListeners = false;
      return;
    }

    if (this._hasSetupTooltipListeners) {
      return;
    }
    this._hasSetupTooltipListeners = true;

    this.addEventListener('mouseenter', this._mouseenterHandler);
  },

  _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');
    tooltip.positionBelow = this.getAttribute('position-below');

    // 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';
    getRootElement().appendChild(tooltip);
    this._positionTooltip(tooltip);
    tooltip.style.visibility = null;

    this._tooltip = tooltip;
    this.listen(window, 'scroll', '_handleWindowScroll');
    this.listen(this, 'mouseleave', '_handleHideTooltip');
    this.listen(this, 'click', '_handleHideTooltip');
  },

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

    this.unlisten(window, 'scroll', '_handleWindowScroll');
    this.unlisten(this, 'mouseleave', '_handleHideTooltip');
    this.unlisten(this, 'click', '_handleHideTooltip');
    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) {
    // This flush is needed for tooltips to be positioned correctly in Firefox
    // and Safari.
    flush();
    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';

    if (!this.positionBelow) {
      tooltip.style.top = Math.max(0, top) + 'px';
      tooltip.style.transform = 'translateY(calc(-100% - ' + BOTTOM_OFFSET +
          'px))';
    } else {
      tooltip.style.top = top + rect.height + BOTTOM_OFFSET + 'px';
    }
  },
};

// TODO(dmfilippov) Remove the following lines with assignments
// Plugins can use the behavior because it was accessible with
// the global Gerrit... variable. To avoid breaking changes in plugins
// temporary assign global variables.
window.Gerrit = window.Gerrit || {};
window.Gerrit.TooltipBehavior = TooltipBehavior;
