/*
 * 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.StoppingTime:
            markerElement.title = WI.UIString("Recording stop requested \u2014 %s").format(Number.secondsToString(markerTime));
            break;
        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"
};
