text: /*
   * Copyright 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.
   */
  
  /**
   * @interface
   */
  WebInspector.LayerView = function()
  {
  }
  
  WebInspector.LayerView.prototype = {
      /**
       * @param {?WebInspector.LayerView.Selection} selection
       */
      hoverObject: function(selection) { },
  
      /**
       * @param {?WebInspector.LayerView.Selection} selection
       */
      selectObject: function(selection) { },
  
      /**
       * @param {?WebInspector.LayerTreeBase} layerTree
       */
      setLayerTree: function(layerTree) { }
  }
  
  
  /**
   * @constructor
   * @param {!WebInspector.LayerView.Selection.Type} type
   * @param {!WebInspector.Layer} layer
   */
  WebInspector.LayerView.Selection = function(type, layer)
  {
      this._type = type;
      this._layer = layer;
  }
  
  /**
   * @enum {string}
   */
  WebInspector.LayerView.Selection.Type = {
      Layer: "Layer",
      ScrollRect: "ScrollRect",
      Tile: "Tile",
  }
  
  /**
   * @param {?WebInspector.LayerView.Selection} a
   * @param {?WebInspector.LayerView.Selection} b
   * @return {boolean}
   */
  WebInspector.LayerView.Selection.isEqual = function(a, b)
  {
      return a && b ? a._isEqual(b) : a === b;
  }
  
  WebInspector.LayerView.Selection.prototype = {
      /**
       * @return {!WebInspector.LayerView.Selection.Type}
       */
      type: function()
      {
          return this._type;
      },
  
      /**
       * @return {!WebInspector.Layer}
       */
      layer: function()
      {
          return this._layer;
      },
  
      /**
       * @param {!WebInspector.LayerView.Selection} other
       * @return {boolean}
       */
      _isEqual: function(other)
      {
          return false;
      }
  }
  
  /**
   * @constructor
   * @extends {WebInspector.LayerView.Selection}
   * @param {!WebInspector.Layer} layer
   */
  WebInspector.LayerView.LayerSelection = function(layer)
  {
      console.assert(layer, "LayerSelection with empty layer");
      WebInspector.LayerView.Selection.call(this, WebInspector.LayerView.Selection.Type.Layer, layer);
  }
  
  WebInspector.LayerView.LayerSelection.prototype = {
      /**
       * @override
       * @param {!WebInspector.LayerView.Selection} other
       * @return {boolean}
       */
      _isEqual: function(other)
      {
          return other._type === WebInspector.LayerView.Selection.Type.Layer && other.layer().id() === this.layer().id();
      },
  
      __proto__: WebInspector.LayerView.Selection.prototype
  }
  
  /**
   * @constructor
   * @extends {WebInspector.LayerView.Selection}
   * @param {!WebInspector.Layer} layer
   * @param {number} scrollRectIndex
   */
  WebInspector.LayerView.ScrollRectSelection = function(layer, scrollRectIndex)
  {
      WebInspector.LayerView.Selection.call(this, WebInspector.LayerView.Selection.Type.ScrollRect, layer);
      this.scrollRectIndex = scrollRectIndex;
  }
  
  WebInspector.LayerView.ScrollRectSelection.prototype = {
      /**
       * @override
       * @param {!WebInspector.LayerView.Selection} other
       * @return {boolean}
       */
      _isEqual: function(other)
      {
          return other._type === WebInspector.LayerView.Selection.Type.ScrollRect &&
              this.layer().id() === other.layer().id() && this.scrollRectIndex === other.scrollRectIndex;
      },
  
      __proto__: WebInspector.LayerView.Selection.prototype
  }
  
  /**
   * @constructor
   * @extends {WebInspector.LayerView.Selection}
   * @param {!WebInspector.Layer} layer
   * @param {!WebInspector.TracingModel.Event} traceEvent
   */
  WebInspector.LayerView.TileSelection = function(layer, traceEvent)
  {
      WebInspector.LayerView.Selection.call(this, WebInspector.LayerView.Selection.Type.Tile, layer);
      this._traceEvent = traceEvent;
  }
  
  WebInspector.LayerView.TileSelection.prototype = {
      /**
       * @override
       * @param {!WebInspector.LayerView.Selection} other
       * @return {boolean}
       */
      _isEqual: function(other)
      {
          return other._type === WebInspector.LayerView.Selection.Type.Tile
              && this.layer().id() === other.layer().id() && this.traceEvent === other.traceEvent;
      },
  
      /**
       * @return {!WebInspector.TracingModel.Event}
       */
      traceEvent: function()
      {
          return this._traceEvent;
      },
  
      __proto__: WebInspector.LayerView.Selection.prototype
  }
  
  /**
   * @constructor
   */
  WebInspector.LayerViewHost = function()
  {
      /** @type {!Array.<!WebInspector.LayerView>} */
      this._views = [];
      this._selectedObject = null;
      this._hoveredObject = null;
      this._showInternalLayersSetting = WebInspector.settings.createSetting("layersShowInternalLayers", false);
  }
  
  WebInspector.LayerViewHost.prototype = {
      /**
       * @param {!WebInspector.LayerView} layerView
       */
      registerView: function(layerView)
      {
          this._views.push(layerView);
      },
  
      /**
       * @param {?WebInspector.LayerTreeBase} layerTree
       */
      setLayerTree: function(layerTree)
      {
          this._target = layerTree.target();
          var selectedLayer = this._selectedObject && this._selectedObject.layer();
          if (selectedLayer && (!layerTree || !layerTree.layerById(selectedLayer.id())))
              this.selectObject(null);
          var hoveredLayer = this._hoveredObject && this._hoveredObject.layer();
          if (hoveredLayer && (!layerTree || !layerTree.layerById(hoveredLayer.id())))
              this.hoverObject(null);
          for (var view of this._views)
              view.setLayerTree(layerTree);
      },
  
      /**
       * @param {?WebInspector.LayerView.Selection} selection
       */
      hoverObject: function(selection)
      {
          if (WebInspector.LayerView.Selection.isEqual(this._hoveredObject, selection))
              return;
          this._hoveredObject = selection;
          var layer = selection && selection.layer();
          this._toggleNodeHighlight(layer ? layer.nodeForSelfOrAncestor() : null);
          for (var view of this._views)
              view.hoverObject(selection);
      },
  
      /**
       * @param {?WebInspector.LayerView.Selection} selection
       */
      selectObject: function(selection)
      {
          if (WebInspector.LayerView.Selection.isEqual(this._selectedObject, selection))
              return;
          this._selectedObject = selection;
          for (var view of this._views)
              view.selectObject(selection);
      },
  
      /**
       * @return {?WebInspector.LayerView.Selection}
       */
      selection: function()
      {
          return this._selectedObject;
      },
  
      /**
       * @param {!WebInspector.ContextMenu} contextMenu
       * @param {?WebInspector.LayerView.Selection} selection
       */
      showContextMenu: function(contextMenu, selection)
      {
          contextMenu.appendCheckboxItem(WebInspector.UIString("Show internal layers"), this._toggleShowInternalLayers.bind(this), this._showInternalLayersSetting.get());
          var node = selection && selection.layer() && selection.layer().nodeForSelfOrAncestor();
          if (node)
              contextMenu.appendApplicableItems(node);
          contextMenu.show();
      },
  
      /**
       * @return {!WebInspector.Setting}
       */
      showInternalLayersSetting: function()
      {
          return this._showInternalLayersSetting;
      },
  
      _toggleShowInternalLayers: function()
      {
          this._showInternalLayersSetting.set(!this._showInternalLayersSetting.get());
      },
  
      /**
       * @param {?WebInspector.DOMNode} node
       */
      _toggleNodeHighlight: function(node)
      {
          if (node) {
              node.highlightForTwoSeconds();
              return;
          }
          WebInspector.DOMModel.hideDOMNodeHighlight();
      }
  }
  
  