// Copyright (c) 2015 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.

/**
 * @constructor
 * @param {!Document} doc
 */
WebInspector.Tooltip = function(doc)
{
    this.element = doc.body.createChild("div");
    this._shadowRoot = WebInspector.createShadowRootWithCoreStyles(this.element, "ui/tooltip.css");

    this._tooltipElement = this._shadowRoot.createChild("div", "tooltip");
    doc.addEventListener("mousemove", this._mouseMove.bind(this), true);
    doc.addEventListener("mousedown", this._hide.bind(this, true), true);
    doc.addEventListener("mouseleave", this._hide.bind(this, false), true);
    doc.addEventListener("keydown", this._hide.bind(this, true), true);
    WebInspector.zoomManager.addEventListener(WebInspector.ZoomManager.Events.ZoomChanged, this._reset, this);
    doc.defaultView.addEventListener("resize", this._reset.bind(this), false);
}

WebInspector.Tooltip.Timing = {
    // Max time between tooltips showing that no opening delay is required.
    "InstantThreshold": 300,
    // Wait time before opening a tooltip.
    "OpeningDelay": 600
}

WebInspector.Tooltip.prototype = {
    /**
     * @param {!Event} event
     */
    _mouseMove: function(event)
    {
        var path = event.path;
        if (!path || event.buttons !== 0)
            return;

        if (this._anchorElement && path.indexOf(this._anchorElement) === -1)
            this._hide(false);

        for (var element of path) {
            if (element === this._anchorElement) {
                return;
            } else if (element[WebInspector.Tooltip._symbol]) {
                this._show(element, event);
                return;
            }
        }
    },

    /**
     * @param {!Element} anchorElement
     * @param {!Event} event
     */
    _show: function(anchorElement, event)
    {
        var tooltip = anchorElement[WebInspector.Tooltip._symbol];
        this._anchorElement = anchorElement;
        this._tooltipElement.removeChildren();

        // Check if native tooltips should be used.
        for (var element of WebInspector.Tooltip._nativeOverrideContainer) {
            if (this._anchorElement.isSelfOrDescendant(element)) {
                Object.defineProperty(this._anchorElement, "title", WebInspector.Tooltip._nativeTitle);
                this._anchorElement.title = tooltip.content;
                return;
            }
        }

        if (typeof tooltip.content === "string")
            this._tooltipElement.textContent = tooltip.content;
        else
            this._tooltipElement.appendChild(tooltip.content);

        if (tooltip.actionId) {
            var shortcuts = WebInspector.shortcutRegistry.shortcutDescriptorsForAction(tooltip.actionId);
            for (var shortcut of shortcuts) {
                var shortcutElement = this._tooltipElement.createChild("div", "tooltip-shortcut");
                shortcutElement.textContent = shortcut.name;
            }
        }

        this._tooltipElement.classList.add("shown");
        // Reposition to ensure text doesn't overflow unnecessarily.
        this._tooltipElement.positionAt(0, 0);

        // Show tooltip instantly if a tooltip was shown recently.
        var now = Date.now();
        var instant = (this._tooltipLastClosed && now - this._tooltipLastClosed < WebInspector.Tooltip.Timing.InstantThreshold);
        this._tooltipElement.classList.toggle("instant", instant);
        this._tooltipLastOpened = instant ? now : now + WebInspector.Tooltip.Timing.OpeningDelay;

        // Get container element.
        var container = WebInspector.Dialog.modalHostView().element;
        if (!anchorElement.isDescendant(container))
            container = this.element.parentElement;

        // Posititon tooltip based on the anchor element.
        var containerOffset = container.offsetRelativeToWindow(this.element.window());
        var containerOffsetWidth = container.offsetWidth;
        var containerOffsetHeight = container.offsetHeight;
        var anchorBox = this._anchorElement.boxInWindow(this.element.window());
        const anchorOffset = 2;
        const pageMargin = 2;
        var cursorOffset = 10;
        this._tooltipElement.style.maxWidth = (containerOffsetWidth - pageMargin * 2) + "px";
        this._tooltipElement.style.maxHeight = "";
        var tooltipWidth = this._tooltipElement.offsetWidth;
        var tooltipHeight = this._tooltipElement.offsetHeight;
        var anchorTooltipAtElement = this._anchorElement.nodeName === "BUTTON" || this._anchorElement.nodeName === "LABEL";
        var tooltipX = anchorTooltipAtElement ? anchorBox.x : event.x + cursorOffset;
        tooltipX = Number.constrain(tooltipX,
            containerOffset.x + pageMargin,
            containerOffset.x + containerOffsetWidth - tooltipWidth - pageMargin);
        var tooltipY;
        if (!anchorTooltipAtElement) {
            tooltipY = event.y + cursorOffset + tooltipHeight < containerOffset.y + containerOffsetHeight ? event.y + cursorOffset : event.y - tooltipHeight;
        } else {
            var onBottom = anchorBox.y + anchorOffset + anchorBox.height + tooltipHeight < containerOffset.y + containerOffsetHeight;
            tooltipY = onBottom ? anchorBox.y + anchorBox.height + anchorOffset : anchorBox.y - tooltipHeight - anchorOffset;
        }
        this._tooltipElement.positionAt(tooltipX, tooltipY);
    },

    /**
     * @param {boolean} removeInstant
     */
    _hide: function(removeInstant)
    {
        delete this._anchorElement;
        this._tooltipElement.classList.remove("shown");
        if (Date.now() > this._tooltipLastOpened)
            this._tooltipLastClosed = Date.now();
        if (removeInstant)
            delete this._tooltipLastClosed;
    },

    _reset: function()
    {
        this._hide(true);
        this._tooltipElement.positionAt(0, 0);
        this._tooltipElement.style.maxWidth = "0";
        this._tooltipElement.style.maxHeight = "0";
    }
}

WebInspector.Tooltip._symbol = Symbol("Tooltip");

/**
 * @param {!Document} doc
 */
WebInspector.Tooltip.installHandler = function(doc)
{
    new WebInspector.Tooltip(doc);
}

/**
 * @param {!Element} element
 * @param {!Element|string} tooltipContent
 * @param {string=} actionId
 * @param {!Object=} options
 */
WebInspector.Tooltip.install = function(element, tooltipContent, actionId, options)
{
    if (typeof tooltipContent === "string" && tooltipContent === "") {
        delete element[WebInspector.Tooltip._symbol];
        return;
    }
    element[WebInspector.Tooltip._symbol] = { content: tooltipContent, actionId: actionId, options: options || {} };
}

/**
 * @param {!Element} element
 */
WebInspector.Tooltip.addNativeOverrideContainer = function(element)
{
    WebInspector.Tooltip._nativeOverrideContainer.push(element);
}

/** @type {!Array.<!Element>} */
WebInspector.Tooltip._nativeOverrideContainer = [];
WebInspector.Tooltip._nativeTitle = /** @type {!ObjectPropertyDescriptor} */(Object.getOwnPropertyDescriptor(HTMLElement.prototype, "title"));

Object.defineProperty(HTMLElement.prototype, "title", {
    /**
     * @return {!Element|string}
     * @this {!Element}
     */
    get: function()
    {
        var tooltip = this[WebInspector.Tooltip._symbol];
        return tooltip ? tooltip.content : "";
    },

    /**
     * @param {!Element|string} x
     * @this {!Element}
     */
    set: function(x)
    {
        WebInspector.Tooltip.install(this, x);
    }
});
