/*
 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.LayerTreeDetailsSidebarPanel = class LayerTreeDetailsSidebarPanel extends WI.DOMDetailsSidebarPanel
{
    constructor()
    {
        super("layer-tree", WI.UIString("Layers"));

        this._dataGridNodesByLayerId = new Map;

        this.element.classList.add("layer-tree");
    }

    // DetailsSidebarPanel Overrides.

    shown()
    {
        WI.layerTreeManager.addEventListener(WI.LayerTreeManager.Event.LayerTreeDidChange, this._layerTreeDidChange, this);

        console.assert(this.parentSidebar);

        super.shown();
    }

    hidden()
    {
        WI.layerTreeManager.removeEventListener(WI.LayerTreeManager.Event.LayerTreeDidChange, this._layerTreeDidChange, this);

        super.hidden();
    }

    // DOMDetailsSidebarPanel Overrides

    supportsDOMNode(nodeToInspect)
    {
        return WI.layerTreeManager.supported && nodeToInspect.nodeType() === Node.ELEMENT_NODE;
    }

    // Protected

    initialLayout()
    {
        super.initialLayout();

        WI.showShadowDOMSetting.addEventListener(WI.Setting.Event.Changed, this._showShadowDOMSettingChanged, this);

        this._buildLayerInfoSection();
        this._buildDataGridSection();
        this._buildBottomBar();
    }

    layout()
    {
        super.layout();

        if (!this.domNode)
            return;

        WI.layerTreeManager.layersForNode(this.domNode, (layers) => {
            let layerForNode = layers[0] && layers[0].nodeId === this.domNode.id && !layers[0].isGeneratedContent ? layers[0] : null;
            let childLayers = layers.slice(layerForNode ? 1 : 0);
            this._unfilteredChildLayers = childLayers;
            this._updateDisplayWithLayers(layerForNode, childLayers);
        });
    }

    sizeDidChange()
    {
        super.sizeDidChange();

        // FIXME: <https://webkit.org/b/152269> Web Inspector: Convert DetailsSection classes to use View
        this._childLayersRow.sizeDidChange();
    }

    // Private

    _layerTreeDidChange(event)
    {
        this.needsLayout();
    }

    _showShadowDOMSettingChanged(event)
    {
        if (this.selected)
            this._updateDisplayWithLayers(this._layerForNode, this._unfilteredChildLayers);
    }

    _buildLayerInfoSection()
    {
        var rows = this._layerInfoRows = {};
        var rowsArray = [];

        rowsArray.push(rows["Width"] = new WI.DetailsSectionSimpleRow(WI.UIString("Width")));
        rowsArray.push(rows["Height"] = new WI.DetailsSectionSimpleRow(WI.UIString("Height")));
        rowsArray.push(rows["Paints"] = new WI.DetailsSectionSimpleRow(WI.UIString("Paints")));
        rowsArray.push(rows["Memory"] = new WI.DetailsSectionSimpleRow(WI.UIString("Memory")));

        this._layerInfoGroup = new WI.DetailsSectionGroup(rowsArray);

        var emptyRow = new WI.DetailsSectionRow(WI.UIString("No Layer Available"));
        emptyRow.showEmptyMessage();
        this._noLayerInformationGroup = new WI.DetailsSectionGroup([emptyRow]);

        this._layerInfoSection = new WI.DetailsSection("layer-info", WI.UIString("Layer Info"), [this._noLayerInformationGroup]);

        this.contentView.element.appendChild(this._layerInfoSection.element);
    }

    _buildDataGridSection()
    {
        var columns = {name: {}, paintCount: {}, memory: {}};

        columns.name.title = WI.UIString("Node");
        columns.name.sortable = false;

        columns.paintCount.title = WI.UIString("Paints");
        columns.paintCount.sortable = true;
        columns.paintCount.aligned = "right";
        columns.paintCount.width = "50px";

        columns.memory.title = WI.UIString("Memory");
        columns.memory.sortable = true;
        columns.memory.aligned = "right";
        columns.memory.width = "70px";

        this._dataGrid = new WI.DataGrid(columns);
        this._dataGrid.inline = true;
        this._dataGrid.addEventListener(WI.DataGrid.Event.SortChanged, this._sortDataGrid, this);
        this._dataGrid.addEventListener(WI.DataGrid.Event.SelectedNodeChanged, this._selectedDataGridNodeChanged, this);

        this._dataGrid.sortColumnIdentifier = "memory";
        this._dataGrid.sortOrder = WI.DataGrid.SortOrder.Descending;
        this._dataGrid.createSettings("layer-tree-details-sidebar-panel");

        var element = this._dataGrid.element;
        element.addEventListener("focus", this._dataGridGainedFocus.bind(this), false);
        element.addEventListener("blur", this._dataGridLostFocus.bind(this), false);
        element.addEventListener("click", this._dataGridWasClicked.bind(this), false);

        this._childLayersRow = new WI.DetailsSectionDataGridRow(null, WI.UIString("No Child Layers"));
        var group = new WI.DetailsSectionGroup([this._childLayersRow]);
        var section = new WI.DetailsSection("layer-children", WI.UIString("Child Layers"), [group], null, true);

        this.contentView.element.appendChild(section.element);
    }

    _buildBottomBar()
    {
        var bottomBar = this.element.appendChild(document.createElement("div"));
        bottomBar.className = "bottom-bar";

        this._layersCountLabel = bottomBar.appendChild(document.createElement("div"));
        this._layersCountLabel.className = "layers-count-label";

        this._layersMemoryLabel = bottomBar.appendChild(document.createElement("div"));
        this._layersMemoryLabel.className = "layers-memory-label";
    }

    _sortDataGrid()
    {
        var sortColumnIdentifier = this._dataGrid.sortColumnIdentifier;

        function comparator(a, b)
        {
            var item1 = a.layer[sortColumnIdentifier] || 0;
            var item2 = b.layer[sortColumnIdentifier] || 0;
            return item1 - item2;
        }

        this._dataGrid.sortNodes(comparator);
        this._updatePopoverForSelectedNode();
    }

    _selectedDataGridNodeChanged()
    {
        if (this._dataGrid.selectedNode) {
            this._highlightSelectedNode();
            this._showPopoverForSelectedNode();
        } else {
            WI.domTreeManager.hideDOMNodeHighlight();
            this._hidePopover();
        }
    }

    _dataGridGainedFocus(event)
    {
        this._highlightSelectedNode();
        this._showPopoverForSelectedNode();
    }

    _dataGridLostFocus(event)
    {
        WI.domTreeManager.hideDOMNodeHighlight();
        this._hidePopover();
    }

    _dataGridWasClicked(event)
    {
        if (this._dataGrid.selectedNode && event.target.parentNode.classList.contains("filler"))
            this._dataGrid.selectedNode.deselect();
    }

    _highlightSelectedNode()
    {
        var dataGridNode = this._dataGrid.selectedNode;
        if (!dataGridNode)
            return;

        var layer = dataGridNode.layer;
        if (layer.isGeneratedContent || layer.isReflection || layer.isAnonymous)
            WI.domTreeManager.highlightRect(layer.bounds, true);
        else
            WI.domTreeManager.highlightDOMNode(layer.nodeId);
    }

    _updateDisplayWithLayers(layerForNode, childLayers)
    {
        if (!WI.showShadowDOMSetting.value) {
            childLayers = childLayers.filter(function(layer) {
                return !layer.isInShadowTree;
            });
        }

        this._updateLayerInfoSection(layerForNode);
        this._updateDataGrid(layerForNode, childLayers);
        this._updateMetrics(layerForNode, childLayers);

        this._layerForNode = layerForNode;
        this._childLayers = childLayers;
    }

    _updateLayerInfoSection(layer)
    {
        this._layerInfoSection.groups = layer ? [this._layerInfoGroup] : [this._noLayerInformationGroup];

        if (!layer)
            return;

        this._layerInfoRows["Memory"].value = Number.bytesToString(layer.memory);
        this._layerInfoRows["Width"].value = layer.compositedBounds.width + "px";
        this._layerInfoRows["Height"].value = layer.compositedBounds.height + "px";
        this._layerInfoRows["Paints"].value = layer.paintCount + "";
    }

    _updateDataGrid(layerForNode, childLayers)
    {
        let dataGrid = this._dataGrid;
        let mutations = WI.layerTreeManager.layerTreeMutations(this._childLayers, childLayers);

        mutations.removals.forEach(function(layer) {
            let node = this._dataGridNodesByLayerId.get(layer.layerId);
            if (node) {
                dataGrid.removeChild(node);
                this._dataGridNodesByLayerId.delete(layer.layerId);
            }
        }, this);

        mutations.additions.forEach(function(layer) {
            let node = this._dataGridNodeForLayer(layer);
            if (node)
                dataGrid.appendChild(node);
        }, this);

        mutations.preserved.forEach(function(layer) {
            let node = this._dataGridNodesByLayerId.get(layer.layerId);
            if (node)
                node.layer = layer;
        }, this);

        this._sortDataGrid();

        this._childLayersRow.dataGrid = !isEmptyObject(childLayers) ? this._dataGrid : null;
    }

    _dataGridNodeForLayer(layer)
    {
        let node = new WI.LayerTreeDataGridNode(layer);
        this._dataGridNodesByLayerId.set(layer.layerId, node);

        return node;
    }

    _updateMetrics(layerForNode, childLayers)
    {
        var layerCount = 0;
        var totalMemory = 0;

        if (layerForNode) {
            layerCount++;
            totalMemory += layerForNode.memory || 0;
        }

        childLayers.forEach(function(layer) {
            layerCount++;
            totalMemory += layer.memory || 0;
        });

        this._layersCountLabel.textContent = WI.UIString("Layer Count: %d").format(layerCount);
        this._layersMemoryLabel.textContent = WI.UIString("Memory: %s").format(Number.bytesToString(totalMemory));
    }

    _showPopoverForSelectedNode()
    {
        var dataGridNode = this._dataGrid.selectedNode;
        if (!dataGridNode)
            return;

        this._contentForPopover(dataGridNode.layer, (content) => {
            if (dataGridNode === this._dataGrid.selectedNode)
                this._updatePopoverForSelectedNode(content);
        });
    }

    _updatePopoverForSelectedNode(content)
    {
        var dataGridNode = this._dataGrid.selectedNode;
        if (!dataGridNode)
            return;

        var popover = this._popover;
        if (!popover) {
            popover = this._popover = new WI.Popover;
            popover.windowResizeHandler = () => { this._updatePopoverForSelectedNode(); };
        }

        var targetFrame = WI.Rect.rectFromClientRect(dataGridNode.element.getBoundingClientRect());

        if (content)
            this._popover.presentNewContentWithFrame(content, targetFrame.pad(2), [WI.RectEdge.MIN_X]);
        else
            popover.present(targetFrame.pad(2), [WI.RectEdge.MIN_X]);
    }

    _hidePopover()
    {
        if (this._popover)
            this._popover.dismiss();
    }

    _contentForPopover(layer, callback)
    {
        var content = document.createElement("div");
        content.className = "layer-tree-popover";

        content.appendChild(document.createElement("p")).textContent = WI.UIString("Reasons for compositing:");

        var list = content.appendChild(document.createElement("ul"));

        WI.layerTreeManager.reasonsForCompositingLayer(layer, (compositingReasons) => {
            if (isEmptyObject(compositingReasons)) {
                callback(content);
                return;
            }

            this._populateListOfCompositingReasons(list, compositingReasons);

            callback(content);
        });

        return content;
    }

    _populateListOfCompositingReasons(list, compositingReasons)
    {
        function addReason(reason)
        {
            list.appendChild(document.createElement("li")).textContent = reason;
        }

        if (compositingReasons.transform3D)
            addReason(WI.UIString("Element has a 3D transform"));
        if (compositingReasons.video)
            addReason(WI.UIString("Element is <video>"));
        if (compositingReasons.canvas)
            addReason(WI.UIString("Element is <canvas>"));
        if (compositingReasons.plugin)
            addReason(WI.UIString("Element is a plug-in"));
        if (compositingReasons.iFrame)
            addReason(WI.UIString("Element is <iframe>"));
        if (compositingReasons.backfaceVisibilityHidden)
            addReason(WI.UIString("Element has “backface-visibility: hidden” style"));
        if (compositingReasons.clipsCompositingDescendants)
            addReason(WI.UIString("Element clips compositing descendants"));
        if (compositingReasons.animation)
            addReason(WI.UIString("Element is animated"));
        if (compositingReasons.filters)
            addReason(WI.UIString("Element has CSS filters applied"));
        if (compositingReasons.positionFixed)
            addReason(WI.UIString("Element has “position: fixed” style"));
        if (compositingReasons.positionSticky)
            addReason(WI.UIString("Element has “position: sticky” style"));
        if (compositingReasons.overflowScrollingTouch)
            addReason(WI.UIString("Element has “-webkit-overflow-scrolling: touch” style"));
        if (compositingReasons.stacking)
            addReason(WI.UIString("Element may overlap another compositing element"));
        if (compositingReasons.overlap)
            addReason(WI.UIString("Element overlaps other compositing element"));
        if (compositingReasons.negativeZIndexChildren)
            addReason(WI.UIString("Element has children with a negative z-index"));
        if (compositingReasons.transformWithCompositedDescendants)
            addReason(WI.UIString("Element has a 2D transform and composited descendants"));
        if (compositingReasons.opacityWithCompositedDescendants)
            addReason(WI.UIString("Element has opacity applied and composited descendants"));
        if (compositingReasons.maskWithCompositedDescendants)
            addReason(WI.UIString("Element is masked and composited descendants"));
        if (compositingReasons.reflectionWithCompositedDescendants)
            addReason(WI.UIString("Element has a reflection and composited descendants"));
        if (compositingReasons.filterWithCompositedDescendants)
            addReason(WI.UIString("Element has CSS filters applied and composited descendants"));
        if (compositingReasons.blendingWithCompositedDescendants)
            addReason(WI.UIString("Element has CSS blending applied and composited descendants"));
        if (compositingReasons.isolatesCompositedBlendingDescendants)
            addReason(WI.UIString("Element is a stacking context and has composited descendants with CSS blending applied"));
        if (compositingReasons.perspective)
            addReason(WI.UIString("Element has perspective applied"));
        if (compositingReasons.preserve3D)
            addReason(WI.UIString("Element has “transform-style: preserve-3d” style"));
        if (compositingReasons.willChange)
            addReason(WI.UIString("Element has “will-change” style with includes opacity, transform, transform-style, perspective, filter or backdrop-filter"));
        if (compositingReasons.root)
            addReason(WI.UIString("Element is the root element"));
        if (compositingReasons.blending)
            addReason(WI.UIString("Element has “blend-mode” style"));
    }
};
