/*
 * 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 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.TimelineOverviewGraph = class TimelineOverviewGraph extends WI.View
{
    constructor(timelineOverview)
    {
        super();

        this.element.classList.add("timeline-overview-graph");

        this._zeroTime = 0;
        this._startTime = 0;
        this._endTime = 5;
        this._currentTime = 0;
        this._timelineOverview = timelineOverview;
        this._selectedRecord = null;
        this._selectedRecordBar = null;
        this._scheduledSelectedRecordLayoutUpdateIdentifier = undefined;
        this._selected = false;
        this._hidden = false;
    }

    // Public

    static createForTimeline(timeline, timelineOverview)
    {
        console.assert(timeline instanceof WI.Timeline, timeline);
        console.assert(timelineOverview instanceof WI.TimelineOverview, timelineOverview);

        var timelineType = timeline.type;
        if (timelineType === WI.TimelineRecord.Type.Network)
            return new WI.NetworkTimelineOverviewGraph(timeline, timelineOverview);

        if (timelineType === WI.TimelineRecord.Type.Layout)
            return new WI.LayoutTimelineOverviewGraph(timeline, timelineOverview);

        if (timelineType === WI.TimelineRecord.Type.Script)
            return new WI.ScriptTimelineOverviewGraph(timeline, timelineOverview);

        if (timelineType === WI.TimelineRecord.Type.RenderingFrame)
            return new WI.RenderingFrameTimelineOverviewGraph(timeline, timelineOverview);

        if (timelineType === WI.TimelineRecord.Type.CPU)
            return new WI.CPUTimelineOverviewGraph(timeline, timelineOverview);

        if (timelineType === WI.TimelineRecord.Type.Memory)
            return new WI.MemoryTimelineOverviewGraph(timeline, timelineOverview);

        if (timelineType === WI.TimelineRecord.Type.HeapAllocations)
            return new WI.HeapAllocationsTimelineOverviewGraph(timeline, timelineOverview);

        if (timelineType === WI.TimelineRecord.Type.Media)
            return new WI.MediaTimelineOverviewGraph(timeline, timelineOverview);

        if (timelineType === WI.TimelineRecord.Type.Screenshots)
            return new WI.ScreenshotsTimelineOverviewGraph(timeline, timelineOverview);

        throw new Error("Can't make a graph for an unknown timeline.");
    }

    get zeroTime()
    {
        return this._zeroTime;
    }

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

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

        this._zeroTime = x;

        this.needsLayout();
    }

    get startTime()
    {
        return this._startTime;
    }

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

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

        this._startTime = x;

        this.needsLayout();
    }

    get endTime()
    {
        return this._endTime;
    }

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

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

        this._endTime = x;

        this.needsLayout();
    }

    get currentTime()
    {
        return this._currentTime;
    }

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

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

        let oldCurrentTime = this._currentTime;

        this._currentTime = x;

        if ((this._startTime <= oldCurrentTime && oldCurrentTime <= this._endTime) || (this._startTime <= this._currentTime && this._currentTime <= this._endTime))
            this.needsLayout();
    }

    get timelineOverview()
    {
        return this._timelineOverview;
    }

    get secondsPerPixel() { return this._timelineOverview.secondsPerPixel; }

    get hidden()
    {
        return this._hidden;
    }

    set hidden(hidden)
    {
        if (!xor(hidden, this._hidden))
            return;

        this._hidden = hidden;

        this.element.classList.toggle("hidden", this._hidden);

        if (!this._hidden)
            this.updateLayout();
    }

    get selectedRecord()
    {
        return this._selectedRecord;
    }

    set selectedRecord(x)
    {
        if (this._selectedRecord === x)
            return;

        this._selectedRecord = x;

        this._needsSelectedRecordLayout();
    }

    get selectedRecordBar()
    {
        return this._selectedRecordBar;
    }

    set selectedRecordBar(recordBar)
    {
        if (this._selectedRecordBar === recordBar)
            return;

        if (this._selectedRecordBar)
            this._selectedRecordBar.selected = false;

        this._selectedRecordBar = recordBar;

        if (this._selectedRecordBar) {
            this._selectedRecordBar.selected = true;

            console.assert(this._selectedRecordBar.records.includes(this._selectedRecord));
        }
    }

    get height()
    {
        // Overridden by sub-classes if needed.
        return 36;
    }

    get selected()
    {
        return this._selected;
    }

    set selected(x)
    {
        if (this._selected === x)
            return;

        this._selected = x;
        this.element.classList.toggle("selected", this._selected);
    }

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

    recordWasFiltered(record, filtered)
    {
        // Implemented by sub-classes if needed.
    }

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

        super.needsLayout();
    }

    didLayoutSubtree()
    {
        super.didLayoutSubtree();

        this.updateSelectedRecord();
    }

    // TimelineRecordBar delegate

    timelineRecordBarClicked(timelineRecordBar)
    {
        this.selectedRecord = timelineRecordBar.records[0];
    }

    // Protected

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

    // Private

    _needsSelectedRecordLayout()
    {
        // If layout is scheduled, abort since the selected record will be updated when layout happens.
        if (this.layoutPending)
            return;

        if (this._scheduledSelectedRecordLayoutUpdateIdentifier)
            return;

        this._scheduledSelectedRecordLayoutUpdateIdentifier = requestAnimationFrame(() => {
            this._scheduledSelectedRecordLayoutUpdateIdentifier = undefined;

            this.updateSelectedRecord();
            this.dispatchEventToListeners(WI.TimelineOverviewGraph.Event.RecordSelected, {record: this.selectedRecord, recordBar: this.selectedRecordBar});
        });
    }
};

WI.TimelineOverviewGraph.Event = {
    RecordSelected: "timeline-overview-graph-record-selected"
};
