/*
 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
 * Copyright (C) 2015 University of Washington.
 *
 * 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.TimelineView = class TimelineView extends WI.ContentView
{
    constructor(representedObject)
    {
        super(representedObject);

        // This class should not be instantiated directly. Create a concrete subclass instead.
        console.assert(this.constructor !== WI.TimelineView && this instanceof WI.TimelineView);

        this.element.classList.add("timeline-view");

        this._zeroTime = 0;
        this._startTime = 0;
        this._endTime = 5;
        this._currentTime = 0;
    }

    // Public

    get scrollableElements()
    {
        if (!this._timelineDataGrid)
            return [];
        return [this._timelineDataGrid.scrollContainer];
    }

    get showsLiveRecordingData()
    {
        // Implemented by sub-classes if needed.
        return true;
    }

    get showsImportedRecordingMessage()
    {
        // Implemented by sub-classes if needed.
        return false;
    }

    get showsFilterBar()
    {
        // Implemented by sub-classes if needed.
        return true;
    }

    get navigationItems()
    {
        return this._scopeBar ? [this._scopeBar] : [];
    }

    get selectionPathComponents()
    {
        // Implemented by sub-classes if needed.
        return null;
    }

    get zeroTime()
    {
        return this._zeroTime;
    }

    set zeroTime(x)
    {
        x = x || 0;

        if (this._zeroTime === x)
            return;

        this._zeroTime = x;

        this._timesDidChange();
    }

    get startTime()
    {
        return this._startTime;
    }

    set startTime(x)
    {
        x = x || 0;

        if (this._startTime === x)
            return;

        this._startTime = x;

        this._timesDidChange();
        this._scheduleFilterDidChange();
    }

    get endTime()
    {
        return this._endTime;
    }

    set endTime(x)
    {
        x = x || 0;

        if (this._endTime === x)
            return;

        this._endTime = x;

        this._timesDidChange();
        this._scheduleFilterDidChange();
    }

    get currentTime()
    {
        return this._currentTime;
    }

    set currentTime(x)
    {
        x = x || 0;

        if (this._currentTime === x)
            return;

        let oldCurrentTime = this._currentTime;

        this._currentTime = x;

        function checkIfLayoutIsNeeded(currentTime)
        {
            // Include some wiggle room since the current time markers can be clipped off the ends a bit and still partially visible.
            const wiggleTime = 0.05; // 50ms
            return this._startTime - wiggleTime <= currentTime && currentTime <= this._endTime + wiggleTime;
        }

        if (checkIfLayoutIsNeeded.call(this, oldCurrentTime) || checkIfLayoutIsNeeded.call(this, this._currentTime))
            this._timesDidChange();
    }

    get filterStartTime()
    {
        // Implemented by sub-classes if needed.
        return this.startTime;
    }

    get filterEndTime()
    {
        // Implemented by sub-classes if needed.
        return this.endTime;
    }

    setupDataGrid(dataGrid)
    {
        if (this._timelineDataGrid) {
            this._timelineDataGrid.filterDelegate = null;
            this._timelineDataGrid.removeEventListener(WI.DataGrid.Event.SelectedNodeChanged, this._timelineDataGridSelectedNodeChanged, this);
            this._timelineDataGrid.removeEventListener(WI.DataGrid.Event.NodeWasFiltered, this._timelineDataGridNodeWasFiltered, this);
            this._timelineDataGrid.removeEventListener(WI.DataGrid.Event.FilterDidChange, this.filterDidChange, this);
        }

        this._timelineDataGrid = dataGrid;
        this._timelineDataGrid.filterDelegate = this;
        this._timelineDataGrid.addEventListener(WI.DataGrid.Event.SelectedNodeChanged, this._timelineDataGridSelectedNodeChanged, this);
        this._timelineDataGrid.addEventListener(WI.DataGrid.Event.NodeWasFiltered, this._timelineDataGridNodeWasFiltered, this);
        this._timelineDataGrid.addEventListener(WI.DataGrid.Event.FilterDidChange, this.filterDidChange, this);
    }

    selectRecord(record)
    {
        if (!this._timelineDataGrid)
            return;

        let selectedDataGridNode = this._timelineDataGrid.selectedNode;
        if (!record) {
            if (selectedDataGridNode)
                selectedDataGridNode.deselect();
            return;
        }

        let dataGridNode = this._timelineDataGrid.findNode((node) => node.record === record);
        console.assert(dataGridNode, "Timeline view has no grid node for record selected in timeline overview.", this, record);
        if (!dataGridNode || dataGridNode.selected)
            return;

        // Don't select the record's grid node if one of it's children is already selected.
        if (selectedDataGridNode && selectedDataGridNode.hasAncestor(dataGridNode))
            return;

        dataGridNode.revealAndSelect();
    }

    reset()
    {
        // Implemented by sub-classes if needed.
    }

    updateFilter(filters)
    {
        if (!this._timelineDataGrid)
            return;

        this._timelineDataGrid.filterText = filters ? filters.text : "";
    }

    matchDataGridNodeAgainstCustomFilters(node)
    {
        // Implemented by sub-classes if needed.
        return true;
    }

    needsLayout()
    {
        // FIXME: needsLayout can be removed once <https://webkit.org/b/150741> is fixed.
        if (!this.visible)
            return;

        super.needsLayout();
    }

    // DataGrid filter delegate

    dataGridMatchNodeAgainstCustomFilters(node)
    {
        console.assert(node);
        if (!this.matchDataGridNodeAgainstCustomFilters(node))
            return false;

        let startTime = this.filterStartTime;
        let endTime = this.filterEndTime;
        let currentTime = this.currentTime;

        function checkTimeBounds(itemStartTime, itemEndTime)
        {
            itemStartTime = itemStartTime || currentTime;
            itemEndTime = itemEndTime || currentTime;

            return startTime <= itemEndTime && itemStartTime <= endTime;
        }

        if (node instanceof WI.ResourceTimelineDataGridNode) {
            let resource = node.resource;
            return checkTimeBounds(resource.requestSentTimestamp, resource.finishedOrFailedTimestamp);
        }

        if (node instanceof WI.SourceCodeTimelineTimelineDataGridNode) {
            let sourceCodeTimeline = node.sourceCodeTimeline;

            // Do a quick check of the timeline bounds before we check each record.
            if (!checkTimeBounds(sourceCodeTimeline.startTime, sourceCodeTimeline.endTime))
                return false;

            for (let record of sourceCodeTimeline.records) {
                if (checkTimeBounds(record.startTime, record.endTime))
                    return true;
            }

            return false;
        }

        if (node instanceof WI.ProfileNodeDataGridNode) {
            let profileNode = node.profileNode;
            if (checkTimeBounds(profileNode.startTime, profileNode.endTime))
                return true;

            return false;
        }

        if (node instanceof WI.TimelineDataGridNode) {
            let record = node.record;
            return checkTimeBounds(record.startTime, record.endTime);
        }

        if (node instanceof WI.ProfileDataGridNode)
            return node.callingContextTreeNode.hasStackTraceInTimeRange(startTime, endTime);

        console.error("Unknown DataGridNode, can't filter by time.");
        return true;
    }

    // Protected

    filterDidChange()
    {
        // Implemented by sub-classes if needed.
    }

    // Private

    _timelineDataGridSelectedNodeChanged(event)
    {
        this.dispatchEventToListeners(WI.ContentView.Event.SelectionPathComponentsDidChange);
    }

    _timelineDataGridNodeWasFiltered(event)
    {
        let node = event.data.node;
        if (!(node instanceof WI.TimelineDataGridNode))
            return;

        this.dispatchEventToListeners(WI.TimelineView.Event.RecordWasFiltered, {record: node.record, filtered: node.hidden});
    }

    _timesDidChange()
    {
        if (!WI.timelineManager.isCapturing() || this.showsLiveRecordingData)
            this.needsLayout();
    }

    _scheduleFilterDidChange()
    {
        if (!this._timelineDataGrid || this._updateFilterTimeout)
            return;

        this._updateFilterTimeout = setTimeout(() => {
            this._updateFilterTimeout = undefined;
            this._timelineDataGrid.filterDidChange();
        }, 0);
    }
};

WI.TimelineView.Event = {
    RecordWasFiltered: "timeline-view-record-was-filtered",
    RecordWasSelected: "timeline-view-record-was-selected",
    ScannerShow: "timeline-view-scanner-show",
    ScannerHide: "timeline-view-scanner-hide",
    NeedsEntireSelectedRange: "timeline-view-needs-entire-selected-range",
};
