 module.exports =
 class AutoIndent
   constructor: (@editor) ->
-    # monkey patch the text @editor method autoIndentBufferRow
-    # to get avoid the limitations of the increaseIndentPattern and decreaseIndentPattern
-    # regex's
-    # Actually, we patch the method in editor.languageMode as atom
-    # doesn't always use the text @editor's stub method
-    @atomAutoIndentBufferRow =
-      @editor.languageMode.autoIndentBufferRow
-    @editor.languageMode.autoIndentBufferRow =
-      @autoIndentBufferRow
-    #default options
+    # Eslint rules to use as default overidden by .eslintrc
+    # N.B. that this is not the same as the eslint rules in that
+    # the tab-spaces and 'tab's in eslintrc are converted to tabs based upon
+    # the Atom editor tab spacing.
+    # e.g. eslint indent [1,4] with an Atom tab spacing of 2 becomes indent [1,3]
     @eslintIndentOptions  =
       jsxClosingBracketLocation: [
         1,

                hardTabsFound += ((line.substr i, 1) is '\t')
              hardTabsFound

          if isFirstTagOfLine
            if row is range.start.row
              # line may start with something like return ( <jsx>
              # but we will treat this as the firstTagInLineIndentation
              firstTagInLineIndentation = firstCharIndentation
            else firstTagInLineIndentation = tagIndentation

          # capture group determines a tag to push onto stack
          if match[1]? # tags starting <tag
            if isFirstTagOfLine and indentRecalc
              stackOfTagsStillOpen.push parentTagIdx = stackOfTagsStillOpen.pop()
              if parentTagIdx?
                @indentRow(row, tagStack[parentTagIdx].firstTagInLineIndentation, 1 )
                line = @editor.lineTextForBufferRow row
                JSXREGEXP.test('') #force regex to start again
                indentRecalc = false
                continue

            stackOfTagsStillOpen.push parentTagIdx = stackOfTagsStillOpen.pop()
            if isFirstTagOfLine
              isFirstTagOfLine = false

            tagStack.push
              type: JSXTAG_OPEN
              name: match[2]
              tagDepth: stackOfTagsStillOpen.length
              row: row
              firstTagInLineIndentation: firstTagInLineIndentation
              tagIndentation: tagIndentation
              firstCharIndentation: firstCharIndentation
              parentTagIdx: parentTagIdx
              termsThisTagsAttributesIdx: null  # ptr to > tag
              termsThisTagIdx: null             # ptr to </tag>

            stackOfTagsStillOpen.push idxOfTags
            idxOfTags++

          else if match[4]? # tags ending </tag>
            if isFirstTagOfLine and indentRecalc
              stackOfTagsStillOpen.push parentTagIdx = stackOfTagsStillOpen.pop()
              @indentRow(row, tagStack[parentTagIdx].firstTagInLineIndentation )
              line = @editor.lineTextForBufferRow row
              JSXREGEXP.test('') #force regex to start again
              indentRecalc = false
              continue

            if isFirstTagOfLine
              isFirstTagOfLine = false

            parentTagIdx = stackOfTagsStillOpen.pop()
            tagStack.push
              type: JSXTAG_CLOSE
              name: match[5]
              row: row
              tagDepth: stackOfTagsStillOpen.length
              parentTagIdx: parentTagIdx         # ptr to <tag
            if parentTagIdx >=0 then tagStack[parentTagIdx].termsThisTagIdx = idxOfTags
            idxOfTags++

          else if match[3]? # tags ending />
            if isFirstTagOfLine and indentRecalc
              stackOfTagsStillOpen.push parentTagIdx = stackOfTagsStillOpen.pop()
              if firstTagInLineIndentation is firstCharIndentation
                @indentForClosingBracket  row,
                  tagStack[parentTagIdx],
                  @eslintIndentOptions.jsxClosingBracketLocation[1].selfClosing
              else
                @indentRow  row,
                  tagStack[parentTagIdx].firstTagInLineIndentation,0,1
              line = @editor.lineTextForBufferRow row
              JSXREGEXP.test('') #force regex to start again
              indentRecalc = false
              continue

            if isFirstTagOfLine
              isFirstTagOfLine = false
            parentTagIdx = stackOfTagsStillOpen.pop()

            tagStack.push
              type: JSXTAG_SELFCLOSE_END
              name: tagStack[parentTagIdx].name
              row: row
              tagDepth: stackOfTagsStillOpen.length
              parentTagIdx: parentTagIdx       # ptr to <tag
            if parentTagIdx >= 0
              tagStack[parentTagIdx].termsThisTagsAttributesIdx = idxOfTags
              tagStack[parentTagIdx].type = JSXTAG_SELFCLOSE_START
              tagStack[parentTagIdx].termsThisTagIdx = idxOfTags
            idxOfTags++


          else if match[7]? # tags ending >
            if isFirstTagOfLine and indentRecalc
              stackOfTagsStillOpen.push parentTagIdx = stackOfTagsStillOpen.pop()
              if firstTagInLineIndentation is firstCharIndentation
                @indentForClosingBracket  row,
                  tagStack[parentTagIdx],
                  @eslintIndentOptions.jsxClosingBracketLocation[1].nonEmpty
              else
                @indentRow  row,
                  tagStack[parentTagIdx].firstTagInLineIndentation,0,1
              line = @editor.lineTextForBufferRow row
              JSXREGEXP.test('') #force regex to start again
              indentRecalc = false
              continue

            if isFirstTagOfLine
              isFirstTagOfLine = false

            stackOfTagsStillOpen.push parentTagIdx = stackOfTagsStillOpen.pop()
            tagStack.push
              type: JSXTAG_CLOSE_ATTRS
              name: tagStack[parentTagIdx].name
              row: row
              tagDepth: stackOfTagsStillOpen.length
              parentTagIdx: parentTagIdx            # ptr to <tag
            if parentTagIdx >= 0 then tagStack[parentTagIdx].termsThisTagsAttributesIdx = idxOfTags
            idxOfTags++

      if idxOfTags > 0 and not tagOnThisLine and  row isnt range.end.row
        if tagStack[idxOfTags-1].type is JSXTAG_CLOSE_ATTRS or
          tagStack[idxOfTags-1].type is JSXTAG_CLOSE or
          tagStack[idxOfTags-1].type is JSXTAG_SELFCLOSE_END
            @indentRow  row, previousLineIndent
        if tagStack[idxOfTags-1].type is JSXTAG_OPEN
            @indentRow  row,
              tagStack[idxOfTags-1].firstTagInLineIndentation,0,1

      previousLineIndent = @editor.indentationForBufferRow row
      if row is range.end.row - 1 # the row that was inserted
        indent =  @editor.indentationForBufferRow row # will be returned
    indent


  # allign nonEmpty and selfClosing tags based on eslint rules
  # row to be indented based upon a parentTags properties and a rule type

      ]
      jsxIndent: [1,1]            # 1 = enabled, 1=#tabs
      jsxIndentProps: [1,1]       # 1 = enabled, 1=#tabs
      indent: [1,1]               # 1 = enabled, 1=#tabs

    @autoJsx = true
    @mouseUp = true

    @disposables = new CompositeDisposable()
    @disposables.add atom.commands.add 'atom-text-editor',
      'language-babel:auto-indent-react-jsx': (event) => @autoIndentJsxCommand()
    @disposables.add atom.commands.add 'atom-text-editor',
      'language-babel:toggle-auto-indent-jsx': (event) =>  @autoJsx = not @autoJsx

    document.addEventListener 'mousedown', => @mouseUp = false
    document.addEventListener 'mouseup', => @mouseUp = true

    @disposables.add @editor.onDidChangeCursorPosition (event) => @changedCursorPosition(event)

    @atomTabLength = @editor.getTabLength()

    if @eslintrcFilename = @getEslintrcFilename()
