 {debounce, isEqual, isEqualForProperties, multiplyString} = require 'underscore-plus'
 {$$} = require 'space-pen'
 
+EditorView = require './editor-view'
+
 DummyLineNode = $$(-> @div className: 'line', style: 'position: absolute; visibility: hidden;', => @span 'x')[0]
 AcceptFilter = {acceptNode: -> NodeFilter.FILTER_ACCEPT}
 


  componentWillMount: ->
    @measuredLines = new WeakSet

  componentDidMount: ->
    @measureLineHeightAndCharWidth()

    false

  componentDidUpdate: (prevProps) ->
    @updateRenderedLines()
    @measureLineHeightAndCharWidth() unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily', 'lineHeight')
    @clearScopedCharWidths() unless isEqualForProperties(prevProps, @props, 'fontSize', 'fontFamily')
    @measureCharactersInNewLines() unless @props.scrollingVertically

  updateRenderedLines: ->
    {editor, visibleRowRange, scrollTop, scrollLeft, lineHeight, showIndentGuide, selectionChanged} = @props
    [startRow, endRow] = visibleRowRange
    verticalScrollOffset = -scrollTop % lineHeight
    horizontalScrollOffset = -scrollLeft

    node = @getDOMNode()

    currentLineIds = new Set
    lines = editor.linesForScreenRows(startRow, endRow - 1)
    for line in lines
      currentLineIds.add(line.id.toString())

    for id, domNode of @lineNodesByLineId
      unless currentLineIds.has(id)
        delete @lineNodesByLineId[id]
        node.removeChild(domNode)

    for line, index in lines
      top = (index * lineHeight) + verticalScrollOffset
      left = horizontalScrollOffset
      screenRow = startRow + index

      if @hasNodeForLine(line.id)
        @updateNodeForLine(line, screenRow, top, left)
      else
        @buildNodeForLine(line, screenRow, top, left)

  hasNodeForLine: (id) ->
    @lineNodesByLineId[id]?

  buildNodeForLine: (tokenizedLine, screenRow, top, left) ->
    {editor} = @props
    {tokens, text, lineEnding, fold, isSoftWrapped, indentLevel} =  tokenizedLine
    if fold
      attributes = {class: 'fold line', 'fold-id': fold.id}
    else
      attributes = {class: 'line'}

    invisibles = {}
    eolInvisibles = {}
    htmlEolInvisibles = []
    indentation = indentLevel

    wrapper = document.createElement('div')
    wrapper.innerHTML = EditorView.buildLineHtml({tokens, text, lineEnding, fold, isSoftWrapped, invisibles, eolInvisibles, htmlEolInvisibles, attributes, indentation, editor})
    lineNode = wrapper.children[0]
    lineNode.style['-webkit-transform'] = "translate3d(#{left}px, #{top}px, 0px)"

    @lineNodesByLineId[tokenizedLine.id] = lineNode
    @getDOMNode().appendChild(lineNode)

  updateNodeForLine: (tokenizedLine, screenRow, top, left) ->
    lineNode = @lineNodesByLineId[tokenizedLine.id]
    lineNode.style['-webkit-transform'] = "translate3d(#{left}px, #{top}px, 0px)"

  measureLineHeightAndCharWidth: ->
    node = @getDOMNode()
