/*
 * Copyright (C) 2013 University of Washington. All rights reserved.
 * Copyright (C) 2014, 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * HOLDER OR 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.ProbeSetDataGrid = class ProbeSetDataGrid extends WI.DataGrid
{
    constructor(probeSet)
    {
        console.assert(probeSet instanceof WI.ProbeSet, "Invalid ProbeSet argument: ", probeSet);

        var columns = {};
        for (var probe of probeSet.probes) {
            var title = probe.expression || WI.UIString("(uninitialized)");
            columns[WI.ProbeSetDataGrid.columnIdentifierForProbe(probe)] = {title};
        }

        super(columns);

        this.probeSet = probeSet;

        this.inline = true;

        this._frameNodes = new Map;
        this._lastUpdatedFrame = null;
        this._nodesSinceLastNavigation = [];

        this._listenerSet = new WI.EventListenerSet(this, "ProbeSetDataGrid instance listeners");
        this._listenerSet.register(probeSet, WI.ProbeSet.Event.ProbeAdded, this._setupProbe);
        this._listenerSet.register(probeSet, WI.ProbeSet.Event.ProbeRemoved, this._teardownProbe);
        this._listenerSet.register(probeSet, WI.ProbeSet.Event.SamplesCleared, this._setupData);
        this._listenerSet.register(WI.Probe, WI.Probe.Event.ExpressionChanged, this._probeExpressionChanged);
        this._listenerSet.install();

        this._setupData();
    }

    // Static

    static columnIdentifierForProbe(probe)
    {
        return "probe" + probe.id;
    }

    // Public

    closed()
    {
        for (var probe of this.probeSet)
            this._teardownProbe(probe);

        this._listenerSet.uninstall(true);
    }

    // Private

    _setupProbe(event)
    {
        var probe = event.data;
        this.insertColumn(WI.ProbeSetDataGrid.columnIdentifierForProbe(probe), {title: probe.expression});

        for (var frame of this._data.frames)
            this._updateNodeForFrame(frame);
    }

    _teardownProbe(event)
    {
        var probe = event.data;
        this.removeColumn(WI.ProbeSetDataGrid.columnIdentifierForProbe(probe));

        for (var frame of this._data.frames)
            this._updateNodeForFrame(frame);
    }

    _setupData()
    {
        this._data = this.probeSet.dataTable;
        for (var frame of this._data.frames)
            this._updateNodeForFrame(frame);

        this._dataListeners = new WI.EventListenerSet(this, "ProbeSetDataGrid data table listeners");
        this._dataListeners.register(this._data, WI.ProbeSetDataTable.Event.FrameInserted, this._dataFrameInserted);
        this._dataListeners.register(this._data, WI.ProbeSetDataTable.Event.SeparatorInserted, this._dataSeparatorInserted);
        this._dataListeners.register(this._data, WI.ProbeSetDataTable.Event.WillRemove, this._teardownData);
        this._dataListeners.install();
    }

    _teardownData()
    {
        this._dataListeners.uninstall(true);
        this.removeChildren();
        this._frameNodes = new Map;
        this._lastUpdatedFrame = null;
    }

    _updateNodeForFrame(frame)
    {
        console.assert(frame instanceof WI.ProbeSetDataFrame, "Invalid ProbeSetDataFrame argument: ", frame);
        var node = null;
        if (this._frameNodes.has(frame)) {
            node = this._frameNodes.get(frame);
            node.frame = frame;
            node.refresh();
        } else {
            node = new WI.ProbeSetDataGridNode(this);
            node.frame = frame;
            this._frameNodes.set(frame, node);
            node.createCells();

            var sortFunction = function(a, b) {
                return WI.ProbeSetDataFrame.compare(a.frame, b.frame);
            };
            var insertionIndex = insertionIndexForObjectInListSortedByFunction(node, this.children, sortFunction);
            if (insertionIndex === this.children.length)
                this.appendChild(node);
            else if (this.children[insertionIndex].frame.key === frame.key) {
                this.removeChild(this.children[insertionIndex]);
                this.insertChild(node, insertionIndex);
            } else
                this.insertChild(node, insertionIndex);
        }
        console.assert(node);

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

        node.element.classList.add("data-updated");
        window.setTimeout(function() {
            node.element.classList.remove("data-updated");
        }, WI.ProbeSetDataGrid.DataUpdatedAnimationDuration);

        this._nodesSinceLastNavigation.push(node);
    }

    _updateNodeForSeparator(frame)
    {
        console.assert(this._frameNodes.has(frame), "Tried to add separator for unknown data frame: ", frame);
        this._frameNodes.get(frame).updateCellsForSeparator(frame, this.probeSet);

        for (var node of this._nodesSinceLastNavigation)
            node.element.classList.add("past-value");

        this._nodesSinceLastNavigation = [];
    }

    _dataFrameInserted(event)
    {
        var frame = event.data;
        this._lastUpdatedFrame = frame;
        this._updateNodeForFrame(frame);
    }

    _dataSeparatorInserted(event)
    {
        var frame = event.data;
        this._updateNodeForSeparator(frame);
    }

    _probeExpressionChanged(event)
    {
        var probe = event.target;
        if (probe.breakpoint !== this.probeSet.breakpoint)
            return;

        let columnIdentifier = WI.ProbeSetDataGrid.columnIdentifierForProbe(probe);
        if (!this.columns.has(columnIdentifier))
            return;

        var oldColumn = this.columns.get(columnIdentifier);
        this.removeColumn(columnIdentifier);
        var ordinal = oldColumn["ordinal"];
        var newColumn = {title: event.data.newValue};
        this.insertColumn(columnIdentifier, newColumn, ordinal);

        for (var frame of this._data.frames)
            this._updateNodeForFrame(frame);
    }
};

WI.ProbeSetDataGrid.DataUpdatedAnimationDuration = 300; // milliseconds
