/*
 * Copyright (C) 2013, 2015 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

WI.TextEditor = class TextEditor extends WI.View
{
    constructor(element, mimeType, delegate)
    {
        super(element);

        this.element.classList.add("text-editor", WI.SyntaxHighlightedStyleClassName);

        this._codeMirror = WI.CodeMirrorEditor.create(this.element, {
            readOnly: true,
            lineNumbers: true,
            matchBrackets: true,
            autoCloseBrackets: true,
            styleSelectedText: true,
        });

        this._codeMirror.on("focus", this._editorFocused.bind(this));
        this._codeMirror.on("change", this._contentChanged.bind(this));
        this._codeMirror.on("gutterClick", this._gutterMouseDown.bind(this));
        this._codeMirror.on("gutterContextMenu", this._gutterContextMenu.bind(this));
        this._codeMirror.getScrollerElement().addEventListener("click", this._openClickedLinks.bind(this), true);

        this._completionController = new WI.CodeMirrorCompletionController(WI.CodeMirrorCompletionController.Mode.Basic, this._codeMirror, this);
        this._tokenTrackingController = new WI.CodeMirrorTokenTrackingController(this._codeMirror, this);

        this._initialStringNotSet = true;

        this.mimeType = mimeType;

        this._breakpoints = {};
        this._executionLineNumber = NaN;
        this._executionColumnNumber = NaN;

        this._executionLineHandle = null;
        this._executionMultilineHandles = [];
        this._executionRangeHighlightMarker = null;

        this._searchQuery = null;
        this._searchResults = [];
        this._currentSearchResultIndex = -1;
        this._ignoreCodeMirrorContentDidChangeEvent = 0;

        this._formatted = false;
        this._formattingPromise = null;
        this._formatterSourceMap = null;
        this._deferReveal = false;
        this._repeatReveal = false;

        this._delegate = delegate || null;
    }

    // Public

    get string()
    {
        return this._codeMirror.getValue();
    }

    set string(newString)
    {
        let previousSelectedTextRange = this._repeatReveal ? this.selectedTextRange : null;

        function update()
        {
            // Clear any styles that may have been set on the empty line before content loaded.
            if (this._initialStringNotSet)
                this._codeMirror.removeLineClass(0, "wrap");

            if (this._codeMirror.getValue() !== newString)
                this._codeMirror.setValue(newString);
            else {
                // Ensure we at display content even if the value did not change. This often happens when auto formatting.
                this.layout();
            }

            if (this._initialStringNotSet) {
                this._codeMirror.clearHistory();
                this._codeMirror.markClean();

                this._initialStringNotSet = false;

                // There may have been an attempt at a search before the initial string was set. If so, reperform it now that we have content.
                if (this._searchQuery) {
                    let query = this._searchQuery;
                    this._searchQuery = null;
                    this.performSearch(query);
                }

                if (this._codeMirror.getMode().name === "null") {
                    // If the content matches a known MIME type, but isn't explicitly declared as
                    // such, attempt to detect that so we can enable syntax highlighting and
                    // formatting features.
                    this._attemptToDetermineMIMEType();
                }
            }

            // Update the execution line now that we might have content for that line.
            this._updateExecutionLine();
            this._updateExecutionRangeHighlight();

            // Set the breakpoint styles now that we might have content for those lines.
            for (var lineNumber in this._breakpoints)
                this._setBreakpointStylesOnLine(lineNumber);

            // Try revealing the pending line, or previous position, now that we might have new content.
            this._revealPendingPositionIfPossible();
            if (previousSelectedTextRange) {
                this.selectedTextRange = previousSelectedTextRange;
                let position = this._codeMirrorPositionFromTextRange(previousSelectedTextRange);
                this._scrollIntoViewCentered(position.start);
            }
        }

        this._ignoreCodeMirrorContentDidChangeEvent++;
        this._codeMirror.operation(update.bind(this));
        this._ignoreCodeMirrorContentDidChangeEvent--;
        console.assert(this._ignoreCodeMirrorContentDidChangeEvent >= 0);
    }

    get readOnly()
    {
        return this._codeMirror.getOption("readOnly") || false;
    }

    set readOnly(readOnly)
    {
        this._codeMirror.setOption("readOnly", readOnly);
        this._codeMirror.getWrapperElement().classList.toggle("read-only", !!readOnly);
    }

    get formatted()
    {
        return this._formatted;
    }

    get hasModified()
    {
        let historySize = this._codeMirror.historySize().undo;

        // Formatting code creates a history item.
        if (this._formatted)
            historySize--;

        return historySize > 0;
    }

    updateFormattedState(formatted)
    {
        return this._format(formatted);
    }

    hasFormatter()
    {
        let mode = this._codeMirror.getMode().name;
        return mode === "javascript" || mode === "css" || mode === "htmlmixed" || mode === "xml";
    }

    canBeFormatted()
    {
        // Can be overridden by subclasses.
        return this.hasFormatter();
    }

    canShowTypeAnnotations()
    {
        return false;
    }

    canShowCoverageHints()
    {
        return false;
    }

    get selectedTextRange()
    {
        var start = this._codeMirror.getCursor(true);
        var end = this._codeMirror.getCursor(false);
        return this._textRangeFromCodeMirrorPosition(start, end);
    }

    set selectedTextRange(textRange)
    {
        if (document.activeElement === document.body)
            this.focus();

        var position = this._codeMirrorPositionFromTextRange(textRange);
        this._codeMirror.setSelection(position.start, position.end);
    }

    get mimeType()
    {
        return this._mimeType;
    }

    set mimeType(newMIMEType)
    {
        newMIMEType = parseMIMEType(newMIMEType).type;

        this._mimeType = newMIMEType;
        this._codeMirror.setOption("mode", {name: newMIMEType, globalVars: true});

        this.dispatchEventToListeners(WI.TextEditor.Event.MIMETypeChanged);
    }

    get executionLineNumber()
    {
        return this._executionLineNumber;
    }

    get executionColumnNumber()
    {
        return this._executionColumnNumber;
    }

    get formatterSourceMap()
    {
        return this._formatterSourceMap;
    }

    get tokenTrackingController()
    {
        return this._tokenTrackingController;
    }

    get delegate()
    {
        return this._delegate;
    }

    set delegate(newDelegate)
    {
        this._delegate = newDelegate || null;
    }

    get numberOfSearchResults()
    {
        return this._searchResults.length;
    }

    get currentSearchQuery()
    {
        return this._searchQuery;
    }

    set automaticallyRevealFirstSearchResult(reveal)
    {
        this._automaticallyRevealFirstSearchResult = reveal;

        // If we haven't shown a search result yet, reveal one now.
        if (this._automaticallyRevealFirstSearchResult && this._searchResults.length > 0) {
            if (this._currentSearchResultIndex === -1)
                this._revealFirstSearchResultAfterCursor();
        }
    }

    set deferReveal(defer)
    {
        this._deferReveal = defer;
    }

    set repeatReveal(repeat)
    {
        this._repeatReveal = repeat;
    }

    performSearch(query)
    {
        if (this._searchQuery === query)
            return;

        this.searchCleared();

        this._searchQuery = query;

        // Defer until the initial string is set.
        if (this._initialStringNotSet)
            return;

        // Allow subclasses to handle the searching if they have a better way.
        // If we are formatted, just use CodeMirror's search.
        if (typeof this.customPerformSearch === "function" && !this.formatted) {
            if (this.customPerformSearch(query))
                return;
        }

        let queryRegex = WI.SearchUtilities.searchRegExpForString(query, WI.SearchUtilities.defaultSettings);
        if (!queryRegex) {
            this.searchCleared();
            this.dispatchEventToListeners(WI.TextEditor.Event.NumberOfSearchResultsDidChange);
            return;
        }

        // Go down the slow patch for all other text content.
        var searchCursor = this._codeMirror.getSearchCursor(queryRegex, {line: 0, ch: 0}, false);
        var boundBatchSearch = batchSearch.bind(this);
        var numberOfSearchResultsDidChangeTimeout = null;

        function reportNumberOfSearchResultsDidChange()
        {
            if (numberOfSearchResultsDidChangeTimeout) {
                clearTimeout(numberOfSearchResultsDidChangeTimeout);
                numberOfSearchResultsDidChangeTimeout = null;
            }

            this.dispatchEventToListeners(WI.TextEditor.Event.NumberOfSearchResultsDidChange);
        }

        function batchSearch()
        {
            // Bail if the query changed since we started.
            if (this._searchQuery !== query)
                return;

            var newSearchResults = [];
            var foundResult = false;
            for (var i = 0; i < WI.TextEditor.NumberOfFindsPerSearchBatch && (foundResult = searchCursor.findNext()); ++i) {
                var textRange = this._textRangeFromCodeMirrorPosition(searchCursor.from(), searchCursor.to());
                newSearchResults.push(textRange);
            }

            this.addSearchResults(newSearchResults);

            // Don't report immediately, coalesce updates so they come in no faster than half a second.
            if (!numberOfSearchResultsDidChangeTimeout)
                numberOfSearchResultsDidChangeTimeout = setTimeout(reportNumberOfSearchResultsDidChange.bind(this), 500);

            if (foundResult) {
                // More lines to search, set a timeout so we don't block the UI long.
                setTimeout(boundBatchSearch, 50);
            } else {
                // Report immediately now that we are finished, canceling any pending update.
                reportNumberOfSearchResultsDidChange.call(this);
            }
        }

        // Start the search.
        boundBatchSearch();
    }

    setExecutionLineAndColumn(lineNumber, columnNumber)
    {
        // Only return early if there isn't a line handle and that isn't changing.
        if (!this._executionLineHandle && isNaN(lineNumber))
            return;

        this._executionLineNumber = lineNumber;
        this._executionColumnNumber = columnNumber;

        if (!this._initialStringNotSet) {
            this._updateExecutionLine();
            this._updateExecutionRangeHighlight();
        }

        // Still dispatch the event even if the number didn't change. The execution state still
        // could have changed (e.g. continuing in a loop with a breakpoint inside).
        this.dispatchEventToListeners(WI.TextEditor.Event.ExecutionLineNumberDidChange);
    }

    addSearchResults(textRanges)
    {
        console.assert(textRanges);
        if (!textRanges || !textRanges.length)
            return;

        function markRanges()
        {
            for (var i = 0; i < textRanges.length; ++i) {
                var position = this._codeMirrorPositionFromTextRange(textRanges[i]);
                var mark = this._codeMirror.markText(position.start, position.end, {className: WI.TextEditor.SearchResultStyleClassName});
                this._searchResults.push(mark);
            }

            // If we haven't shown a search result yet, reveal one now.
            if (this._automaticallyRevealFirstSearchResult) {
                if (this._currentSearchResultIndex === -1)
                    this._revealFirstSearchResultAfterCursor();
            }
        }

        this._codeMirror.operation(markRanges.bind(this));
    }

    searchCleared()
    {
        this._codeMirror.operation(() => {
            for (let searchResult of this._searchResults)
                searchResult.clear();
        });

        this._searchQuery = null;
        this._searchResults = [];
        this._currentSearchResultIndex = -1;
    }

    searchQueryWithSelection()
    {
        if (!this._codeMirror.somethingSelected())
            return null;

        return this._codeMirror.getSelection();
    }

    revealPreviousSearchResult(changeFocus)
    {
        if (!this._searchResults.length)
            return;

        if (this._currentSearchResultIndex === -1 || this._cursorDoesNotMatchLastRevealedSearchResult()) {
            this._revealFirstSearchResultBeforeCursor(changeFocus);
            return;
        }

        if (this._currentSearchResultIndex > 0)
            --this._currentSearchResultIndex;
        else
            this._currentSearchResultIndex = this._searchResults.length - 1;

        this._revealSearchResult(this._searchResults[this._currentSearchResultIndex], changeFocus, -1);
    }

    revealNextSearchResult(changeFocus)
    {
        if (!this._searchResults.length)
            return;

        if (this._currentSearchResultIndex === -1 || this._cursorDoesNotMatchLastRevealedSearchResult()) {
            this._revealFirstSearchResultAfterCursor(changeFocus);
            return;
        }

        if (this._currentSearchResultIndex + 1 < this._searchResults.length)
            ++this._currentSearchResultIndex;
        else
            this._currentSearchResultIndex = 0;

        this._revealSearchResult(this._searchResults[this._currentSearchResultIndex], changeFocus, 1);
    }

    line(lineNumber)
    {
        return this._codeMirror.getLine(lineNumber);
    }

    getTextInRange(startPosition, endPosition)
    {
        return this._codeMirror.getRange(startPosition.toCodeMirror(), endPosition.toCodeMirror());
    }

    addStyleToTextRange(startPosition, endPosition, styleClassName)
    {
        endPosition = endPosition.offsetColumn(1);
        return this._codeMirror.getDoc().markText(startPosition.toCodeMirror(), endPosition.toCodeMirror(), {className: styleClassName, inclusiveLeft: true, inclusiveRight: true});
    }

    revealPosition(position, textRangeToSelect, forceUnformatted, noHighlight)
    {
        console.assert(position === undefined || position instanceof WI.SourceCodePosition, "revealPosition called without a SourceCodePosition");
        if (!(position instanceof WI.SourceCodePosition))
            return;

        if (!this.isAttached || this._initialStringNotSet || this._deferReveal) {
            // If we can't get a line handle or are not visible then we wait to do the reveal.
            this._positionToReveal = position;
            this._textRangeToSelect = textRangeToSelect;
            this._forceUnformatted = forceUnformatted;
            return;
        }

        // Delete now that the reveal is happening.
        delete this._positionToReveal;
        delete this._textRangeToSelect;
        delete this._forceUnformatted;

        // If we need to unformat, reveal the line after a wait.
        // Otherwise the line highlight doesn't work properly.
        if (this._formatted && forceUnformatted) {
            this.updateFormattedState(false).then(() => {
                setTimeout(this.revealPosition.bind(this), 0, position, textRangeToSelect);
            });
            return;
        }

        let line = Number.constrain(position.lineNumber, 0, this._codeMirror.lineCount() - 1);
        let lineHandle = this._codeMirror.getLineHandle(line);

        if (!textRangeToSelect) {
            let column = Number.constrain(position.columnNumber, 0, this._codeMirror.getLine(line).length);
            textRangeToSelect = new WI.TextRange(line, column, line, column);
        }

        function removeStyleClass()
        {
            this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.HighlightedStyleClassName);
        }

        function revealAndHighlightLine()
        {
            // If the line is not visible, reveal it as the center line in the editor.
            var position = this._codeMirrorPositionFromTextRange(textRangeToSelect);
            if (!this._isPositionVisible(position.start))
                this._scrollIntoViewCentered(position.start);

            this.selectedTextRange = textRangeToSelect;

            if (noHighlight)
                return;

            // Avoid highlighting the execution line while debugging.
            if (WI.debuggerManager.paused && line === this._executionLineNumber)
                return;

            this._codeMirror.addLineClass(lineHandle, "wrap", WI.TextEditor.HighlightedStyleClassName);

            // Use a timeout instead of a animationEnd event listener because the line element might
            // be removed if the user scrolls during the animation. In that case animationEnd isn't
            // fired, and the line would highlight again the next time it scrolls into view.
            setTimeout(removeStyleClass.bind(this), WI.TextEditor.HighlightAnimationDuration);
        }

        this._codeMirror.operation(revealAndHighlightLine.bind(this));
    }

    attached()
    {
        super.attached();

        // Refresh since our size might have changed.
        this._codeMirror.refresh();

        // Try revealing the pending line now that we are visible.
        // This needs to be done as a separate operation from the refresh
        // so that the scrollInfo coordinates are correct.
        this._revealPendingPositionIfPossible();
    }

    setBreakpointInfoForLineAndColumn(lineNumber, columnNumber, breakpointInfo)
    {
        if (this._ignoreSetBreakpointInfoCalls)
            return;

        if (breakpointInfo)
            this._addBreakpointToLineAndColumnWithInfo(lineNumber, columnNumber, breakpointInfo);
        else
            this._removeBreakpointFromLineAndColumn(lineNumber, columnNumber);
    }

    updateBreakpointLineAndColumn(oldLineNumber, oldColumnNumber, newLineNumber, newColumnNumber)
    {
        console.assert(this._breakpoints[oldLineNumber]);
        if (!this._breakpoints[oldLineNumber])
            return;

        console.assert(this._breakpoints[oldLineNumber][oldColumnNumber]);
        if (!this._breakpoints[oldLineNumber][oldColumnNumber])
            return;

        var breakpointInfo = this._breakpoints[oldLineNumber][oldColumnNumber];
        this._removeBreakpointFromLineAndColumn(oldLineNumber, oldColumnNumber);
        this._addBreakpointToLineAndColumnWithInfo(newLineNumber, newColumnNumber, breakpointInfo);
    }

    addStyleClassToLine(lineNumber, styleClassName)
    {
        var lineHandle = this._codeMirror.getLineHandle(lineNumber);
        if (!lineHandle)
            return null;

        return this._codeMirror.addLineClass(lineHandle, "wrap", styleClassName);
    }

    removeStyleClassFromLine(lineNumber, styleClassName)
    {
        var lineHandle = this._codeMirror.getLineHandle(lineNumber);
        console.assert(lineHandle);
        if (!lineHandle)
            return null;

        return this._codeMirror.removeLineClass(lineHandle, "wrap", styleClassName);
    }

    toggleStyleClassForLine(lineNumber, styleClassName)
    {
        var lineHandle = this._codeMirror.getLineHandle(lineNumber);
        console.assert(lineHandle);
        if (!lineHandle)
            return false;

        return this._codeMirror.toggleLineClass(lineHandle, "wrap", styleClassName);
    }

    createWidgetForLine(lineNumber)
    {
        var lineHandle = this._codeMirror.getLineHandle(lineNumber);
        if (!lineHandle)
            return null;

        var widgetElement = document.createElement("div");
        var lineWidget = this._codeMirror.addLineWidget(lineHandle, widgetElement, {coverGutter: false, noHScroll: true});
        return new WI.LineWidget(lineWidget, widgetElement);
    }

    get lineCount()
    {
        return this._codeMirror.lineCount();
    }

    focus()
    {
        this._codeMirror.focus();
    }

    contentDidChange(replacedRanges, newRanges)
    {
        // Implemented by subclasses.
    }

    rectsForRange(range)
    {
        return this._codeMirror.rectsForRange(range);
    }

    get markers()
    {
        return this._codeMirror.getAllMarks().map(WI.TextMarker.textMarkerForCodeMirrorTextMarker);
    }

    markersAtPosition(position)
    {
        return this._codeMirror.findMarksAt(position).map(WI.TextMarker.textMarkerForCodeMirrorTextMarker);
    }

    createColorMarkers(range)
    {
        return createCodeMirrorColorTextMarkers(this._codeMirror, range);
    }

    createGradientMarkers(range)
    {
        return createCodeMirrorGradientTextMarkers(this._codeMirror, range);
    }

    createCubicBezierMarkers(range)
    {
        return createCodeMirrorCubicBezierTextMarkers(this._codeMirror, range);
    }

    createSpringMarkers(range)
    {
        return createCodeMirrorSpringTextMarkers(this._codeMirror, range);
    }

    editingControllerForMarker(editableMarker)
    {
        switch (editableMarker.type) {
        case WI.TextMarker.Type.Color:
            return new WI.CodeMirrorColorEditingController(this._codeMirror, editableMarker);
        case WI.TextMarker.Type.Gradient:
            return new WI.CodeMirrorGradientEditingController(this._codeMirror, editableMarker);
        case WI.TextMarker.Type.CubicBezier:
            return new WI.CodeMirrorBezierEditingController(this._codeMirror, editableMarker);
        case WI.TextMarker.Type.Spring:
            return new WI.CodeMirrorSpringEditingController(this._codeMirror, editableMarker);
        default:
            return new WI.CodeMirrorEditingController(this._codeMirror, editableMarker);
        }
    }

    visibleRangeOffsets()
    {
        var startOffset = null;
        var endOffset = null;
        var visibleRange = this._codeMirror.getViewport();

        if (this._formatterSourceMap) {
            startOffset = this._formatterSourceMap.formattedToOriginalOffset(Math.max(visibleRange.from - 1, 0), 0);
            endOffset = this._formatterSourceMap.formattedToOriginalOffset(visibleRange.to - 1, 0);
        } else {
            startOffset = this._codeMirror.getDoc().indexFromPos({line: visibleRange.from, ch: 0});
            endOffset = this._codeMirror.getDoc().indexFromPos({line: visibleRange.to, ch: 0});
        }

        return {startOffset, endOffset};
    }

    visibleRangePositions()
    {
        let visibleRange = this._codeMirror.getViewport();
        let startLine;
        let endLine;

        if (this._formatterSourceMap) {
            startLine = this._formatterSourceMap.formattedToOriginal(Math.max(visibleRange.from - 1, 0), 0).lineNumber;
            endLine = this._formatterSourceMap.formattedToOriginal(visibleRange.to - 1, 0).lineNumber;
        } else {
            startLine = visibleRange.from;
            endLine = visibleRange.to;
        }

        return {
            startPosition: new WI.SourceCodePosition(startLine, 0),
            endPosition: new WI.SourceCodePosition(endLine, 0)
        };
    }

    originalPositionToCurrentPosition(position)
    {
        if (!this._formatterSourceMap)
            return position;

        let {lineNumber, columnNumber} = this._formatterSourceMap.originalToFormatted(position.lineNumber, position.columnNumber);
        return new WI.SourceCodePosition(lineNumber, columnNumber);
    }

    originalOffsetToCurrentPosition(offset)
    {
        var position = null;
        if (this._formatterSourceMap) {
            var location = this._formatterSourceMap.originalPositionToFormatted(offset);
            position = {line: location.lineNumber, ch: location.columnNumber};
        } else
            position = this._codeMirror.getDoc().posFromIndex(offset);

        return position;
    }

    currentOffsetToCurrentPosition(offset)
    {
        let pos = this._codeMirror.getDoc().posFromIndex(offset);
        return new WI.SourceCodePosition(pos.line, pos.ch);
    }

    currentPositionToOriginalOffset(position)
    {
        let offset = null;

        if (this._formatterSourceMap)
            offset = this._formatterSourceMap.formattedToOriginalOffset(position.line, position.ch);
        else
            offset = this._codeMirror.getDoc().indexFromPos(position);

        return offset;
    }

    currentPositionToOriginalPosition(position)
    {
        if (!this._formatterSourceMap)
            return position;

        let location = this._formatterSourceMap.formattedToOriginal(position.lineNumber, position.columnNumber);
        return new WI.SourceCodePosition(location.lineNumber, location.columnNumber);
    }

    currentPositionToCurrentOffset(position)
    {
        return this._codeMirror.getDoc().indexFromPos(position.toCodeMirror());
    }

    setInlineWidget(position, inlineElement)
    {
        return this._codeMirror.setUniqueBookmark(position.toCodeMirror(), {widget: inlineElement});
    }

    addScrollHandler(handler)
    {
        this._codeMirror.on("scroll", handler);
    }

    removeScrollHandler(handler)
    {
        this._codeMirror.off("scroll", handler);
    }

    // Protected

    layout()
    {
        super.layout();

        this._codeMirror.refresh();
    }

    _format(formatted)
    {
        if (this._formatted === formatted)
            return Promise.resolve(this._formatted);

        console.assert(!formatted || this.canBeFormatted());
        if (formatted && !this.canBeFormatted())
            return Promise.resolve(this._formatted);

        if (this._formattingPromise)
            return this._formattingPromise;

        this._ignoreCodeMirrorContentDidChangeEvent++;
        this._formattingPromise = this.prettyPrint(formatted).then(() => {
            this._ignoreCodeMirrorContentDidChangeEvent--;
            console.assert(this._ignoreCodeMirrorContentDidChangeEvent >= 0);

            this._formattingPromise = null;

            let originalFormatted = this._formatted;
            this._formatted = !!this._formatterSourceMap;

            if (this._formatted !== originalFormatted)
                this.dispatchEventToListeners(WI.TextEditor.Event.FormattingDidChange);

            return this._formatted;
        });

        return this._formattingPromise;
    }

    prettyPrint(pretty)
    {
        return new Promise((resolve, reject) => {
            let beforePrettyPrintState = {
                selectionAnchor: this._codeMirror.getCursor("anchor"),
                selectionHead: this._codeMirror.getCursor("head"),
            };

            if (!pretty)
                this._undoFormatting(beforePrettyPrintState, resolve);
            else
                this._startWorkerPrettyPrint(beforePrettyPrintState, resolve);
        });
    }

    _attemptToDetermineMIMEType()
    {
        let startTime = Date.now();

        const isModule = false;
        const includeSourceMapData = false;
        let workerProxy = WI.FormatterWorkerProxy.singleton();
        workerProxy.formatJavaScript(this.string, isModule, WI.indentString(), includeSourceMapData, ({formattedText}) => {
            if (!formattedText)
                return;

            this.mimeType = "text/javascript";

            if (Date.now() - startTime < 100)
                this.updateFormattedState(true);
        });
    }

    _startWorkerPrettyPrint(beforePrettyPrintState, callback)
    {
        let workerProxy = WI.FormatterWorkerProxy.singleton();
        let sourceText = this._codeMirror.getValue();
        let indentString = WI.indentString();
        const includeSourceMapData = true;

        let formatCallback = ({formattedText, sourceMapData}) => {
            // Handle if formatting failed, which is possible for invalid programs.
            if (formattedText === null) {
                callback();
                return;
            }
            this._finishPrettyPrint(beforePrettyPrintState, formattedText, sourceMapData, callback);
        };

        let mode = this._codeMirror.getMode().name;
        switch (mode) {
        case "javascript": {
            let sourceType = this._delegate ? this._delegate.textEditorScriptSourceType(this) : WI.Script.SourceType.Program;
            const isModule = sourceType === WI.Script.SourceType.Module;
            workerProxy.formatJavaScript(sourceText, isModule, indentString, includeSourceMapData, formatCallback);
            break;
        }
        case "css":
            workerProxy.formatCSS(sourceText, indentString, includeSourceMapData, formatCallback);
            break;
        case "htmlmixed":
            workerProxy.formatHTML(sourceText, indentString, includeSourceMapData, formatCallback);
            break;
        case "xml":
            workerProxy.formatXML(sourceText, indentString, includeSourceMapData, formatCallback);
            break;
        default:
            console.assert(false, "Unexpected mode attempted to pretty print.");
            break;
        }
    }

    _finishPrettyPrint(beforePrettyPrintState, formattedText, sourceMapData, callback)
    {
        this._codeMirror.operation(() => {
            this._formatterSourceMap = WI.FormatterSourceMap.fromSourceMapData(sourceMapData);
            this._codeMirror.setValue(formattedText);
            this._updateAfterFormatting(true, beforePrettyPrintState);
        });

        callback();
    }

    _undoFormatting(beforePrettyPrintState, callback)
    {
        this._codeMirror.operation(() => {
            this._codeMirror.undo();
            this._updateAfterFormatting(false, beforePrettyPrintState);
        });

        callback();
    }

    _updateAfterFormatting(pretty, beforePrettyPrintState)
    {
        let oldSelectionAnchor = beforePrettyPrintState.selectionAnchor;
        let oldSelectionHead = beforePrettyPrintState.selectionHead;
        let newSelectionAnchor, newSelectionHead;
        let newExecutionLocation = null;

        if (pretty) {
            if (this._positionToReveal) {
                let newRevealPosition = this._formatterSourceMap.originalToFormatted(this._positionToReveal.lineNumber, this._positionToReveal.columnNumber);
                this._positionToReveal = new WI.SourceCodePosition(newRevealPosition.lineNumber, newRevealPosition.columnNumber);
            }

            if (this._textRangeToSelect) {
                let mappedRevealSelectionStart = this._formatterSourceMap.originalToFormatted(this._textRangeToSelect.startLine, this._textRangeToSelect.startColumn);
                let mappedRevealSelectionEnd = this._formatterSourceMap.originalToFormatted(this._textRangeToSelect.endLine, this._textRangeToSelect.endColumn);
                this._textRangeToSelect = new WI.TextRange(mappedRevealSelectionStart.lineNumber, mappedRevealSelectionStart.columnNumber, mappedRevealSelectionEnd.lineNumber, mappedRevealSelectionEnd.columnNumber);
            }

            if (!isNaN(this._executionLineNumber)) {
                console.assert(!isNaN(this._executionColumnNumber));
                newExecutionLocation = this._formatterSourceMap.originalToFormatted(this._executionLineNumber, this._executionColumnNumber);
            }

            let mappedAnchorLocation = this._formatterSourceMap.originalToFormatted(oldSelectionAnchor.line, oldSelectionAnchor.ch);
            let mappedHeadLocation = this._formatterSourceMap.originalToFormatted(oldSelectionHead.line, oldSelectionHead.ch);
            newSelectionAnchor = {line: mappedAnchorLocation.lineNumber, ch: mappedAnchorLocation.columnNumber};
            newSelectionHead = {line: mappedHeadLocation.lineNumber, ch: mappedHeadLocation.columnNumber};
        } else {
            if (this._positionToReveal) {
                let newRevealPosition = this._formatterSourceMap.formattedToOriginal(this._positionToReveal.lineNumber, this._positionToReveal.columnNumber);
                this._positionToReveal = new WI.SourceCodePosition(newRevealPosition.lineNumber, newRevealPosition.columnNumber);
            }

            if (this._textRangeToSelect) {
                let mappedRevealSelectionStart = this._formatterSourceMap.formattedToOriginal(this._textRangeToSelect.startLine, this._textRangeToSelect.startColumn);
                let mappedRevealSelectionEnd = this._formatterSourceMap.formattedToOriginal(this._textRangeToSelect.endLine, this._textRangeToSelect.endColumn);
                this._textRangeToSelect = new WI.TextRange(mappedRevealSelectionStart.lineNumber, mappedRevealSelectionStart.columnNumber, mappedRevealSelectionEnd.lineNumber, mappedRevealSelectionEnd.columnNumber);
            }

            if (!isNaN(this._executionLineNumber)) {
                console.assert(!isNaN(this._executionColumnNumber));
                newExecutionLocation = this._formatterSourceMap.formattedToOriginal(this._executionLineNumber, this._executionColumnNumber);
            }

            let mappedAnchorLocation = this._formatterSourceMap.formattedToOriginal(oldSelectionAnchor.line, oldSelectionAnchor.ch);
            let mappedHeadLocation = this._formatterSourceMap.formattedToOriginal(oldSelectionHead.line, oldSelectionHead.ch);
            newSelectionAnchor = {line: mappedAnchorLocation.lineNumber, ch: mappedAnchorLocation.columnNumber};
            newSelectionHead = {line: mappedHeadLocation.lineNumber, ch: mappedHeadLocation.columnNumber};

            this._formatterSourceMap = null;
        }

        this._scrollIntoViewCentered(newSelectionAnchor);
        this._codeMirror.setSelection(newSelectionAnchor, newSelectionHead);

        if (newExecutionLocation) {
            this._executionLineHandle = null;
            this._executionMultilineHandles = [];
            this.setExecutionLineAndColumn(newExecutionLocation.lineNumber, newExecutionLocation.columnNumber);
        }

        // FIXME: <rdar://problem/13129955> FindBanner: New searches should not lose search position (start from current selection/caret)
        if (this.currentSearchQuery) {
            let searchQuery = this.currentSearchQuery;
            this.searchCleared();
            // Set timeout so that this happens after the current CodeMirror operation.
            // The editor has to update for the value and selection changes.
            setTimeout(() => { this.performSearch(searchQuery); }, 0);
        }

        if (this._delegate && typeof this._delegate.textEditorUpdatedFormatting === "function")
            this._delegate.textEditorUpdatedFormatting(this);
    }

    // Private

    hasEdits()
    {
        return !this._codeMirror.isClean();
    }

    _editorFocused(codeMirror)
    {
        this.dispatchEventToListeners(WI.TextEditor.Event.Focused);
    }

    _contentChanged(codeMirror, change)
    {
        if (this._ignoreCodeMirrorContentDidChangeEvent > 0)
            return;

        var replacedRanges = [];
        var newRanges = [];
        while (change) {
            replacedRanges.push(new WI.TextRange(
                change.from.line,
                change.from.ch,
                change.to.line,
                change.to.ch
            ));
            newRanges.push(new WI.TextRange(
                change.from.line,
                change.from.ch,
                change.from.line + change.text.length - 1,
                change.text.length === 1 ? change.from.ch + change.text[0].length : change.text.lastValue.length
            ));
            change = change.next;
        }
        this.contentDidChange(replacedRanges, newRanges);

        if (this._formatted) {
            this._formatterSourceMap = null;
            this._formatted = false;

            if (this._delegate && typeof this._delegate.textEditorUpdatedFormatting === "function")
                this._delegate.textEditorUpdatedFormatting(this);

            this.dispatchEventToListeners(WI.TextEditor.Event.FormattingDidChange);
        }

        this.dispatchEventToListeners(WI.TextEditor.Event.ContentDidChange);
    }

    _textRangeFromCodeMirrorPosition(start, end)
    {
        console.assert(start);
        console.assert(end);

        return new WI.TextRange(start.line, start.ch, end.line, end.ch);
    }

    _codeMirrorPositionFromTextRange(textRange)
    {
        console.assert(textRange);

        var start = {line: textRange.startLine, ch: textRange.startColumn};
        var end = {line: textRange.endLine, ch: textRange.endColumn};
        return {start, end};
    }

    _revealPendingPositionIfPossible()
    {
        // Nothing to do if we don't have a pending position.
        if (!this._positionToReveal)
            return;

        // Don't try to reveal unless we are visible.
        if (!this.isAttached)
            return;

        this.revealPosition(this._positionToReveal, this._textRangeToSelect, this._forceUnformatted);
    }

    _revealSearchResult(result, changeFocus, directionInCaseOfRevalidation)
    {
        let position = result.find();

        // Check for a valid position, it might have been removed from editing by the user.
        // If the position is invalide, revalidate all positions reveal as needed.
        if (!position) {
            this._revalidateSearchResults(directionInCaseOfRevalidation);
            return;
        }

        // If the line is not visible, reveal it as the center line in the editor.
        if (!this._isPositionVisible(position.from))
            this._scrollIntoViewCentered(position.from);

        // Update the text selection to select the search result.
        this.selectedTextRange = this._textRangeFromCodeMirrorPosition(position.from, position.to);

        // Remove the automatically reveal state now that we have revealed a search result.
        this._automaticallyRevealFirstSearchResult = false;

        // Focus the editor if requested.
        if (changeFocus)
            this._codeMirror.focus();

        // Collect info for the bouncy highlight.
        let highlightEditorPosition = this._codeMirror.getCursor("start");
        let textContent = this._codeMirror.getSelection();

        // Remove the bouncy highlight if it is still around. The animation will not
        // start unless we remove it and add it back to the document.
        this._removeBouncyHighlightElementIfNeeded();

        // Create the bouncy highlight.
        this._bouncyHighlightElement = document.createElement("div");
        this._bouncyHighlightElement.className = WI.TextEditor.BouncyHighlightStyleClassName;
        this._bouncyHighlightElement.textContent = textContent;

        function positionBouncyHighlight() {
            // Adjust the coordinates to be based in the text editor's space.
            let coordinates = this._codeMirror.cursorCoords(highlightEditorPosition, "page");
            let textEditorRect = this.element.getBoundingClientRect();
            coordinates.top -= textEditorRect.top;
            coordinates.left -= textEditorRect.left;

            // Position the bouncy highlight.
            this._bouncyHighlightElement.style.top = coordinates.top + "px";
            this._bouncyHighlightElement.style.left = coordinates.left + "px";
        }

        // Position and show the highlight.
        positionBouncyHighlight.call(this);
        this.element.appendChild(this._bouncyHighlightElement);

        // Reposition the highlight if the editor scrolls.
        this._bouncyHighlightScrollHandler = () => { positionBouncyHighlight.call(this); };
        this.addScrollHandler(this._bouncyHighlightScrollHandler);

        // Listen for the end of the animation so we can remove the element.
        this._bouncyHighlightElement.addEventListener("animationend", () => {
            this._removeBouncyHighlightElementIfNeeded();
        });
    }

    _removeBouncyHighlightElementIfNeeded()
    {
        if (!this._bouncyHighlightElement)
            return;

        this.removeScrollHandler(this._bouncyHighlightScrollHandler);
        this._bouncyHighlightScrollHandler = null;

        this._bouncyHighlightElement.remove();
        this._bouncyHighlightElement = null;
    }

    _binarySearchInsertionIndexInSearchResults(object, comparator)
    {
        // It is possible that markers in the search results array may have been deleted.
        // In those cases the comparator will return "null" and we immediately stop
        // the binary search and return null. The search results list needs to be updated.
        var array = this._searchResults;

        var first = 0;
        var last = array.length - 1;

        while (first <= last) {
            var mid = (first + last) >> 1;
            var c = comparator(object, array[mid]);
            if (c === null)
                return null;
            if (c > 0)
                first = mid + 1;
            else if (c < 0)
                last = mid - 1;
            else
                return mid;
        }

        return first - 1;
    }

    _revealFirstSearchResultBeforeCursor(changeFocus)
    {
        console.assert(this._searchResults.length);

        var currentCursorPosition = this._codeMirror.getCursor("start");
        if (currentCursorPosition.line === 0 && currentCursorPosition.ch === 0) {
            this._currentSearchResultIndex = this._searchResults.length - 1;
            this._revealSearchResult(this._searchResults[this._currentSearchResultIndex], changeFocus, -1);
            return;
        }

        var index = this._binarySearchInsertionIndexInSearchResults(currentCursorPosition, function(current, searchResult) {
            var searchResultMarker = searchResult.find();
            if (!searchResultMarker)
                return null;
            return WI.compareCodeMirrorPositions(current, searchResultMarker.from);
        });

        if (index === null) {
            this._revalidateSearchResults(-1);
            return;
        }

        this._currentSearchResultIndex = index;
        this._revealSearchResult(this._searchResults[this._currentSearchResultIndex], changeFocus);
    }

    _revealFirstSearchResultAfterCursor(changeFocus)
    {
        console.assert(this._searchResults.length);

        var currentCursorPosition = this._codeMirror.getCursor("start");
        if (currentCursorPosition.line === 0 && currentCursorPosition.ch === 0) {
            this._currentSearchResultIndex = 0;
            this._revealSearchResult(this._searchResults[this._currentSearchResultIndex], changeFocus, 1);
            return;
        }

        var index = this._binarySearchInsertionIndexInSearchResults(currentCursorPosition, function(current, searchResult) {
            var searchResultMarker = searchResult.find();
            if (!searchResultMarker)
                return null;
            return WI.compareCodeMirrorPositions(current, searchResultMarker.from);
        });

        if (index === null) {
            this._revalidateSearchResults(1);
            return;
        }

        if (index + 1 < this._searchResults.length)
            ++index;
        else
            index = 0;

        this._currentSearchResultIndex = index;
        this._revealSearchResult(this._searchResults[this._currentSearchResultIndex], changeFocus);
    }

    _cursorDoesNotMatchLastRevealedSearchResult()
    {
        console.assert(this._currentSearchResultIndex !== -1);
        console.assert(this._searchResults.length);

        var lastRevealedSearchResultMarker = this._searchResults[this._currentSearchResultIndex].find();
        if (!lastRevealedSearchResultMarker)
            return true;

        var currentCursorPosition = this._codeMirror.getCursor("start");
        var lastRevealedSearchResultPosition = lastRevealedSearchResultMarker.from;

        return WI.compareCodeMirrorPositions(currentCursorPosition, lastRevealedSearchResultPosition) !== 0;
    }

    _revalidateSearchResults(direction)
    {
        console.assert(direction !== undefined);

        this._currentSearchResultIndex = -1;

        var updatedSearchResults = [];
        for (var i = 0; i < this._searchResults.length; ++i) {
            if (this._searchResults[i].find())
                updatedSearchResults.push(this._searchResults[i]);
        }

        console.assert(updatedSearchResults.length !== this._searchResults.length);

        this._searchResults = updatedSearchResults;
        this.dispatchEventToListeners(WI.TextEditor.Event.NumberOfSearchResultsDidChange);

        if (this._searchResults.length) {
            if (direction > 0)
                this._revealFirstSearchResultAfterCursor();
            else
                this._revealFirstSearchResultBeforeCursor();
        }
    }

    _clearMultilineExecutionLineHighlights()
    {
        if (this._executionMultilineHandles.length) {
            for (let lineHandle of this._executionMultilineHandles)
                this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.ExecutionLineStyleClassName);
            this._executionMultilineHandles = [];
        }
    }

    _updateExecutionLine()
    {
        this._codeMirror.operation(() => {
            if (this._executionLineHandle) {
                this._codeMirror.removeLineClass(this._executionLineHandle, "wrap", WI.TextEditor.ExecutionLineStyleClassName);
                this._codeMirror.removeLineClass(this._executionLineHandle, "wrap", "primary");
            }

            this._clearMultilineExecutionLineHighlights();

            this._executionLineHandle = !isNaN(this._executionLineNumber) ? this._codeMirror.getLineHandle(this._executionLineNumber) : null;

            if (this._executionLineHandle) {
                this._codeMirror.addLineClass(this._executionLineHandle, "wrap", WI.TextEditor.ExecutionLineStyleClassName);
                this._codeMirror.addLineClass(this._executionLineHandle, "wrap", "primary");
                this._codeMirror.removeLineClass(this._executionLineHandle, "wrap", WI.TextEditor.HighlightedStyleClassName);
            }
        });
    }

    _updateExecutionRangeHighlight()
    {
        if (this._executionRangeHighlightMarker) {
            this._executionRangeHighlightMarker.clear();
            this._executionRangeHighlightMarker = null;
        }

        if (isNaN(this._executionLineNumber))
            return;

        let currentPosition = new WI.SourceCodePosition(this._executionLineNumber, this._executionColumnNumber);

        this._delegate.textEditorExecutionHighlightRange(currentPosition, (range) => {
            let start, end;
            if (!range) {
                // Highlight the rest of the line.
                start = {line: this._executionLineNumber, ch: this._executionColumnNumber};
                end = {line: this._executionLineNumber};
            } else {
                // Highlight the range.
                start = range.startPosition.toCodeMirror();
                end = range.endPosition.toCodeMirror();
            }

            // Ensure the marker is cleared in case there were multiple updates very quickly.
            if (this._executionRangeHighlightMarker) {
                this._executionRangeHighlightMarker.clear();
                this._executionRangeHighlightMarker = null;
            }

            // Avoid highlighting trailing whitespace.
            let text = this._codeMirror.getRange(start, end);
            let trailingWhitespace = text.match(/\s+$/);
            if (trailingWhitespace)
                end.ch = Math.max(0, end.ch - trailingWhitespace[0].length);

            // Give each line containing part of the range the full line style.
            this._clearMultilineExecutionLineHighlights();
            if (start.line !== end.line) {
                for (let line = start.line; line < end.line; ++line) {
                    let lineHandle = this._codeMirror.getLineHandle(line);
                    this._codeMirror.addLineClass(lineHandle, "wrap", WI.TextEditor.ExecutionLineStyleClassName);
                    this._executionMultilineHandles.push(lineHandle);
                }
            }

            this._executionRangeHighlightMarker = this._codeMirror.markText(start, end, {className: "execution-range-highlight"});
        });
    }

    _setBreakpointStylesOnLine(lineNumber)
    {
        var columnBreakpoints = this._breakpoints[lineNumber];
        console.assert(columnBreakpoints);
        if (!columnBreakpoints)
            return;

        var allDisabled = true;
        var allResolved = true;
        var allAutoContinue = true;
        var multiple = Object.keys(columnBreakpoints).length > 1;
        for (var columnNumber in columnBreakpoints) {
            var breakpointInfo = columnBreakpoints[columnNumber];
            if (!breakpointInfo.disabled)
                allDisabled = false;
            if (!breakpointInfo.resolved)
                allResolved = false;
            if (!breakpointInfo.autoContinue)
                allAutoContinue = false;
        }

        allResolved = allResolved && WI.debuggerManager.breakpointsEnabled;

        function updateStyles()
        {
            // We might not have a line if the content isn't fully populated yet.
            // This will be called again when the content is available.
            var lineHandle = this._codeMirror.getLineHandle(lineNumber);
            if (!lineHandle)
                return;

            this._codeMirror.addLineClass(lineHandle, "wrap", WI.TextEditor.HasBreakpointStyleClassName);

            if (allResolved)
                this._codeMirror.addLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointResolvedStyleClassName);
            else
                this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointResolvedStyleClassName);

            if (allDisabled)
                this._codeMirror.addLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointDisabledStyleClassName);
            else
                this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointDisabledStyleClassName);

            if (allAutoContinue)
                this._codeMirror.addLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointAutoContinueStyleClassName);
            else
                this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointAutoContinueStyleClassName);

            if (multiple)
                this._codeMirror.addLineClass(lineHandle, "wrap", WI.TextEditor.MultipleBreakpointsStyleClassName);
            else
                this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.MultipleBreakpointsStyleClassName);
        }

        this._codeMirror.operation(updateStyles.bind(this));
    }

    _addBreakpointToLineAndColumnWithInfo(lineNumber, columnNumber, breakpointInfo)
    {
        if (!this._breakpoints[lineNumber])
            this._breakpoints[lineNumber] = {};
        this._breakpoints[lineNumber][columnNumber] = breakpointInfo;

        this._setBreakpointStylesOnLine(lineNumber);
    }

    _removeBreakpointFromLineAndColumn(lineNumber, columnNumber)
    {
        console.assert(columnNumber in this._breakpoints[lineNumber]);
        delete this._breakpoints[lineNumber][columnNumber];

        // There are still breakpoints on the line. Update the breakpoint style.
        if (!isEmptyObject(this._breakpoints[lineNumber])) {
            this._setBreakpointStylesOnLine(lineNumber);
            return;
        }

        delete this._breakpoints[lineNumber];

        function updateStyles()
        {
            var lineHandle = this._codeMirror.getLineHandle(lineNumber);
            if (!lineHandle)
                return;

            this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.HasBreakpointStyleClassName);
            this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointResolvedStyleClassName);
            this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointDisabledStyleClassName);
            this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.BreakpointAutoContinueStyleClassName);
            this._codeMirror.removeLineClass(lineHandle, "wrap", WI.TextEditor.MultipleBreakpointsStyleClassName);
        }

        this._codeMirror.operation(updateStyles.bind(this));
    }

    _allColumnBreakpointInfoForLine(lineNumber)
    {
        return this._breakpoints[lineNumber];
    }

    _setColumnBreakpointInfoForLine(lineNumber, columnBreakpointInfo)
    {
        console.assert(columnBreakpointInfo);
        this._breakpoints[lineNumber] = columnBreakpointInfo;
        this._setBreakpointStylesOnLine(lineNumber);
    }

    _gutterMouseDown(codeMirror, lineNumber, gutterElement, event)
    {
        if (event.button !== 0 || event.ctrlKey)
            return;

        if (!this._codeMirror.hasLineClass(lineNumber, "wrap", WI.TextEditor.HasBreakpointStyleClassName)) {
            console.assert(!(lineNumber in this._breakpoints));

            // No breakpoint, add a new one.
            if (this._delegate && typeof this._delegate.textEditorBreakpointAdded === "function") {
                var data = this._delegate.textEditorBreakpointAdded(this, lineNumber, 0);
                if (data) {
                    var breakpointInfo = data.breakpointInfo;
                    if (breakpointInfo)
                        this._addBreakpointToLineAndColumnWithInfo(data.lineNumber, data.columnNumber, breakpointInfo);
                }
            }

            return;
        }

        console.assert(lineNumber in this._breakpoints);

        if (this._codeMirror.hasLineClass(lineNumber, "wrap", WI.TextEditor.MultipleBreakpointsStyleClassName)) {
            console.assert(!isEmptyObject(this._breakpoints[lineNumber]));
            return;
        }

        // Single existing breakpoint, start tracking it for dragging.
        console.assert(Object.keys(this._breakpoints[lineNumber]).length === 1);
        var columnNumber = Object.keys(this._breakpoints[lineNumber])[0];
        this._draggingBreakpointInfo = this._breakpoints[lineNumber][columnNumber];
        this._lineNumberWithMousedDownBreakpoint = lineNumber;
        this._lineNumberWithDraggedBreakpoint = lineNumber;
        this._columnNumberWithMousedDownBreakpoint = columnNumber;
        this._columnNumberWithDraggedBreakpoint = columnNumber;

        this._documentMouseMovedEventListener = this._documentMouseMoved.bind(this);
        this._documentMouseUpEventListener = this._documentMouseUp.bind(this);

        // Register these listeners on the document so we can track the mouse if it leaves the gutter.
        document.addEventListener("mousemove", this._documentMouseMovedEventListener, true);
        document.addEventListener("mouseup", this._documentMouseUpEventListener, true);
    }

    _gutterContextMenu(codeMirror, lineNumber, gutterElement, event)
    {
        if (this._delegate && typeof this._delegate.textEditorGutterContextMenu === "function") {
            var breakpoints = [];
            for (var columnNumber in this._breakpoints[lineNumber])
                breakpoints.push({lineNumber, columnNumber});

            this._delegate.textEditorGutterContextMenu(this, lineNumber, 0, breakpoints, event);
        }
    }

    _documentMouseMoved(event)
    {
        console.assert("_lineNumberWithMousedDownBreakpoint" in this);
        if (!("_lineNumberWithMousedDownBreakpoint" in this))
            return;

        event.preventDefault();

        var lineNumber;
        var position = this._codeMirror.coordsChar({left: event.pageX, top: event.pageY});

        // CodeMirror's coordsChar returns a position even if it is outside the bounds. Nullify the position
        // if the event is outside the bounds of the gutter so we will remove the breakpoint.
        var gutterBounds = this._codeMirror.getGutterElement().getBoundingClientRect();
        if (event.pageX < gutterBounds.left || event.pageX > gutterBounds.right || event.pageY < gutterBounds.top || event.pageY > gutterBounds.bottom)
            position = null;

        // If we have a position and it has a line then use it.
        if (position && "line" in position)
            lineNumber = position.line;

        // The _lineNumberWithDraggedBreakpoint property can be undefined if the user drags
        // outside of the gutter. The lineNumber variable can be undefined for the same reason.

        if (lineNumber === this._lineNumberWithDraggedBreakpoint)
            return;

        // Record that the mouse dragged some so when mouse up fires we know to do the
        // work of removing and moving the breakpoint.
        this._mouseDragged = true;

        if ("_lineNumberWithDraggedBreakpoint" in this) {
            // We have a line that is currently showing the dragged breakpoint. Remove that breakpoint
            // and restore the previous one (if any.)
            if (this._previousColumnBreakpointInfo)
                this._setColumnBreakpointInfoForLine(this._lineNumberWithDraggedBreakpoint, this._previousColumnBreakpointInfo);
            else
                this._removeBreakpointFromLineAndColumn(this._lineNumberWithDraggedBreakpoint, this._columnNumberWithDraggedBreakpoint);

            delete this._previousColumnBreakpointInfo;
            delete this._lineNumberWithDraggedBreakpoint;
            delete this._columnNumberWithDraggedBreakpoint;
        }

        if (lineNumber !== undefined) {
            // We have a new line that will now show the dragged breakpoint.
            var newColumnBreakpoints = {};
            var columnNumber = lineNumber === this._lineNumberWithMousedDownBreakpoint ? this._columnNumberWithDraggedBreakpoint : 0;
            newColumnBreakpoints[columnNumber] = this._draggingBreakpointInfo;
            this._previousColumnBreakpointInfo = this._allColumnBreakpointInfoForLine(lineNumber);
            this._setColumnBreakpointInfoForLine(lineNumber, newColumnBreakpoints);
            this._lineNumberWithDraggedBreakpoint = lineNumber;
            this._columnNumberWithDraggedBreakpoint = columnNumber;
        }
    }

    _documentMouseUp(event)
    {
        console.assert("_lineNumberWithMousedDownBreakpoint" in this);
        if (!("_lineNumberWithMousedDownBreakpoint" in this))
            return;

        event.preventDefault();

        document.removeEventListener("mousemove", this._documentMouseMovedEventListener, true);
        document.removeEventListener("mouseup", this._documentMouseUpEventListener, true);

        var delegateImplementsBreakpointClicked = this._delegate && typeof this._delegate.textEditorBreakpointClicked === "function";
        var delegateImplementsBreakpointRemoved = this._delegate && typeof this._delegate.textEditorBreakpointRemoved === "function";
        var delegateImplementsBreakpointMoved = this._delegate && typeof this._delegate.textEditorBreakpointMoved === "function";

        if (this._mouseDragged) {
            if (!("_lineNumberWithDraggedBreakpoint" in this)) {
                // The breakpoint was dragged off the gutter, remove it.
                if (delegateImplementsBreakpointRemoved) {
                    this._ignoreSetBreakpointInfoCalls = true;
                    this._delegate.textEditorBreakpointRemoved(this, this._lineNumberWithMousedDownBreakpoint, this._columnNumberWithMousedDownBreakpoint);
                    delete this._ignoreSetBreakpointInfoCalls;
                }
            } else if (this._lineNumberWithMousedDownBreakpoint !== this._lineNumberWithDraggedBreakpoint) {
                // The dragged breakpoint was moved to a new line.

                // If there is are breakpoints already at the drop line, tell the delegate to remove them.
                // We have already updated the breakpoint info internally, so when the delegate removes the breakpoints
                // and tells us to clear the breakpoint info, we can ignore those calls.
                if (this._previousColumnBreakpointInfo && delegateImplementsBreakpointRemoved) {
                    this._ignoreSetBreakpointInfoCalls = true;
                    for (var columnNumber in this._previousColumnBreakpointInfo)
                        this._delegate.textEditorBreakpointRemoved(this, this._lineNumberWithDraggedBreakpoint, columnNumber);
                    delete this._ignoreSetBreakpointInfoCalls;
                }

                // Tell the delegate to move the breakpoint from one line to another.
                if (delegateImplementsBreakpointMoved) {
                    this._ignoreSetBreakpointInfoCalls = true;
                    this._delegate.textEditorBreakpointMoved(this, this._lineNumberWithMousedDownBreakpoint, this._columnNumberWithMousedDownBreakpoint, this._lineNumberWithDraggedBreakpoint, this._columnNumberWithDraggedBreakpoint);
                    delete this._ignoreSetBreakpointInfoCalls;
                }
            }
        } else {
            // Toggle the disabled state of the breakpoint.
            console.assert(this._lineNumberWithMousedDownBreakpoint in this._breakpoints);
            console.assert(this._columnNumberWithMousedDownBreakpoint in this._breakpoints[this._lineNumberWithMousedDownBreakpoint]);
            if (this._lineNumberWithMousedDownBreakpoint in this._breakpoints && this._columnNumberWithMousedDownBreakpoint in this._breakpoints[this._lineNumberWithMousedDownBreakpoint] && delegateImplementsBreakpointClicked)
                this._delegate.textEditorBreakpointClicked(this, this._lineNumberWithMousedDownBreakpoint, this._columnNumberWithMousedDownBreakpoint);
        }

        delete this._documentMouseMovedEventListener;
        delete this._documentMouseUpEventListener;
        delete this._lineNumberWithMousedDownBreakpoint;
        delete this._lineNumberWithDraggedBreakpoint;
        delete this._columnNumberWithMousedDownBreakpoint;
        delete this._columnNumberWithDraggedBreakpoint;
        delete this._previousColumnBreakpointInfo;
        delete this._mouseDragged;
    }

    _openClickedLinks(event)
    {
        if (!this.readOnly && !event.commandOrControlKey)
            return;

        // Get the position in the text and the token at that position.
        var position = this._codeMirror.coordsChar({left: event.pageX, top: event.pageY});
        var tokenInfo = this._codeMirror.getTokenAt(position);
        if (!tokenInfo || !tokenInfo.type || !tokenInfo.string)
            return;

        // If the token is not a link, then ignore it.
        if (!/\blink\b/.test(tokenInfo.type))
            return;

        // The token string is the URL we should open. It might be a relative URL.
        var url = tokenInfo.string;

        // Get the base URL.
        var baseURL = "";
        if (this._delegate && typeof this._delegate.textEditorBaseURL === "function")
            baseURL = this._delegate.textEditorBaseURL(this);

        // Open the link after resolving the absolute URL from the base URL.
        WI.openURL(absoluteURL(url, baseURL));

        // Stop processing the event.
        event.preventDefault();
        event.stopPropagation();
    }

    _isPositionVisible(position)
    {
        var scrollInfo = this._codeMirror.getScrollInfo();
        var visibleRangeStart = scrollInfo.top;
        var visibleRangeEnd = visibleRangeStart + scrollInfo.clientHeight;
        var coords = this._codeMirror.charCoords(position, "local");

        return coords.top >= visibleRangeStart && coords.bottom <= visibleRangeEnd;
    }

    _scrollIntoViewCentered(position)
    {
        var scrollInfo = this._codeMirror.getScrollInfo();
        var lineHeight = Math.ceil(this._codeMirror.defaultTextHeight());
        var margin = Math.floor((scrollInfo.clientHeight - lineHeight) / 2);
        this._codeMirror.scrollIntoView(position, margin);
    }
};

WI.TextEditor.HighlightedStyleClassName = "highlighted";
WI.TextEditor.SearchResultStyleClassName = "search-result";
WI.TextEditor.HasBreakpointStyleClassName = "has-breakpoint";
WI.TextEditor.BreakpointResolvedStyleClassName = "breakpoint-resolved";
WI.TextEditor.BreakpointAutoContinueStyleClassName = "breakpoint-auto-continue";
WI.TextEditor.BreakpointDisabledStyleClassName = "breakpoint-disabled";
WI.TextEditor.MultipleBreakpointsStyleClassName = "multiple-breakpoints";
WI.TextEditor.ExecutionLineStyleClassName = "execution-line";
WI.TextEditor.BouncyHighlightStyleClassName = "bouncy-highlight";
WI.TextEditor.NumberOfFindsPerSearchBatch = 10;
WI.TextEditor.HighlightAnimationDuration = 2000;

WI.TextEditor.Event = {
    Focused: "text-editor-focused",
    ExecutionLineNumberDidChange: "text-editor-execution-line-number-did-change",
    NumberOfSearchResultsDidChange: "text-editor-number-of-search-results-did-change",
    ContentDidChange: "text-editor-content-did-change",
    FormattingDidChange: "text-editor-formatting-did-change",
    MIMETypeChanged: "text-editor-mime-type-changed",
};
