/*
 * Copyright (C) 2013 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.TimelineRuler = class TimelineRuler extends WI.View
{
    constructor()
    {
        super();

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

        this._headerElement = document.createElement("div");
        this._headerElement.classList.add("header");
        this.element.appendChild(this._headerElement);

        this._markersElement = document.createElement("div");
        this._markersElement.classList.add("markers");
        this.element.appendChild(this._markersElement);

        this._zeroTime = 0;
        this._startTime = 0;
        this._endTime = 0;
        this._duration = NaN;
        this._secondsPerPixel = 0;
        this._selectionStartTime = 0;
        this._selectionEndTime = Number.MAX_VALUE;
        this._endTimePinned = false;
        this._snapInterval = 0;
        this._allowsClippedLabels = false;
        this._allowsTimeRangeSelection = false;
        this._minimumSelectionDuration = 0.01;
        this._formatLabelCallback = null;
        this._timeRangeSelectionChanged = false;
        this._enabled = true;

        this._scannerMarker = null;
        this._markerElementMap = new Map;
        this._cachedClientWidth = 0;
    }

    // Public

    get enabled()
    {
        return this._enabled;
    }

    set enabled(x)
    {
        if (this._enabled === x)
            return;

        this._enabled = x;
        this.element.classList.toggle(WI.TreeElementStatusButton.DisabledStyleClassName, !this._enabled);
    }

    get allowsClippedLabels()
    {
        return this._allowsClippedLabels;
    }

    set allowsClippedLabels(x)
    {
        x = !!x;

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

        this._allowsClippedLabels = x;

        this.needsLayout();
    }

    set formatLabelCallback(x)
    {
        console.assert(typeof x === "function" || !x, x);

        x = x || null;

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

        this._formatLabelCallback = x;

        this.needsLayout();
    }

    get allowsTimeRangeSelection()
    {
        return this._allowsTimeRangeSelection;
    }

    set allowsTimeRangeSelection(x)
    {
        x = !!x;

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

        this._allowsTimeRangeSelection = x;

        if (x) {
            this._clickEventListener = this._handleClick.bind(this);
            this._doubleClickEventListener = this._handleDoubleClick.bind(this);
            this._mouseDownEventListener = this._handleMouseDown.bind(this);
            this.element.addEventListener("click", this._clickEventListener);
            this.element.addEventListener("dblclick", this._doubleClickEventListener);
            this.element.addEventListener("mousedown", this._mouseDownEventListener);

            this._leftShadedAreaElement = document.createElement("div");
            this._leftShadedAreaElement.classList.add("shaded-area");
            this._leftShadedAreaElement.classList.add("left");

            this._rightShadedAreaElement = document.createElement("div");
            this._rightShadedAreaElement.classList.add("shaded-area");
            this._rightShadedAreaElement.classList.add("right");

            this._leftSelectionHandleElement = document.createElement("div");
            this._leftSelectionHandleElement.classList.add("selection-handle");
            this._leftSelectionHandleElement.classList.add("left");
            this._leftSelectionHandleElement.addEventListener("mousedown", this._handleSelectionHandleMouseDown.bind(this));

            this._rightSelectionHandleElement = document.createElement("div");
            this._rightSelectionHandleElement.classList.add("selection-handle");
            this._rightSelectionHandleElement.classList.add("right");
            this._rightSelectionHandleElement.addEventListener("mousedown", this._handleSelectionHandleMouseDown.bind(this));

            this._selectionDragElement = document.createElement("div");
            this._selectionDragElement.classList.add("selection-drag");

            this._needsSelectionLayout();
        } else {
            this.element.removeEventListener("click", this._clickEventListener);
            this.element.removeEventListener("dblclick", this._doubleClickEventListener);
            this.element.removeEventListener("mousedown", this._mouseDownEventListener);
            this._clickEventListener = null;
            this._doubleClickEventListener = null;
            this._mouseDownEventListener = null;

            this._leftShadedAreaElement.remove();
            this._rightShadedAreaElement.remove();
            this._leftSelectionHandleElement.remove();
            this._rightSelectionHandleElement.remove();
            this._selectionDragElement.remove();

            delete this._leftShadedAreaElement;
            delete this._rightShadedAreaElement;
            delete this._leftSelectionHandleElement;
            delete this._rightSelectionHandleElement;
            delete this._selectionDragElement;
        }
    }

    get minimumSelectionDuration()
    {
        return this._minimumSelectionDuration;
    }

    set minimumSelectionDuration(x)
    {
        this._minimumSelectionDuration = x;
    }

    get zeroTime()
    {
        return this._zeroTime;
    }

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

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

        if (this.entireRangeSelected)
            this.selectionStartTime = x;

        this._zeroTime = x;

        this.needsLayout();
    }

    get startTime()
    {
        return this._startTime;
    }

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

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

        this._startTime = x;

        if (!isNaN(this._duration))
            this._endTime = this._startTime + this._duration;

        this._currentDividers = null;

        this.needsLayout();
    }

    get duration()
    {
        if (!isNaN(this._duration))
            return this._duration;
        return this.endTime - this.startTime;
    }

    get endTime()
    {
        if (!this._endTimePinned && this.layoutPending)
            this._recalculate();
        return this._endTime;
    }

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

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

        this._endTime = x;
        this._endTimePinned = true;

        this.needsLayout();
    }

    get secondsPerPixel()
    {
        if (this.layoutPending)
            this._recalculate();
        return this._secondsPerPixel;
    }

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

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

        this._secondsPerPixel = x;
        this._endTimePinned = false;
        this._currentDividers = null;
        this._currentSliceTime = 0;

        this.needsLayout();
    }

    get snapInterval()
    {
        return this._snapInterval;
    }

    set snapInterval(x)
    {
        if (this._snapInterval === x)
            return;

        this._snapInterval = x;
    }

    get selectionStartTime()
    {
        return this._selectionStartTime;
    }

    set selectionStartTime(x)
    {
        x = this._snapValue(x) || 0;

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

        this._selectionStartTime = x;
        this._timeRangeSelectionChanged = true;

        this._needsSelectionLayout();
    }

    get selectionEndTime()
    {
        return this._selectionEndTime;
    }

    set selectionEndTime(x)
    {
        x = this._snapValue(x) || 0;

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

        this._selectionEndTime = x;
        this._timeRangeSelectionChanged = true;

        this._needsSelectionLayout();
    }

    get entireRangeSelected()
    {
        return this._selectionStartTime === this._zeroTime && this._selectionEndTime === Number.MAX_VALUE;
    }

    selectEntireRange()
    {
        this.selectionStartTime = this._zeroTime;
        this.selectionEndTime = Number.MAX_VALUE;
    }

    addMarker(marker)
    {
        console.assert(marker instanceof WI.TimelineMarker);

        if (this._markerElementMap.has(marker))
            return;

        marker.addEventListener(WI.TimelineMarker.Event.TimeChanged, this._timelineMarkerTimeChanged, this);

        let markerTime = marker.time - this._startTime;
        let markerElement = document.createElement("div");
        markerElement.classList.add(marker.type, "marker");

        switch (marker.type) {
        case WI.TimelineMarker.Type.LoadEvent:
            markerElement.title = WI.UIString("Load \u2014 %s").format(Number.secondsToString(markerTime));
            break;
        case WI.TimelineMarker.Type.DOMContentEvent:
            markerElement.title = WI.UIString("DOM Content Loaded \u2014 %s").format(Number.secondsToString(markerTime));
            break;
        case WI.TimelineMarker.Type.TimeStamp:
            if (marker.details)
                markerElement.title = WI.UIString("%s \u2014 %s").format(marker.details, Number.secondsToString(markerTime));
            else
                markerElement.title = WI.UIString("Timestamp \u2014 %s").format(Number.secondsToString(markerTime));
            break;
        }

        this._markerElementMap.set(marker, markerElement);

        this._needsMarkerLayout();
    }

    clearMarkers()
    {
        for (let [marker, markerElement] of this._markerElementMap) {
            marker.removeEventListener(null, null, this);
            markerElement.remove();
        }

        this._markerElementMap.clear();

        this._scannerMarker = null;
    }

    elementForMarker(marker)
    {
        return this._markerElementMap.get(marker) || null;
    }

    showScanner(time)
    {
        if (!this._scannerMarker) {
            this._scannerMarker = new WI.TimelineMarker(time, WI.TimelineMarker.Type.Scanner);
            this.addMarker(this._scannerMarker);
        }

        this._scannerMarker.time = time;
    }

    hideScanner()
    {
        if (this._scannerMarker)
            this._scannerMarker.time = -1;
    }

    updateLayoutIfNeeded(layoutReason)
    {
        // If a layout is pending we can let the base class handle it and return, since that will update
        // markers and the selection at the same time.
        if (this.layoutPending) {
            super.updateLayoutIfNeeded(layoutReason);
            return;
        }

        let visibleWidth = this._recalculate();
        if (visibleWidth <= 0)
            return;

        if (this._scheduledMarkerLayoutUpdateIdentifier)
            this._updateMarkers(visibleWidth, this.duration);

        if (this._scheduledSelectionLayoutUpdateIdentifier)
            this._updateSelection(visibleWidth, this.duration);
    }

    needsLayout(layoutReason)
    {
        if (this.layoutPending)
            return;

        if (this._scheduledMarkerLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledMarkerLayoutUpdateIdentifier);
            this._scheduledMarkerLayoutUpdateIdentifier = undefined;
        }

        if (this._scheduledSelectionLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledSelectionLayoutUpdateIdentifier);
            this._scheduledSelectionLayoutUpdateIdentifier = undefined;
        }

        super.needsLayout(layoutReason);
    }

    // Protected

    layout()
    {
        let visibleWidth = this._recalculate();
        if (visibleWidth <= 0)
            return;

        let duration = this.duration;
        let pixelsPerSecond = visibleWidth / duration;

        // Calculate a divider count based on the maximum allowed divider density.
        let dividerCount = Math.round(visibleWidth / WI.TimelineRuler.MinimumDividerSpacing);
        let sliceTime;
        if (this._endTimePinned || !this._currentSliceTime) {
            // Calculate the slice time based on the rough divider count and the time span.
            sliceTime = duration / dividerCount;

            // Snap the slice time to a nearest number (e.g. 0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, etc.)
            sliceTime = Math.pow(10, Math.ceil(Math.log(sliceTime) / Math.LN10));
            if (sliceTime * pixelsPerSecond >= 5 * WI.TimelineRuler.MinimumDividerSpacing)
                sliceTime = sliceTime / 5;
            if (sliceTime * pixelsPerSecond >= 2 * WI.TimelineRuler.MinimumDividerSpacing)
                sliceTime = sliceTime / 2;

            this._currentSliceTime = sliceTime;
        } else {
            // Reuse the last slice time since the time duration does not scale to fit when the end time isn't pinned.
            sliceTime = this._currentSliceTime;
        }

        // Calculate the divider count now based on the final slice time.
        dividerCount = Math.floor(visibleWidth * this.secondsPerPixel / sliceTime);

        let firstDividerTime = (Math.ceil((this._startTime - this._zeroTime) / sliceTime) * sliceTime) + this._zeroTime;
        let lastDividerTime = firstDividerTime + sliceTime * dividerCount;

        // Make an extra divider in case the last one is partially visible.
        if (!this._endTimePinned)
            ++dividerCount;

        let dividerData = {
            count: dividerCount,
            firstTime: firstDividerTime,
            lastTime: lastDividerTime,
        };

        if (Object.shallowEqual(dividerData, this._currentDividers)) {
            this._updateMarkers(visibleWidth, duration);
            this._updateSelection(visibleWidth, duration);
            return;
        }

        this._currentDividers = dividerData;

        let markerDividers = this._markersElement.querySelectorAll("." + WI.TimelineRuler.DividerElementStyleClassName);
        let dividerElement = this._headerElement.firstChild;

        for (var i = 0; i <= dividerCount; ++i) {
            if (!dividerElement) {
                dividerElement = document.createElement("div");
                dividerElement.className = WI.TimelineRuler.DividerElementStyleClassName;
                this._headerElement.appendChild(dividerElement);

                let labelElement = document.createElement("div");
                labelElement.className = WI.TimelineRuler.DividerLabelElementStyleClassName;
                dividerElement.appendChild(labelElement);
            }

            let markerDividerElement = markerDividers[i];
            if (!markerDividerElement) {
                markerDividerElement = document.createElement("div");
                markerDividerElement.className = WI.TimelineRuler.DividerElementStyleClassName;
                this._markersElement.appendChild(markerDividerElement);
            }

            let dividerTime = firstDividerTime + (sliceTime * i);
            let newPosition = (dividerTime - this._startTime) / duration;

            if (!this._allowsClippedLabels) {
                // Don't allow dividers under 0% where they will be completely hidden.
                if (newPosition < 0)
                    continue;

                // When over 100% it is time to stop making/updating dividers.
                if (newPosition > 1)
                    break;

                // Don't allow the left-most divider spacing to be so tight it clips.
                if ((newPosition * visibleWidth) < WI.TimelineRuler.MinimumLeftDividerSpacing)
                    continue;
            }

            let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
            this._updatePositionOfElement(dividerElement, newPosition, visibleWidth, property);
            this._updatePositionOfElement(markerDividerElement, newPosition, visibleWidth, property);

            console.assert(dividerElement.firstChild.classList.contains(WI.TimelineRuler.DividerLabelElementStyleClassName));

            dividerElement.firstChild.textContent = isNaN(dividerTime) ? "" : this._formatDividerLabelText(dividerTime - this._zeroTime);
            dividerElement = dividerElement.nextSibling;
        }

        // Remove extra dividers.
        while (dividerElement) {
            let nextDividerElement = dividerElement.nextSibling;
            dividerElement.remove();
            dividerElement = nextDividerElement;
        }

        for (; i < markerDividers.length; ++i)
            markerDividers[i].remove();

        this._updateMarkers(visibleWidth, duration);
        this._updateSelection(visibleWidth, duration);
    }

    sizeDidChange()
    {
        this._cachedClientWidth = this.element.clientWidth;
    }

    // Private

    _needsMarkerLayout()
    {
        // If layout is scheduled, abort since markers will be updated when layout happens.
        if (this.layoutPending)
            return;

        if (this._scheduledMarkerLayoutUpdateIdentifier)
            return;

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

            let visibleWidth = this._cachedClientWidth;
            if (visibleWidth <= 0)
                return;

            this._updateMarkers(visibleWidth, this.duration);
        });
    }

    _needsSelectionLayout()
    {
        if (!this._allowsTimeRangeSelection)
            return;

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

        if (this._scheduledSelectionLayoutUpdateIdentifier)
            return;

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

            let visibleWidth = this._cachedClientWidth;
            if (visibleWidth <= 0)
                return;

            this._updateSelection(visibleWidth, this.duration);
        });
    }

    _recalculate()
    {
        let visibleWidth = this._cachedClientWidth;
        if (visibleWidth <= 0)
            return 0;

        let duration;
        if (this._endTimePinned)
            duration = this._endTime - this._startTime;
        else
            duration = visibleWidth * this._secondsPerPixel;

        this._secondsPerPixel = duration / visibleWidth;

        if (!this._endTimePinned)
            this._endTime = this._startTime + (visibleWidth * this._secondsPerPixel);

        return visibleWidth;
    }

    _updatePositionOfElement(element, newPosition, visibleWidth, property)
    {
        newPosition *= this._endTimePinned ? 100 : visibleWidth;

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

    _updateMarkers(visibleWidth, duration)
    {
        if (this._scheduledMarkerLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledMarkerLayoutUpdateIdentifier);
            this._scheduledMarkerLayoutUpdateIdentifier = undefined;
        }

        for (let [marker, markerElement] of this._markerElementMap) {
            if (marker.time < 0) {
                markerElement.remove();
                continue;
            }

            let newPosition = (marker.time - this._startTime) / duration;
            let property = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
            this._updatePositionOfElement(markerElement, newPosition, visibleWidth, property);

            if (!markerElement.parentNode)
                this._markersElement.appendChild(markerElement);
        }
    }

    _updateSelection(visibleWidth, duration)
    {
        if (this._scheduledSelectionLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledSelectionLayoutUpdateIdentifier);
            this._scheduledSelectionLayoutUpdateIdentifier = undefined;
        }

        this.element.classList.toggle("allows-time-range-selection", this._allowsTimeRangeSelection);

        if (!this._allowsTimeRangeSelection)
            return;

        this.element.classList.toggle("selection-hidden", this.entireRangeSelected);

        if (this.entireRangeSelected) {
            this._dispatchTimeRangeSelectionChangedEvent();
            return;
        }

        let startTimeClamped = this._selectionStartTime < this._startTime || this._selectionStartTime > this._endTime;
        let endTimeClamped = this._selectionEndTime < this._startTime || this._selectionEndTime > this._endTime;

        this.element.classList.toggle("both-handles-clamped", startTimeClamped && endTimeClamped);

        let formattedStartTimeText = this._formatDividerLabelText(this._selectionStartTime - this._zeroTime);
        let formattedEndTimeText = this._formatDividerLabelText(this._selectionEndTime - this._zeroTime);

        let startProperty = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "right" : "left";
        let newStartPosition = Number.constrain((this._selectionStartTime - this._startTime) / duration, 0, 1);
        this._updatePositionOfElement(this._leftShadedAreaElement, newStartPosition, visibleWidth, "width");
        this._updatePositionOfElement(this._leftSelectionHandleElement, newStartPosition, visibleWidth, startProperty);
        this._updatePositionOfElement(this._selectionDragElement, newStartPosition, visibleWidth, startProperty);

        this._leftSelectionHandleElement.classList.toggle("clamped", startTimeClamped);
        this._leftSelectionHandleElement.classList.toggle("hidden", startTimeClamped && endTimeClamped && this._selectionStartTime < this._startTime);
        this._leftSelectionHandleElement.title = formattedStartTimeText;

        let endProperty = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL ? "left" : "right";
        let newEndPosition = 1 - Number.constrain((this._selectionEndTime - this._startTime) / duration, 0, 1);
        this._updatePositionOfElement(this._rightShadedAreaElement, newEndPosition, visibleWidth, "width");
        this._updatePositionOfElement(this._rightSelectionHandleElement, newEndPosition, visibleWidth, endProperty);
        this._updatePositionOfElement(this._selectionDragElement, newEndPosition, visibleWidth, endProperty);

        this._rightSelectionHandleElement.classList.toggle("clamped", endTimeClamped);
        this._rightSelectionHandleElement.classList.toggle("hidden", startTimeClamped && endTimeClamped && this._selectionEndTime > this._endTime);
        this._rightSelectionHandleElement.title = formattedEndTimeText;

        if (!this._selectionDragElement.parentNode) {
            this.element.appendChild(this._selectionDragElement);
            this.element.appendChild(this._leftShadedAreaElement);
            this.element.appendChild(this._leftSelectionHandleElement);
            this.element.appendChild(this._rightShadedAreaElement);
            this.element.appendChild(this._rightSelectionHandleElement);
        }

        this._dispatchTimeRangeSelectionChangedEvent();
    }

    _formatDividerLabelText(value)
    {
        if (this._formatLabelCallback)
            return this._formatLabelCallback(value);

        return Number.secondsToString(value, true);
    }

    _snapValue(value)
    {
        if (!value || !this.snapInterval)
            return value;

        return Math.round(value / this.snapInterval) * this.snapInterval;
    }

    _dispatchTimeRangeSelectionChangedEvent()
    {
        if (!this._timeRangeSelectionChanged)
            return;

        this._timeRangeSelectionChanged = false;

        this.dispatchEventToListeners(WI.TimelineRuler.Event.TimeRangeSelectionChanged);
    }

    _timelineMarkerTimeChanged()
    {
        this._needsMarkerLayout();
    }

    _shouldIgnoreMicroMovement(event)
    {
        if (this._mousePassedMicroMovementTest)
            return false;

        let pixels = Math.abs(event.pageX - this._mouseStartX);
        if (pixels <= 4)
            return true;

        this._mousePassedMicroMovementTest = true;
        return false;
    }

    _handleClick(event)
    {
        if (!this._enabled)
            return;

        if (this._mouseMoved)
            return;

        for (let newTarget of document.elementsFromPoint(event.pageX, event.pageY)) {
            if (!newTarget || typeof newTarget.click !== "function")
                continue;
            if (this.element.contains(newTarget))
                continue;

            // Clone the event to dispatch it on the new element.
            let newEvent = new event.constructor(event.type, event);
            newTarget.dispatchEvent(newEvent);
            if (newEvent.__timelineRecordClickEventHandled)
                event.stop();
            return;
        }
    }

    _handleDoubleClick(event)
    {
        if (this.entireRangeSelected)
            return;

        this.selectEntireRange();
    }

    _handleMouseDown(event)
    {
        // Only handle left mouse clicks.
        if (event.button !== 0 || event.ctrlKey)
            return;

        this._selectionIsMove = event.target === this._selectionDragElement;
        this._rulerBoundingClientRect = this.element.getBoundingClientRect();

        if (this._selectionIsMove) {
            this._lastMousePosition = event.pageX;
            var selectionDragElementRect = this._selectionDragElement.getBoundingClientRect();
            this._moveSelectionMaximumLeftOffset = this._rulerBoundingClientRect.left + (event.pageX - selectionDragElementRect.left);
            this._moveSelectionMaximumRightOffset = this._rulerBoundingClientRect.right - (selectionDragElementRect.right - event.pageX);
        } else {
            if (WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL)
                this._mouseDownPosition = this._rulerBoundingClientRect.right - event.pageX;
            else
                this._mouseDownPosition = event.pageX - this._rulerBoundingClientRect.left;
        }

        this._mouseMoved = false;

        this._mousePassedMicroMovementTest = false;
        this._mouseStartX = event.pageX;

        this._mouseMoveEventListener = this._handleMouseMove.bind(this);
        this._mouseUpEventListener = this._handleMouseUp.bind(this);

        // Register these listeners on the document so we can track the mouse if it leaves the ruler.
        document.addEventListener("mousemove", this._mouseMoveEventListener);
        document.addEventListener("mouseup", this._mouseUpEventListener);

        event.preventDefault();
        event.stopPropagation();
    }

    _handleMouseMove(event)
    {
        console.assert(event.button === 0);

        if (this._shouldIgnoreMicroMovement(event))
            return;

        this._mouseMoved = true;

        let isRTL = WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL;

        let currentMousePosition;
        if (this._selectionIsMove) {
            currentMousePosition = Math.max(this._moveSelectionMaximumLeftOffset, Math.min(this._moveSelectionMaximumRightOffset, event.pageX));

            let positionDelta = 0;
            if (isRTL)
                positionDelta = this._lastMousePosition - currentMousePosition;
            else
                positionDelta = currentMousePosition - this._lastMousePosition;

            let offsetTime = positionDelta * this.secondsPerPixel;
            let selectionDuration = this.selectionEndTime - this.selectionStartTime;
            let oldSelectionStartTime = this.selectionStartTime;

            this.selectionStartTime = Math.max(this.startTime, Math.min(this.selectionStartTime + offsetTime, this.endTime - selectionDuration));
            this.selectionEndTime = this.selectionStartTime + selectionDuration;

            if (this.snapInterval) {
                // When snapping we need to check the mouse position delta relative to the last snap, rather than the
                // last mouse move. If a snap occurs we adjust for the amount the cursor drifted, so that the mouse
                // position relative to the selection remains constant.
                let snapOffset = this.selectionStartTime - oldSelectionStartTime;
                if (!snapOffset)
                    return;

                let positionDrift = (offsetTime - snapOffset * this.snapInterval) / this.secondsPerPixel;
                currentMousePosition -= positionDrift;
            }

            this._lastMousePosition = currentMousePosition;
        } else {
            if (isRTL)
                currentMousePosition = this._rulerBoundingClientRect.right - event.pageX;
            else
                currentMousePosition = event.pageX - this._rulerBoundingClientRect.left;

            this.selectionStartTime = Math.max(this.startTime, this.startTime + (Math.min(currentMousePosition, this._mouseDownPosition) * this.secondsPerPixel));
            this.selectionEndTime = Math.min(this.startTime + (Math.max(currentMousePosition, this._mouseDownPosition) * this.secondsPerPixel), this.endTime);

            // Turn on col-resize cursor style once dragging begins, rather than on the initial mouse down.
            this.element.classList.add(WI.TimelineRuler.ResizingSelectionStyleClassName);
        }

        this._updateSelection(this._cachedClientWidth, this.duration);

        event.preventDefault();
        event.stopPropagation();
    }

    _handleMouseUp(event)
    {
        console.assert(event.button === 0);

        if (!this._selectionIsMove) {
            this.element.classList.remove(WI.TimelineRuler.ResizingSelectionStyleClassName);

            if (this.selectionEndTime - this.selectionStartTime < this.minimumSelectionDuration) {
                // The section is smaller than allowed, grow in the direction of the drag to meet the minumum.
                let currentMousePosition = 0;
                if (WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL)
                    currentMousePosition = this._rulerBoundingClientRect.right - event.pageX;
                else
                    currentMousePosition = event.pageX - this._rulerBoundingClientRect.left;

                if (currentMousePosition > this._mouseDownPosition) {
                    this.selectionEndTime = Math.min(this.selectionStartTime + this.minimumSelectionDuration, this.endTime);
                    this.selectionStartTime = this.selectionEndTime - this.minimumSelectionDuration;
                } else {
                    this.selectionStartTime = Math.max(this.startTime, this.selectionEndTime - this.minimumSelectionDuration);
                    this.selectionEndTime = this.selectionStartTime + this.minimumSelectionDuration;
                }
            }
        }

        this._dispatchTimeRangeSelectionChangedEvent();

        document.removeEventListener("mousemove", this._mouseMoveEventListener);
        document.removeEventListener("mouseup", this._mouseUpEventListener);

        delete this._mouseMoveEventListener;
        delete this._mouseUpEventListener;
        delete this._mouseDownPosition;
        delete this._lastMousePosition;
        delete this._selectionIsMove;
        delete this._rulerBoundingClientRect;
        delete this._moveSelectionMaximumLeftOffset;
        delete this._moveSelectionMaximumRightOffset;

        event.preventDefault();
        event.stopPropagation();
    }

    _handleSelectionHandleMouseDown(event)
    {
        // Only handle left mouse clicks.
        if (event.button !== 0 || event.ctrlKey)
            return;

        this._dragHandleIsStartTime = event.target === this._leftSelectionHandleElement;

        if (WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL)
            this._mouseDownPosition = this.element.totalOffsetRight - event.pageX;
        else
            this._mouseDownPosition = event.pageX - this.element.totalOffsetLeft;

        this._selectionHandleMouseMoveEventListener = this._handleSelectionHandleMouseMove.bind(this);
        this._selectionHandleMouseUpEventListener = this._handleSelectionHandleMouseUp.bind(this);

        // Register these listeners on the document so we can track the mouse if it leaves the ruler.
        document.addEventListener("mousemove", this._selectionHandleMouseMoveEventListener);
        document.addEventListener("mouseup", this._selectionHandleMouseUpEventListener);

        this.element.classList.add(WI.TimelineRuler.ResizingSelectionStyleClassName);

        event.preventDefault();
        event.stopPropagation();
    }

    _handleSelectionHandleMouseMove(event)
    {
        console.assert(event.button === 0);

        let currentMousePosition = 0;
        if (WI.resolvedLayoutDirection() === WI.LayoutDirection.RTL)
            currentMousePosition = this.element.totalOffsetRight - event.pageX;
        else
            currentMousePosition = event.pageX - this.element.totalOffsetLeft;

        let currentTime = this.startTime + (currentMousePosition * this.secondsPerPixel);
        if (this.snapInterval)
            currentTime = this._snapValue(currentTime);

        if (event.altKey && !event.ctrlKey && !event.metaKey && !event.shiftKey) {
            // Resize the selection on both sides when the Option keys is held down.
            if (this._dragHandleIsStartTime) {
                let timeDifference = currentTime - this.selectionStartTime;
                this.selectionStartTime = Math.max(this.startTime, Math.min(currentTime, this.selectionEndTime - this.minimumSelectionDuration));
                this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + this.minimumSelectionDuration, this.selectionEndTime - timeDifference), this.endTime);
            } else {
                let timeDifference = currentTime - this.selectionEndTime;
                this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + this.minimumSelectionDuration, currentTime), this.endTime);
                this.selectionStartTime = Math.max(this.startTime, Math.min(this.selectionStartTime - timeDifference, this.selectionEndTime - this.minimumSelectionDuration));
            }
        } else {
            // Resize the selection on side being dragged.
            if (this._dragHandleIsStartTime)
                this.selectionStartTime = Math.max(this.startTime, Math.min(currentTime, this.selectionEndTime - this.minimumSelectionDuration));
            else
                this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + this.minimumSelectionDuration, currentTime), this.endTime);
        }

        this._updateSelection(this._cachedClientWidth, this.duration);

        event.preventDefault();
        event.stopPropagation();
    }

    _handleSelectionHandleMouseUp(event)
    {
        console.assert(event.button === 0);

        this.element.classList.remove(WI.TimelineRuler.ResizingSelectionStyleClassName);

        document.removeEventListener("mousemove", this._selectionHandleMouseMoveEventListener);
        document.removeEventListener("mouseup", this._selectionHandleMouseUpEventListener);

        delete this._selectionHandleMouseMoveEventListener;
        delete this._selectionHandleMouseUpEventListener;
        delete this._dragHandleIsStartTime;
        delete this._mouseDownPosition;

        event.preventDefault();
        event.stopPropagation();
    }
};

WI.TimelineRuler.MinimumLeftDividerSpacing = 48;
WI.TimelineRuler.MinimumDividerSpacing = 64;

WI.TimelineRuler.ResizingSelectionStyleClassName = "resizing-selection";
WI.TimelineRuler.DividerElementStyleClassName = "divider";
WI.TimelineRuler.DividerLabelElementStyleClassName = "label";

WI.TimelineRuler.Event = {
    TimeRangeSelectionChanged: "time-ruler-time-range-selection-changed"
};
