const ItemRange = require('./codemirror-range-objects').ItemRange
const ItemLocation = require('./codemirror-range-objects').ItemLocation
const SetUtilites = require('./codemirror-range-set-utilities')
const markupItemsForLineTokens = require('./codemirror-range-determination').markupItemsForLineTokens

const getItemRangeFromSelection = (codeMirror) => {
  const fromCursor = codeMirror.getCursor('from')
  const toCursor = codeMirror.getCursor('to')
  const fromLocation = new ItemLocation(fromCursor.line, fromCursor.ch)
  const toLocation = new ItemLocation(toCursor.line, toCursor.ch)
  const selectionRange = new ItemRange(fromLocation, toLocation)
  return selectionRange
}

const getMarkupItemsIntersectingSelection = (codeMirror) => {
  const selectionRange = getItemRangeFromSelection(codeMirror)

  const line = codeMirror.getCursor().line
  const lineTokens = codeMirror.getLineTokens(line, true)
  const markupItems = markupItemsForLineTokens(lineTokens, line)
  
  const markupItemsIntersectingSelection = markupItems.filter(item => item.outerRange.intersectsRange(selectionRange))  
  
  return markupItemsIntersectingSelection
}

const getButtonNamesIntersectingSelection = (codeMirror) => getMarkupItemsIntersectingSelection(codeMirror).map(item => item.buttonName)

/*
TODO: add generic (non-regex or otherwise string aware) functional methods here for: 
- unwrapping existing markup item (i.e. turning off something like bold)
    would simply look at the item's inner and outer range and replace the code mirror string from the
    outer range with the code mirror string from the inner range,
- others t.b.d. - need to think a bit more about best way to implement wrapping related method(s)
*/

exports.getItemRangeFromSelection = getItemRangeFromSelection
exports.getButtonNamesIntersectingSelection = getButtonNamesIntersectingSelection
@@ -134,174 +134,8 @@
 tion
-%0Aconst SetUtilites = require('./codemirror-range-set-utilities')%0Aconst markupItemsForLineTokens = require('./codemirror-range-determination').markupItemsForLineTokens
 %0A%0Aco
@@ -565,30 +565,30 @@
 deMirror
-) =%3E %7B%0A  const
+, markupItems,
  selecti
@@ -598,227 +598,245 @@
 ange
+)
  =
- getItemRangeFromSelection(codeMirror)%0A%0A  const line = codeMirror.getCursor().line%0A  const lineTokens = codeMirror.getLineTokens(line, true)%0A  const markupI
+%3E %7B%0A  const itemIntersectsSelection = item =%3E item.outerRange.intersectsRange(selectionRange, true)%0A  const itemDoesNotStartsAtSelectionEnd = i
 tem
-s
  =
- markupItemsForLineTokens(lineTokens, line
+%3E !item.openingMarkupRange().startLocation.equals(selectionRange.endLocation
 )%0A
-  %0A
   const 
 mark
@@ -835,70 +835,49 @@
 nst 
-markupItemsIntersectingSelection = markupItems.filter(
+itemDoesNotEndAtSelectionStart = 
 item =%3E 
 item
@@ -876,61 +876,83 @@
  =%3E 
+!
 item.
-outerRange.intersectsRange(selectionRange))  %0A  
+closingMarkupRange().endLocation.equals(selectionRange.startLocation)
 %0A  r
@@ -960,32 +960,49 @@
 turn markupItems
+%0A    .filter(item
 IntersectingSele
@@ -986,35 +986,33 @@
 er(itemIntersect
-ing
+s
 Selection%0A%7D%0A%0Acon
@@ -1008,119 +1008,168 @@
 tion
-%0A%7D%0A%0Aconst getButtonNamesIntersectingSelection = (codeMirror) =%3E getMarkupItemsIntersectingSelection(codeMirror)
+)%0A    .filter(itemDoesNotStartsAtSelectionEnd)%0A    .filter(itemDoesNotEndAtSelectionStart)%0A%7D%0A%0Aconst getButtonNamesFromMarkupItems = (markupItems) =%3E markupItems
 .map
@@ -1700,26 +1700,26 @@
 orts.get
-ButtonName
+MarkupItem
 sInterse
@@ -1738,26 +1738,26 @@
 on = get
-ButtonName
+MarkupItem
 sInterse
@@ -1750,28 +1750,99 @@
 upItemsIntersectingSelection
+%0Aexports.getButtonNamesFromMarkupItems = getButtonNamesFromMarkupItems%0A

update method for getting markup items for selection range