/*
 * 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.
 */

WebInspector.TimelineRuler = function()
{
    WebInspector.Object.call(this);

    this._element = document.createElement("div");
    this._element.className = WebInspector.TimelineRuler.StyleClassName;

    this._headerElement = document.createElement("div");
    this._headerElement.className = WebInspector.TimelineRuler.HeaderElementStyleClassName;
    this._element.appendChild(this._headerElement);

    this._markersElement = document.createElement("div");
    this._markersElement.className = WebInspector.TimelineRuler.MarkersElementStyleClassName;
    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 = Infinity;
    this._endTimePinned = false;
    this._allowsClippedLabels = false;
    this._allowsTimeRangeSelection = false;

    this._markerElementMap = new Map;
}

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

WebInspector.TimelineRuler.StyleClassName = "timeline-ruler";
WebInspector.TimelineRuler.AllowsTimeRangeSelectionStyleClassName = "allows-time-range-selection";
WebInspector.TimelineRuler.HeaderElementStyleClassName = "header";
WebInspector.TimelineRuler.DividerElementStyleClassName = "divider";
WebInspector.TimelineRuler.DividerLabelElementStyleClassName = "label";

WebInspector.TimelineRuler.MarkersElementStyleClassName = "markers";
WebInspector.TimelineRuler.BaseMarkerElementStyleClassName = "marker";
WebInspector.TimelineRuler.ShadedAreaElementStyleClassName = "shaded-area";
WebInspector.TimelineRuler.SelectionDragElementStyleClassName = "selection-drag";
WebInspector.TimelineRuler.SelectionHandleElementStyleClassName = "selection-handle";
WebInspector.TimelineRuler.LeftSelectionElementStyleClassName = "left";
WebInspector.TimelineRuler.RightSelectionElementStyleClassName = "right";
WebInspector.TimelineRuler.MinimumSelectionTimeRange = 0.01;

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

WebInspector.TimelineRuler.prototype = {
    constructor: WebInspector.TimelineRuler,

    // Public

    get element()
    {
        return this._element;
    },

    get allowsClippedLabels()
    {
        return this._allowsClippedLabels
    },

    set allowsClippedLabels(x)
    {
        if (this._allowsClippedLabels === x)
            return;

        this._allowsClippedLabels = x || false;

        this._needsLayout();
    },

    get allowsTimeRangeSelection()
    {
        return this._allowsTimeRangeSelection;
    },

    set allowsTimeRangeSelection(x)
    {
        if (this._allowsTimeRangeSelection === x)
            return;

        this._allowsTimeRangeSelection = x || false;

        if (x) {
            this._mouseDownEventListener = this._handleMouseDown.bind(this);
            this._element.addEventListener("mousedown", this._mouseDownEventListener);

            this._leftShadedAreaElement = document.createElement("div");
            this._leftShadedAreaElement.classList.add(WebInspector.TimelineRuler.ShadedAreaElementStyleClassName);
            this._leftShadedAreaElement.classList.add(WebInspector.TimelineRuler.LeftSelectionElementStyleClassName);

            this._rightShadedAreaElement = document.createElement("div");
            this._rightShadedAreaElement.classList.add(WebInspector.TimelineRuler.ShadedAreaElementStyleClassName);
            this._rightShadedAreaElement.classList.add(WebInspector.TimelineRuler.RightSelectionElementStyleClassName);

            this._leftSelectionHandleElement = document.createElement("div");
            this._leftSelectionHandleElement.classList.add(WebInspector.TimelineRuler.SelectionHandleElementStyleClassName);
            this._leftSelectionHandleElement.classList.add(WebInspector.TimelineRuler.LeftSelectionElementStyleClassName);
            this._leftSelectionHandleElement.addEventListener("mousedown", this._handleSelectionHandleMouseDown.bind(this));

            this._rightSelectionHandleElement = document.createElement("div");
            this._rightSelectionHandleElement.classList.add(WebInspector.TimelineRuler.SelectionHandleElementStyleClassName);
            this._rightSelectionHandleElement.classList.add(WebInspector.TimelineRuler.RightSelectionElementStyleClassName);
            this._rightSelectionHandleElement.addEventListener("mousedown", this._handleSelectionHandleMouseDown.bind(this));

            this._selectionDragElement = document.createElement("div");
            this._selectionDragElement.classList.add(WebInspector.TimelineRuler.SelectionDragElementStyleClassName);

            this._needsSelectionLayout();
        } else {
            this._element.removeEventListener("mousedown", this._mouseDownEventListener);
            delete this._mouseDownEventListener;

            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 zeroTime()
    {
        return this._zeroTime;
    },

    set zeroTime(x)
    {
        if (this._zeroTime === x)
            return;

        this._zeroTime = x || 0;

        this._needsLayout();
    },

    get startTime()
    {
        return this._startTime;
    },

    set startTime(x)
    {
        if (this._startTime === x)
            return;

        this._startTime = x || 0;

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

        this._needsLayout();
    },

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

    set duration(x)
    {
        if (this._duration === x)
            return;

        this._duration = x || NaN;

        if (!isNaN(this._duration)) {
            this._endTime = this._startTime + this._duration;
            this._endTimePinned = true;
        } else
            this._endTimePinned = false;

        this._needsLayout();
    },

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

    set endTime(x)
    {
        if (this._endTime === x)
            return;

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

        this._needsLayout();
    },

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

    set secondsPerPixel(x)
    {
        if (this._secondsPerPixel === x)
            return;

        this._secondsPerPixel = x || 0;
        this._endTimePinned = false;
        this._currentSliceTime = 0;

        this._needsLayout();
    },

    get selectionStartTime()
    {
        return this._selectionStartTime;
    },

    set selectionStartTime(x)
    {
        if (this._selectionStartTime === x)
            return;

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

        this._needsSelectionLayout();
    },

    get selectionEndTime()
    {
        return this._selectionEndTime;
    },

    set selectionEndTime(x)
    {
        if (this._selectionEndTime === x)
            return;

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

        this._needsSelectionLayout();
    },

    addMarker: function(marker)
    {
        console.assert(marker instanceof WebInspector.TimelineMarker);

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

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

        var markerElement = document.createElement("div");
        markerElement.classList.add(WebInspector.TimelineRuler.BaseMarkerElementStyleClassName);
        markerElement.classList.add(marker.type);

        this._markerElementMap.set(marker, markerElement);

        this._needsMarkerLayout();
    },

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

    updateLayout: function()
    {
        if (this._scheduledLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledLayoutUpdateIdentifier);
            delete this._scheduledLayoutUpdateIdentifier;
        }

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

        var duration = this.duration;

        var pixelsPerSecond = visibleWidth / duration;

        // Calculate a divider count based on the maximum allowed divider density.
        var dividerCount = Math.round(visibleWidth / WebInspector.TimelineRuler.MinimumDividerSpacing);

        if (this._endTimePinned || !this._currentSliceTime) {
            // Calculate the slice time based on the rough divider count and the time span.
            var 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 * WebInspector.TimelineRuler.MinimumDividerSpacing)
                sliceTime = sliceTime / 5;
            if (sliceTime * pixelsPerSecond >= 2 * WebInspector.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.
            var sliceTime = this._currentSliceTime;
        }

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

        // Calculate the divider count now based on the final slice time.
        dividerCount = Math.ceil((lastDividerTime - firstDividerTime) / sliceTime);

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

        var markerDividers = this._markersElement.querySelectorAll("." + WebInspector.TimelineRuler.DividerElementStyleClassName);

        var dividerElement = this._headerElement.firstChild;

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

                var labelElement = document.createElement("div");
                labelElement.className = WebInspector.TimelineRuler.DividerLabelElementStyleClassName;
                dividerElement._labelElement = labelElement;
                dividerElement.appendChild(labelElement);
            }

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

            var dividerTime = firstDividerTime + (sliceTime * i);

            var newLeftPosition = (dividerTime - this._startTime) / duration;

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

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

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

            this._updatePositionOfElement(dividerElement, newLeftPosition, visibleWidth);
            this._updatePositionOfElement(markerDividerElement, newLeftPosition, visibleWidth);

            dividerElement._labelElement.textContent = isNaN(dividerTime) ? "" : Number.secondsToString(dividerTime - this._zeroTime, true);
            dividerElement = dividerElement.nextSibling;
        }

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

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

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

    updateLayoutIfNeeded: function()
    {
        // If there is a main layout scheduled we can just update layout and return, since that
        // will update markers and the selection at the same time.
        if (this._scheduledLayoutUpdateIdentifier) {
            this.updateLayout();
            return;
        }

        var visibleWidth = this._element.clientWidth;
        if (visibleWidth <= 0)
            return;

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

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

    // Private

    _needsLayout: function()
    {
        if (this._scheduledLayoutUpdateIdentifier)
            return;

        if (this._scheduledMarkerLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledMarkerLayoutUpdateIdentifier);
            delete this._scheduledMarkerLayoutUpdateIdentifier;
        }

        if (this._scheduledSelectionLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledSelectionLayoutUpdateIdentifier);
            delete this._scheduledSelectionLayoutUpdateIdentifier;
        }

        this._scheduledLayoutUpdateIdentifier = requestAnimationFrame(this.updateLayout.bind(this));
    },

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

        if (this._scheduledMarkerLayoutUpdateIdentifier)
            return;

        function update()
        {
            delete this._scheduledMarkerLayoutUpdateIdentifier;

            var visibleWidth = this._element.clientWidth;
            if (visibleWidth <= 0)
                return;

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

        this._scheduledMarkerLayoutUpdateIdentifier = requestAnimationFrame(update.bind(this));
    },

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

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

        if (this._scheduledSelectionLayoutUpdateIdentifier)
            return;

        function update()
        {
            delete this._scheduledSelectionLayoutUpdateIdentifier;

            var visibleWidth = this._element.clientWidth;
            if (visibleWidth <= 0)
                return;

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

        this._scheduledSelectionLayoutUpdateIdentifier = requestAnimationFrame(update.bind(this));
    },

    _recalculate: function()
    {
        var visibleWidth = this._element.clientWidth;
        if (visibleWidth <= 0)
            return 0;

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

        this._secondsPerPixel = duration / visibleWidth;

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

        return visibleWidth;
    },

    _updatePositionOfElement: function(element, newPosition, visibleWidth, property)
    {
        property = property || "left";

        newPosition *= this._endTimePinned ? 100 : visibleWidth;
        newPosition = newPosition.toFixed(2);

        var currentPosition = parseFloat(element.style[property]).toFixed(2);
        if (currentPosition !== newPosition)
            element.style[property] = newPosition + (this._endTimePinned ? "%" : "px");
    },

    _updateMarkers: function(visibleWidth, duration)
    {
        if (this._scheduledMarkerLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledMarkerLayoutUpdateIdentifier);
            delete this._scheduledMarkerLayoutUpdateIdentifier;
        }

        this._markerElementMap.forEach(function(markerElement, marker) {
            var newLeftPosition = (marker.time - this._startTime) / duration;

            this._updatePositionOfElement(markerElement, newLeftPosition, visibleWidth);

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

    _updateSelection: function(visibleWidth, duration)
    {
        if (this._scheduledSelectionLayoutUpdateIdentifier) {
            cancelAnimationFrame(this._scheduledSelectionLayoutUpdateIdentifier);
            delete this._scheduledSelectionLayoutUpdateIdentifier;
        }

        this._element.classList.toggle(WebInspector.TimelineRuler.AllowsTimeRangeSelectionStyleClassName, this._allowsTimeRangeSelection);

        if (!this._allowsTimeRangeSelection)
            return;

        var newLeftPosition = Math.max(0, (this._selectionStartTime - this._startTime) / duration);
        this._updatePositionOfElement(this._leftShadedAreaElement, newLeftPosition, visibleWidth, "width");
        this._updatePositionOfElement(this._leftSelectionHandleElement, newLeftPosition, visibleWidth, "left");
        this._updatePositionOfElement(this._selectionDragElement, newLeftPosition, visibleWidth, "left");

        var newRightPosition = 1 - Math.min((this._selectionEndTime - this._startTime) / duration, 1);
        this._updatePositionOfElement(this._rightShadedAreaElement, newRightPosition, visibleWidth, "width");
        this._updatePositionOfElement(this._rightSelectionHandleElement, newRightPosition, visibleWidth, "right");
        this._updatePositionOfElement(this._selectionDragElement, newRightPosition, visibleWidth, "right");

        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);
        }

        if (this._timeRangeSelectionChanged)
            this._dispatchTimeRangeSelectionChangedEvent();
    },

    _dispatchTimeRangeSelectionChangedEvent: function()
    {
        delete this._timeRangeSelectionChanged;

        if (this._suppressTimeRangeSelectionChangedEvent)
            return;

        this.dispatchEventToListeners(WebInspector.TimelineRuler.Event.TimeRangeSelectionChanged);
    },

    _timelineMarkerTimeChanged: function()
    {
        this._needsMarkerLayout();
    },

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

        this._selectionIsMove = event.target === this._selectionDragElement;
        this._suppressTimeRangeSelectionChangedEvent = !this._selectionIsMove;

        if (this._selectionIsMove)
            this._lastMousePosition = event.pageX;
        else
            this._mouseDownPosition = event.pageX - this._element.totalOffsetLeft;

        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: function(event)
    {
        console.assert(event.button === 0);

        if (this._selectionIsMove) {
            var currentMousePosition = event.pageX;

            var offsetTime = (currentMousePosition - this._lastMousePosition) * this.secondsPerPixel;
            var selectionDuration = this.selectionEndTime - this.selectionStartTime;

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

            this._lastMousePosition = currentMousePosition;
        } else {
            var currentMousePosition = event.pageX - this._element.totalOffsetLeft;

            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);
        }

        this._updateSelection(this._element.clientWidth, this.duration);

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

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

        if (!this._selectionIsMove && this.selectionEndTime - this.selectionStartTime < WebInspector.TimelineRuler.MinimumSelectionTimeRange) {
            // The section is smaller than allowed, grow in the direction of the drag to meet the minumum.
            var currentMousePosition = event.pageX - this._element.totalOffsetLeft;
            if (currentMousePosition > this._mouseDownPosition) {
                this.selectionEndTime = Math.min(this.selectionStartTime + WebInspector.TimelineRuler.MinimumSelectionTimeRange, this.endTime);
                this.selectionStartTime = this.selectionEndTime - WebInspector.TimelineRuler.MinimumSelectionTimeRange;
            } else {
                this.selectionStartTime = Math.max(this.startTime, this.selectionEndTime - WebInspector.TimelineRuler.MinimumSelectionTimeRange);
                this.selectionEndTime = this.selectionStartTime + WebInspector.TimelineRuler.MinimumSelectionTimeRange
            }
        }

        delete this._suppressTimeRangeSelectionChangedEvent;

        this._dispatchTimeRangeSelectionChangedEvent();

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

        delete this._mouseMovedEventListener;
        delete this._mouseUpEventListener;
        delete this._mouseDownPosition;
        delete this._lastMousePosition;
        delete this._selectionIsMove;

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

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

        this._dragHandleIsStartTime = event.target === this._leftSelectionHandleElement;
        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);

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

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

        var currentMousePosition = event.pageX - this._element.totalOffsetLeft;
        var currentTime = this.startTime + (currentMousePosition * this.secondsPerPixel);

        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) {
                var timeDifference = currentTime - this.selectionStartTime;
                this.selectionStartTime = Math.max(this.startTime, Math.min(currentTime, this.selectionEndTime - WebInspector.TimelineRuler.MinimumSelectionTimeRange));
                this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + WebInspector.TimelineRuler.MinimumSelectionTimeRange, this.selectionEndTime - timeDifference), this.endTime);
            } else {
                var timeDifference = currentTime - this.selectionEndTime;
                this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + WebInspector.TimelineRuler.MinimumSelectionTimeRange, currentTime), this.endTime);
                this.selectionStartTime = Math.max(this.startTime, Math.min(this.selectionStartTime - timeDifference, this.selectionEndTime - WebInspector.TimelineRuler.MinimumSelectionTimeRange));
            }
        } else {
            // Resize the selection on side being dragged.
            if (this._dragHandleIsStartTime)
                this.selectionStartTime = Math.max(this.startTime, Math.min(currentTime, this.selectionEndTime - WebInspector.TimelineRuler.MinimumSelectionTimeRange));
            else
                this.selectionEndTime = Math.min(Math.max(this.selectionStartTime + WebInspector.TimelineRuler.MinimumSelectionTimeRange, currentTime), this.endTime);
        }

        this._updateSelection(this._element.clientWidth, this.duration);

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

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

        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();
    }
}

WebInspector.TimelineRuler.prototype.__proto__ = WebInspector.Object.prototype;
