// 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.
import {ElementsTreeOutline} from './ElementsTreeOutline.js';

/**
 * @unrestricted
 */
export class ElementsTreeElementHighlighter {
  /**
   * @param {!ElementsTreeOutline} treeOutline
   */
  constructor(treeOutline) {
    this._throttler = new Common.Throttler(100);
    this._treeOutline = treeOutline;
    this._treeOutline.addEventListener(UI.TreeOutline.Events.ElementExpanded, this._clearState, this);
    this._treeOutline.addEventListener(UI.TreeOutline.Events.ElementCollapsed, this._clearState, this);
    this._treeOutline.addEventListener(ElementsTreeOutline.Events.SelectedNodeChanged, this._clearState, this);
    SDK.targetManager.addModelListener(
        SDK.OverlayModel, SDK.OverlayModel.Events.HighlightNodeRequested, this._highlightNode, this);
    SDK.targetManager.addModelListener(
        SDK.OverlayModel, SDK.OverlayModel.Events.InspectModeWillBeToggled, this._clearState, this);
  }

  /**
   * @param {!Common.Event} event
   */
  _highlightNode(event) {
    if (!Common.moduleSetting('highlightNodeOnHoverInOverlay').get()) {
      return;
    }

    const domNode = /** @type {!SDK.DOMNode} */ (event.data);

    this._throttler.schedule(callback.bind(this));
    this._pendingHighlightNode =
        this._treeOutline === ElementsTreeOutline.forDOMModel(domNode.domModel()) ? domNode : null;

    /**
     * @this {ElementsTreeElementHighlighter}
     */
    function callback() {
      this._highlightNodeInternal(this._pendingHighlightNode);
      delete this._pendingHighlightNode;
      return Promise.resolve();
    }
  }

  /**
   * @param {?SDK.DOMNode} node
   */
  _highlightNodeInternal(node) {
    this._isModifyingTreeOutline = true;
    let treeElement = null;

    if (this._currentHighlightedElement) {
      let currentTreeElement = this._currentHighlightedElement;
      while (currentTreeElement !== this._alreadyExpandedParentElement) {
        if (currentTreeElement.expanded) {
          currentTreeElement.collapse();
        }

        currentTreeElement = currentTreeElement.parent;
      }
    }

    delete this._currentHighlightedElement;
    delete this._alreadyExpandedParentElement;
    if (node) {
      let deepestExpandedParent = node;
      const treeElementSymbol = this._treeOutline.treeElementSymbol();
      while (deepestExpandedParent &&
             (!deepestExpandedParent[treeElementSymbol] || !deepestExpandedParent[treeElementSymbol].expanded)) {
        deepestExpandedParent = deepestExpandedParent.parentNode;
      }

      this._alreadyExpandedParentElement =
          deepestExpandedParent ? deepestExpandedParent[treeElementSymbol] : this._treeOutline.rootElement();
      treeElement = this._treeOutline.createTreeElementFor(node);
    }

    this._currentHighlightedElement = treeElement;
    this._treeOutline.setHoverEffect(treeElement);
    if (treeElement) {
      treeElement.reveal(true);
    }

    this._isModifyingTreeOutline = false;
  }

  _clearState() {
    if (this._isModifyingTreeOutline) {
      return;
    }

    delete this._currentHighlightedElement;
    delete this._alreadyExpandedParentElement;
    delete this._pendingHighlightNode;
  }
}
