// 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';

  var BOTTOM_OFFSET = 10;

  var TooltipBehavior = {

    properties: {
      hasTooltip: Boolean,

      _tooltip: Element,
      _titleText: String,
    },

    attached: function() {
      if (!this.hasTooltip) { return; }

      this.addEventListener('mouseover', this._handleShowTooltip.bind(this));
      this.addEventListener('mouseout', this._handleHideTooltip.bind(this));
      this.addEventListener('focusin', this._handleShowTooltip.bind(this));
      this.addEventListener('focusout', this._handleHideTooltip.bind(this));
      this.listen(window, 'scroll', '_handleWindowScroll');
    },

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

    _handleShowTooltip: function(e) {
      if (!this.hasAttribute('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', '');

      var tooltip = document.createElement('gr-tooltip');
      tooltip.text = this._titleText;

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

      this._tooltip = tooltip;
    },

    _handleHideTooltip: function(e) {
      if (!this.hasAttribute('title') ||
          !this._titleText ||
          this === document.activeElement) { return; }

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

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

      this._positionTooltip(this._tooltip);
    },

    _positionTooltip: function(tooltip) {
      var offset = this._getOffset(this);
      var top = offset.top;
      var left = offset.left;

      top -= this.offsetHeight + BOTTOM_OFFSET;
      left -= (tooltip.offsetWidth / 2) - (this.offsetWidth / 2);
      left = Math.max(0, left);
      top = Math.max(0, top);

      tooltip.style.left = left + 'px';
      tooltip.style.top = top + 'px';
    },

    _getOffset: function(el) {
      var top = 0;
      var left = 0;
      for (var node = el; node; node = node.offsetParent) {
        if (node.offsetTop) { top += node.offsetTop; }
        if (node.offsetLeft) { left += node.offsetLeft; }
      }
      top += window.scrollY;
      left += window.scrollX;
      return {top: top, left: left};
    },
  };

  window.Gerrit = window.Gerrit || {};
  window.Gerrit.TooltipBehavior = TooltipBehavior;
})(window);
