/*
 * 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.TimelineRecordBar = class TimelineRecordBar extends WI.Object
{
    constructor(delegate, records, renderMode)
    {
        super();

        this._delegate = delegate || null;

        this._element = document.createElement("div");
        this._element.classList.add("timeline-record-bar");
        this._element[WI.TimelineRecordBar.ElementReferenceSymbol] = this;
        this._element.addEventListener("click", this._handleClick.bind(this));

        this.renderMode = renderMode;
        this.records = records;
    }

    static createCombinedBars(records, secondsPerPixel, graphDataSource, createBarCallback)
    {
        if (!records.length)
            return;

        var startTime = graphDataSource.startTime;
        var currentTime = graphDataSource.currentTime;
        var endTime = graphDataSource.endTime;

        var visibleRecords = [];
        var usesActiveStartTime = false;
        var lastRecordType = null;

        // FIXME: Do a binary search for records that fall inside start and current time.

        for (var i = 0; i < records.length; ++i) {
            var record = records[i];
            if (isNaN(record.startTime))
                continue;

            // If this bar is completely before the bounds of the graph, skip this record.
            if (record.endTime < startTime)
                continue;

            // If this record is completely after the current time or end time, break out now.
            // Records are sorted, so all records after this will be beyond the current or end time too.
            if (record.startTime > currentTime || record.startTime > endTime)
                break;

            if (record.usesActiveStartTime)
                usesActiveStartTime = true;

            // If one record uses active time the rest are assumed to use it.
            console.assert(record.usesActiveStartTime === usesActiveStartTime);

            // Only a single record type is supported right now.
            console.assert(!lastRecordType || record.type === lastRecordType);

            visibleRecords.push(record);

            lastRecordType = record.type;
        }

        if (!visibleRecords.length)
            return;

        if (visibleRecords.length === 1) {
            createBarCallback(visibleRecords, WI.TimelineRecordBar.RenderMode.Normal);
            return;
        }

        function compareByActiveStartTime(a, b)
        {
            return a.activeStartTime - b.activeStartTime;
        }

        var minimumDuration = secondsPerPixel * WI.TimelineRecordBar.MinimumWidthPixels;
        var minimumMargin = secondsPerPixel * WI.TimelineRecordBar.MinimumMarginPixels;

        if (usesActiveStartTime) {
            var inactiveStartTime = NaN;
            var inactiveEndTime = NaN;
            var inactiveRecords = [];

            for (var i = 0; i < visibleRecords.length; ++i) {
                var record = visibleRecords[i];

                // Check if the previous record is far enough away to create the inactive bar.
                if (!isNaN(inactiveStartTime) && inactiveStartTime + Math.max(inactiveEndTime - inactiveStartTime, minimumDuration) + minimumMargin <= record.startTime) {
                    createBarCallback(inactiveRecords, WI.TimelineRecordBar.RenderMode.InactiveOnly);
                    inactiveRecords = [];
                    inactiveStartTime = NaN;
                    inactiveEndTime = NaN;
                }

                // If this is a new bar, peg the start time.
                if (isNaN(inactiveStartTime))
                    inactiveStartTime = record.startTime;

                // Update the end time to be the maximum we encounter. inactiveEndTime might be NaN, so "|| 0" to prevent Math.max from returning NaN.
                inactiveEndTime = Math.max(inactiveEndTime || 0, record.activeStartTime);

                inactiveRecords.push(record);
            }

            // Create the inactive bar for the last record if needed.
            if (!isNaN(inactiveStartTime))
                createBarCallback(inactiveRecords, WI.TimelineRecordBar.RenderMode.InactiveOnly);

            visibleRecords.sort(compareByActiveStartTime);
        }

        var activeStartTime = NaN;
        var activeEndTime = NaN;
        var activeRecords = [];

        var startTimeProperty = usesActiveStartTime ? "activeStartTime" : "startTime";

        for (var i = 0; i < visibleRecords.length; ++i) {
            var record = visibleRecords[i];
            var startTime = record[startTimeProperty];

            // Check if the previous record is far enough away to create the active bar. We also create it now if the current record has no active state time.
            if (!isNaN(activeStartTime) && (activeStartTime + Math.max(activeEndTime - activeStartTime, minimumDuration) + minimumMargin <= startTime
                || (isNaN(startTime) && !isNaN(activeEndTime)))) {
                createBarCallback(activeRecords, WI.TimelineRecordBar.RenderMode.ActiveOnly);
                activeRecords = [];
                activeStartTime = NaN;
                activeEndTime = NaN;
            }

            if (isNaN(startTime))
                continue;

            // If this is a new bar, peg the start time.
            if (isNaN(activeStartTime))
                activeStartTime = startTime;

            // Update the end time to be the maximum we encounter. activeEndTime might be NaN, so "|| 0" to prevent Math.max from returning NaN.
            if (!isNaN(record.endTime))
                activeEndTime = Math.max(activeEndTime || 0, record.endTime);

            activeRecords.push(record);
        }

        // Create the active bar for the last record if needed.
        if (!isNaN(activeStartTime))
            createBarCallback(activeRecords, WI.TimelineRecordBar.RenderMode.ActiveOnly);
    }

    static fromElement(element)
    {
        return element[WI.TimelineRecordBar.ElementReferenceSymbol] || null;
    }

    // Public

    get element()
    {
        return this._element;
    }

    get selected()
    {
        return this._element.classList.contains("selected");
    }

    set selected(selected)
    {
        this._element.classList.toggle("selected", !!selected);
    }

    get renderMode()
    {
        return this._renderMode;
    }

    set renderMode(renderMode)
    {
        this._renderMode = renderMode || WI.TimelineRecordBar.RenderMode.Normal;
    }

    get records()
    {
        return this._records;
    }

    set records(records)
    {
        let oldRecordType;
        let oldRecordEventType;
        let oldRecordUsesActiveStartTime = false;
        if (this._records && this._records.length) {
            let oldRecord = this._records[0];
            oldRecordType = oldRecord.type;
            oldRecordEventType = oldRecord.eventType;
            oldRecordUsesActiveStartTime = oldRecord.usesActiveStartTime;
        }

        records = records || [];

        this._records = records;

        // Assume all records in the group are the same type.
        if (this._records.length) {
            let newRecord = this._records[0];
            if (newRecord.type !== oldRecordType) {
                this._element.classList.remove(oldRecordType);
                this._element.classList.add(newRecord.type);
            }
            // Although all records may not have the same event type, the first record is
            // sufficient to determine the correct style for the record bar.
            if (newRecord.eventType !== oldRecordEventType) {
                this._element.classList.remove(oldRecordEventType);
                this._element.classList.add(newRecord.eventType);
            }
            if (newRecord.usesActiveStartTime !== oldRecordUsesActiveStartTime) {
                if (!this._delegate || !this._delegate.timelineRecordBarCustomChildren)
                    this._element.classList.toggle("has-inactive-segment", newRecord.usesActiveStartTime);
            }
        } else
            this._element.classList.remove(oldRecordType, oldRecordEventType, "has-inactive-segment");
    }

    refresh(graphDataSource)
    {
        if (isNaN(graphDataSource.secondsPerPixel))
            return false;

        console.assert(graphDataSource.zeroTime);
        console.assert(graphDataSource.startTime);
        console.assert(graphDataSource.currentTime);
        console.assert(graphDataSource.endTime);
        console.assert(graphDataSource.secondsPerPixel);

        if (!this._records || !this._records.length)
            return false;

        var firstRecord = this._records[0];
        var barStartTime = firstRecord.startTime;

        // If this bar has no time info, return early.
        if (isNaN(barStartTime))
            return false;

        var graphStartTime = graphDataSource.startTime;
        var graphEndTime = graphDataSource.endTime;
        var graphCurrentTime = graphDataSource.currentTime;

        var barEndTime = this._records.reduce(function(previousValue, currentValue) { return Math.max(previousValue, currentValue.endTime); }, 0);

        // If this bar is completely after the current time, return early.
        if (barStartTime > graphCurrentTime)
            return false;

        // If this bar is completely before or after the bounds of the graph, return early.
        if (barEndTime < graphStartTime || barStartTime > graphEndTime)
            return false;

        var barUnfinished = isNaN(barEndTime) || barEndTime >= graphCurrentTime;
        if (barUnfinished)
            barEndTime = graphCurrentTime;

        var barDuration = barEndTime - barStartTime;

        var graphDuration = graphEndTime - graphStartTime;

        let newBarPosition = (barStartTime - graphStartTime) / graphDuration;
        let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
        this._updateElementPosition(this._element, newBarPosition, property);

        var newBarWidth = ((barEndTime - graphStartTime) / graphDuration) - newBarPosition;
        this._updateElementPosition(this._element, newBarWidth, "width");

        if (this._delegate && this._delegate.timelineRecordBarCustomChildren) {
            this._element.removeChildren();

            this._element.classList.add("has-custom-children");
            this._element.classList.toggle("unfinished", barUnfinished);

            let children = this._delegate.timelineRecordBarCustomChildren(this);
            for (let child of children) {
                let childElement;
                if (child.image) {
                    childElement = this._element.appendChild(document.createElement("img"));
                    childElement.src = child.image;
                } else
                    childElement = this._element.appendChild(document.createElement("div"));

                childElement.classList.add(...child.classNames);
                childElement.title = child.title;
                this._updateElementPosition(childElement, (child.startTime - barStartTime) / barDuration, property);

                if (typeof child.endTime === "number") {
                    let childEndTime = !isNaN(child.endTime) ? child.endTime : barEndTime;
                    this._updateElementPosition(childElement, (childEndTime - child.startTime) / barDuration, "width");
                }
            }

            return true;
        }

        this._element.classList.remove("has-custom-children");

        if (!this._activeBarElement && this._renderMode !== WI.TimelineRecordBar.RenderMode.InactiveOnly) {
            this._activeBarElement = document.createElement("div");
            this._activeBarElement.classList.add("segment");
        }

        if (!firstRecord.usesActiveStartTime) {
            this._element.classList.toggle("unfinished", barUnfinished);

            if (this._inactiveBarElement)
                this._inactiveBarElement.remove();

            if (this._renderMode === WI.TimelineRecordBar.RenderMode.InactiveOnly) {
                if (this._activeBarElement)
                    this._activeBarElement.remove();

                return false;
            }

            // If this TimelineRecordBar is reused and had an inactive bar previously, clean it up.
            this._activeBarElement.style.removeProperty(WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left");
            this._activeBarElement.style.removeProperty("width");

            if (!this._activeBarElement.parentNode)
                this._element.appendChild(this._activeBarElement);

            return true;
        }

        // Find the earliest active start time for active only rendering, and the latest for the other modes.
        // This matches the values that TimelineRecordBar.createCombinedBars uses when combining.
        if (this._renderMode === WI.TimelineRecordBar.RenderMode.ActiveOnly)
            var barActiveStartTime = this._records.reduce(function(previousValue, currentValue) { return Math.min(previousValue, currentValue.activeStartTime); }, Infinity);
        else
            var barActiveStartTime = this._records.reduce(function(previousValue, currentValue) { return Math.max(previousValue, currentValue.activeStartTime); }, 0);

        var inactiveUnfinished = isNaN(barActiveStartTime) || barActiveStartTime >= graphCurrentTime;
        this._element.classList.toggle("unfinished", inactiveUnfinished);

        if (inactiveUnfinished)
            barActiveStartTime = graphCurrentTime;
        else if (this._renderMode === WI.TimelineRecordBar.RenderMode.Normal) {
            // Hide the inactive segment when its duration is less than the minimum displayable size.
            let minimumSegmentDuration = graphDataSource.secondsPerPixel * WI.TimelineRecordBar.MinimumWidthPixels;
            if (barActiveStartTime - barStartTime < minimumSegmentDuration) {
                barActiveStartTime = barStartTime;
                if (this._inactiveBarElement)
                    this._inactiveBarElement.remove();
            }
        }

        let showInactiveSegment = barActiveStartTime > barStartTime;
        this._element.classList.toggle("has-inactive-segment", showInactiveSegment);

        let middlePercentage = (barActiveStartTime - barStartTime) / barDuration;
        if (showInactiveSegment && this._renderMode !== WI.TimelineRecordBar.RenderMode.ActiveOnly) {
            if (!this._inactiveBarElement) {
                this._inactiveBarElement = document.createElement("div");
                this._inactiveBarElement.classList.add("segment");
                this._inactiveBarElement.classList.add("inactive");
            }

            let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "left" : "right";
            this._updateElementPosition(this._inactiveBarElement, 1 - middlePercentage, property);
            this._updateElementPosition(this._inactiveBarElement, middlePercentage, "width");

            if (!this._inactiveBarElement.parentNode)
                this._element.insertBefore(this._inactiveBarElement, this._element.firstChild);
        }

        if (!inactiveUnfinished && this._renderMode !== WI.TimelineRecordBar.RenderMode.InactiveOnly) {
            let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
            this._updateElementPosition(this._activeBarElement, middlePercentage, property);
            this._updateElementPosition(this._activeBarElement, 1 - middlePercentage, "width");

            if (!this._activeBarElement.parentNode)
                this._element.appendChild(this._activeBarElement);
        } else if (this._activeBarElement)
            this._activeBarElement.remove();

        return true;
    }

    // Private

    _updateElementPosition(element, newPosition, property)
    {
        newPosition *= 100;

        let newPositionAprox = Math.round(newPosition * 100);
        let currentPositionAprox = Math.round(parseFloat(element.style[property]) * 100);
        if (currentPositionAprox !== newPositionAprox)
            element.style[property] = (newPositionAprox / 100) + "%";
    }

    _handleClick(event)
    {
        // Ensure that the container "click" listener added by `WI.TimelineOverview` isn't called.
        event.__timelineRecordClickEventHandled = true;

        if (this._delegate && this._delegate.timelineRecordBarClicked)
            this._delegate.timelineRecordBarClicked(this);
    }
};

WI.TimelineRecordBar.ElementReferenceSymbol = Symbol("timeline-record-bar");

WI.TimelineRecordBar.MinimumWidthPixels = 4;
WI.TimelineRecordBar.MinimumMarginPixels = 1;

WI.TimelineRecordBar.RenderMode = {
    Normal: "timeline-record-bar-normal-render-mode",
    InactiveOnly: "timeline-record-bar-inactive-only-render-mode",
    ActiveOnly: "timeline-record-bar-active-only-render-mode"
};
