/*
 * Copyright (C) 2018 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.MediaTimelineView = class MediaTimelineView extends WI.TimelineView
{
    constructor(timeline, extraArguments)
    {
        console.assert(timeline instanceof WI.Timeline);
        console.assert(timeline.type === WI.TimelineRecord.Type.Media);

        super(timeline, extraArguments);

        this._timelineRuler = new WI.TimelineRuler;

        const columns = {
            name: {
                title: WI.UIString("Name"),
                width: "200px",
                icon: true,
                sortable: true,
                locked: true,
            },
            element: {
                title: WI.UIString("Element"),
                width: "150px",
                sortable: true,
            },
            time: {
                title: WI.UIString("Time"),
                width: "80px",
                sortable: true,
                locked: true,
            },
            originator: {
                title: WI.UIString("Originator"),
                width: "150px",
                sortable: true,
                hidden: true,
            },
            graph: {
                headerView: this._timelineRuler,
                locked: true,
            },
        };

        this._dataGrid = new WI.TimelineDataGrid(columns);
        this._dataGrid.sortDelegate = this;
        this._dataGrid.sortColumnIdentifier = "time";
        this._dataGrid.sortOrder = WI.DataGrid.SortOrder.Ascending;
        this._dataGrid.setColumnVisible("originator", false);
        this._dataGrid.createSettings("media-timeline-view");
        this.setupDataGrid(this._dataGrid);
        this.addSubview(this._dataGrid);

        this.element.classList.add("media");

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

        this._pendingRecords = [];

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

    // Public

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

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

        let pathComponent = new WI.TimelineDataGridNodePathComponent(this._dataGrid.selectedNode);
        pathComponent.addEventListener(WI.HierarchicalPathComponent.Event.SiblingWasSelected, this._handleSelectionPathComponentSiblingSelected, this);
        return [pathComponent];
    }

    closed()
    {
        this.representedObject.removeEventListener(null, null, this);

        super.closed();
    }

    reset()
    {
        super.reset();

        this._pendingRecords = [];
    }

    // TimelineDataGrid delegate

    dataGridSortComparator(sortColumnIdentifier, sortDirection, node1, node2)
    {
        function compareDOMNodes(a, b) {
            if (a && !b)
                return -1;
            if (b && !a)
                return 1;
            if (!a && !b)
                return 0;
            return a.id - b.id;
        }

        if (sortColumnIdentifier === "name") {
            let displayName1 = node1.displayName();
            let displayName2 = node2.displayName();
            return displayName1.extendedLocaleCompare(displayName2) * sortDirection;
        }

        if (sortColumnIdentifier === "element")
            return compareDOMNodes(node1.record.domNode, node2.record.domNode) * sortDirection;

        if (sortColumnIdentifier === "time")
            return (node1.record.startTime - node2.record.startTime) * sortDirection;

        if (sortColumnIdentifier === "originator") {
            function getOriginator(record) {
                if (record.eventType !== WI.MediaTimelineRecord.EventType.DOMEvent || !record.domEvent)
                    return null;
                return record.domEvent.originator;
            }
            return compareDOMNodes(getOriginator(node1.record), getOriginator(node2.record)) * sortDirection;
        }

        return null;
    }

    // Protected

    layout()
    {
        super.layout();

        this.endTime = Math.min(this.endTime, this.currentTime);

        let oldZeroTime = this._timelineRuler.zeroTime;
        let oldStartTime = this._timelineRuler.startTime;
        let oldEndTime = this._timelineRuler.endTime;

        this._timelineRuler.zeroTime = this.zeroTime;
        this._timelineRuler.startTime = this.startTime;
        this._timelineRuler.endTime = this.endTime;

        // We only need to refresh the graphs when the any of the times change.
        if (this.zeroTime !== oldZeroTime || this.startTime !== oldStartTime || this.endTime !== oldEndTime) {
            for (let dataGridNode of this._dataGrid.children)
                dataGridNode.refreshGraph();
        }

        this._processPendingRecords();
    }

    // Private

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

        for (let timelineRecord of this._pendingRecords) {
            if (timelineRecord.domEvent && timelineRecord.domEvent.originator)
                this._dataGrid.setColumnVisible("originator", true);

            this._dataGrid.addRowInSortOrder(new WI.MediaTimelineDataGridNode(timelineRecord, {
                graphDataSource: this,
            }));
        }

        this._pendingRecords = [];
    }

    _handleRecordAdded(event)
    {
        let mediaTimelineRecord = event.data.record;
        console.assert(mediaTimelineRecord instanceof WI.MediaTimelineRecord);

        this._processRecord(mediaTimelineRecord);

        this.needsLayout();
    }

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

    _handleSelectionPathComponentSiblingSelected(event)
    {
        let pathComponent = event.data.pathComponent;
        console.assert(pathComponent instanceof WI.TimelineDataGridNodePathComponent);

        let dataGridNode = pathComponent.timelineDataGridNode;
        console.assert(dataGridNode.dataGrid === this._dataGrid);

        dataGridNode.revealAndSelect();
    }
};
