/*
 * Copyright (C) 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.RenderingFrameTimelineView = class RenderingFrameTimelineView extends WI.TimelineView
{
    constructor(timeline, extraArguments)
    {
        super(timeline, extraArguments);

        console.assert(WI.TimelineRecord.Type.RenderingFrame);

        var scopeBarItems = [];
        for (var key in WI.RenderingFrameTimelineView.DurationFilter) {
            var value = WI.RenderingFrameTimelineView.DurationFilter[key];
            scopeBarItems.push(new WI.ScopeBarItem(value, WI.RenderingFrameTimelineView.displayNameForDurationFilter(value)));
        }

        this._scopeBar = new WI.ScopeBar("rendering-frame-scope-bar", scopeBarItems, scopeBarItems[0], true);
        this._scopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._scopeBarSelectionDidChange, this);

        let columns = {name: {}, totalTime: {}, scriptTime: {}, layoutTime: {}, paintTime: {}, otherTime: {}, startTime: {}, location: {}};

        columns.name.title = WI.UIString("Name");
        columns.name.width = "20%";
        columns.name.icon = true;
        columns.name.disclosure = true;
        columns.name.locked = true;

        columns.totalTime.title = WI.UIString("Total Time");
        columns.totalTime.width = "15%";
        columns.totalTime.aligned = "right";

        columns.scriptTime.title = WI.RenderingFrameTimelineRecord.displayNameForTaskType(WI.RenderingFrameTimelineRecord.TaskType.Script);
        columns.scriptTime.width = "10%";
        columns.scriptTime.aligned = "right";

        columns.layoutTime.title = WI.RenderingFrameTimelineRecord.displayNameForTaskType(WI.RenderingFrameTimelineRecord.TaskType.Layout);
        columns.layoutTime.width = "10%";
        columns.layoutTime.aligned = "right";

        columns.paintTime.title = WI.RenderingFrameTimelineRecord.displayNameForTaskType(WI.RenderingFrameTimelineRecord.TaskType.Paint);
        columns.paintTime.width = "10%";
        columns.paintTime.aligned = "right";

        columns.otherTime.title = WI.RenderingFrameTimelineRecord.displayNameForTaskType(WI.RenderingFrameTimelineRecord.TaskType.Other);
        columns.otherTime.width = "10%";
        columns.otherTime.aligned = "right";

        columns.startTime.title = WI.UIString("Start Time");
        columns.startTime.width = "15%";
        columns.startTime.aligned = "right";

        columns.location.title = WI.UIString("Location");

        for (var column in columns)
            columns[column].sortable = true;

        this._dataGrid = new WI.TimelineDataGrid(columns);
        this._dataGrid.sortColumnIdentifier = "startTime";
        this._dataGrid.sortOrder = WI.DataGrid.SortOrder.Ascending;
        this._dataGrid.createSettings("rendering-frame-timeline-view");

        this.setupDataGrid(this._dataGrid);

        this.element.classList.add("rendering-frame");
        this.addSubview(this._dataGrid);

        timeline.addEventListener(WI.Timeline.Event.RecordAdded, this._renderingFrameTimelineRecordAdded, this);

        this._pendingRecords = [];

        for (let record of timeline.records)
            this._processRecord(record);
    }

    static displayNameForDurationFilter(filter)
    {
        switch (filter) {
            case WI.RenderingFrameTimelineView.DurationFilter.All:
                return WI.UIString("All");
            case WI.RenderingFrameTimelineView.DurationFilter.OverOneMillisecond:
                return WI.UIString("Over 1 ms");
            case WI.RenderingFrameTimelineView.DurationFilter.OverFifteenMilliseconds:
                return WI.UIString("Over 15 ms");
            default:
                console.error("Unknown filter type", filter);
        }

        return null;
    }

    // Public

    get showsLiveRecordingData() { return false; }

    closed()
    {
        this.representedObject.removeEventListener(WI.Timeline.Event.RecordAdded, this._renderingFrameTimelineRecordAdded, this);

        this._dataGrid.closed();
    }

    get selectionPathComponents()
    {
        let dataGridNode = this._dataGrid.selectedNode;
        if (!dataGridNode || dataGridNode.hidden)
            return null;

        let pathComponents = [];

        while (dataGridNode && !dataGridNode.root) {
            console.assert(dataGridNode instanceof WI.TimelineDataGridNode);
            if (dataGridNode.hidden)
                return null;

            let pathComponent = new WI.TimelineDataGridNodePathComponent(dataGridNode);
            pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this.dataGridNodePathComponentSelected, this);
            pathComponents.unshift(pathComponent);
            dataGridNode = dataGridNode.parent;
        }

        return pathComponents;
    }

    get filterStartTime()
    {
        let records = this.representedObject.records;
        let startIndex = this.startTime;
        if (startIndex >= records.length)
            return Infinity;

        return records[startIndex].startTime;
    }

    get filterEndTime()
    {
        let records = this.representedObject.records;
        let endIndex = this.endTime - 1;
        if (endIndex >= records.length)
            return Infinity;

        return records[endIndex].endTime;
    }

    reset()
    {
        super.reset();

        this._dataGrid.reset();

        this._pendingRecords = [];
    }

    // Protected

    dataGridNodePathComponentSelected(event)
    {
        let dataGridNode = event.data.pathComponent.timelineDataGridNode;
        console.assert(dataGridNode.dataGrid === this._dataGrid);

        dataGridNode.revealAndSelect();
    }

    matchDataGridNodeAgainstCustomFilters(node)
    {
        if (!super.matchDataGridNodeAgainstCustomFilters(node))
            return false;

        console.assert(node instanceof WI.TimelineDataGridNode);
        console.assert(this._scopeBar.selectedItems.length === 1);
        let selectedScopeBarItem = this._scopeBar.selectedItems[0];
        if (!selectedScopeBarItem || selectedScopeBarItem.id === WI.RenderingFrameTimelineView.DurationFilter.All)
            return true;

        while (node && !(node.record instanceof WI.RenderingFrameTimelineRecord))
            node = node.parent;

        console.assert(node, "Cannot apply duration filter: no RenderingFrameTimelineRecord found.");
        if (!node)
            return false;

        let minimumDuration = selectedScopeBarItem.id === WI.RenderingFrameTimelineView.DurationFilter.OverOneMillisecond ? 0.001 : 0.015;
        return node.record.duration > minimumDuration;
    }

    layout()
    {
        this._processPendingRecords();
    }

    // Private

    _processPendingRecords()
    {
        if (!this._pendingRecords.length)
            return;

        for (let renderingFrameTimelineRecord of this._pendingRecords) {
            console.assert(renderingFrameTimelineRecord instanceof WI.RenderingFrameTimelineRecord);

            let dataGridNode = new WI.RenderingFrameTimelineDataGridNode(renderingFrameTimelineRecord, {
                graphDataSource: this,
            });
            this._dataGrid.addRowInSortOrder(dataGridNode);

            let stack = [{children: renderingFrameTimelineRecord.children, parentDataGridNode: dataGridNode, index: 0}];
            while (stack.length) {
                let entry = stack.lastValue;
                if (entry.index >= entry.children.length) {
                    stack.pop();
                    continue;
                }

                let childRecord = entry.children[entry.index];
                let childDataGridNode = null;
                if (childRecord.type === WI.TimelineRecord.Type.Layout) {
                    childDataGridNode = new WI.LayoutTimelineDataGridNode(childRecord, {
                        graphDataSource: this,
                    });

                    this._dataGrid.addRowInSortOrder(childDataGridNode, entry.parentDataGridNode);
                } else if (childRecord.type === WI.TimelineRecord.Type.Script) {
                    let rootNodes = [];
                    if (childRecord.profile) {
                        // FIXME: Support using the bottom-up tree once it is implemented.
                        rootNodes = childRecord.profile.topDownRootNodes;
                    }

                    childDataGridNode = new WI.ScriptTimelineDataGridNode(childRecord, {
                        graphDataSource: this,
                    });

                    this._dataGrid.addRowInSortOrder(childDataGridNode, entry.parentDataGridNode);

                    for (let profileNode of rootNodes) {
                        let profileNodeDataGridNode = new WI.ProfileNodeDataGridNode(profileNode, {
                            graphDataSource: this,
                        });
                        this._dataGrid.addRowInSortOrder(profileNodeDataGridNode, childDataGridNode);
                    }
                }

                if (childDataGridNode && childRecord.children.length)
                    stack.push({children: childRecord.children, parentDataGridNode: childDataGridNode, index: 0});
                ++entry.index;
            }
        }

        this._pendingRecords = [];
    }

    _renderingFrameTimelineRecordAdded(event)
    {
        let renderingFrameTimelineRecord = event.data.record;
        console.assert(renderingFrameTimelineRecord instanceof WI.RenderingFrameTimelineRecord);
        console.assert(renderingFrameTimelineRecord.children.length, "Missing child records for rendering frame.");

        this._processRecord(renderingFrameTimelineRecord);

        this.needsLayout();
    }

    _processRecord(renderingFrameTimelineRecord)
    {
        this._pendingRecords.push(renderingFrameTimelineRecord);
    }

    _scopeBarSelectionDidChange()
    {
        this._dataGrid.filterDidChange();
    }
};

WI.RenderingFrameTimelineView.DurationFilter = {
    All: "rendering-frame-timeline-view-duration-filter-all",
    OverOneMillisecond: "rendering-frame-timeline-view-duration-filter-over-1-ms",
    OverFifteenMilliseconds: "rendering-frame-timeline-view-duration-filter-over-15-ms"
};

