module.exports = dragDrop

var flatten = require('flatten')
var parallel = require('run-parallel')

function dragDrop (elem, ondrop) {
  if (typeof elem === 'string') elem = window.document.querySelector(elem)

  var onDragOver = makeOnDragOver(elem)
  var onDragLeave = makeOnDragLeave(elem)
  var onDrop = makeOnDrop(elem, ondrop)

  elem.addEventListener('dragenter', stopEvent, false)
  elem.addEventListener('dragover', onDragOver, false)
  elem.addEventListener('dragleave', onDragLeave, false)
  elem.addEventListener('drop', onDrop, false)

  // Function to remove drag-drop listeners
  return function remove () {
    if (elem instanceof window.Element) elem.classList.remove('drag')
    elem.removeEventListener('dragenter', stopEvent, false)
    elem.removeEventListener('dragover', onDragOver, false)
    elem.removeEventListener('dragleave', onDragLeave, false)
    elem.removeEventListener('drop', onDrop, false)
  }
}

function stopEvent (e) {
  e.stopPropagation()
  e.preventDefault()
  return false
}

function makeOnDragOver (elem) {
  return function (e) {
    if (e.target !== elem) return
    e.stopPropagation()
    e.preventDefault()
    if (elem instanceof window.Element) elem.classList.add('drag')
    e.dataTransfer.dropEffect = 'copy'
    return false
  }
}

function makeOnDragLeave (elem) {
  return function (e) {
    if (e.target !== elem) return
    e.stopPropagation()
    e.preventDefault()
    if (elem instanceof window.Element) elem.classList.remove('drag')
    return false
  }
}

function makeOnDrop (elem, ondrop) {
  return function (e) {
    e.stopPropagation()
    e.preventDefault()
    if (elem instanceof window.Element) elem.classList.remove('drag')
    var pos = { x: e.clientX, y: e.clientY }
    if (e.dataTransfer.items) {
      // Handle directories in Chrome using the proprietary FileSystem API
      parallel(toArray(e.dataTransfer.items).map(function (item) {
        return function (cb) {
          processEntry(item.webkitGetAsEntry(), cb)
        }
      }), function (err, results) {
        // There should never be an error in production code. This catches permission
        // errors with file:// in Chrome.
        if (err) throw err
        ondrop(flatten(results), pos)
      })
    } else {
      var files = toArray(e.dataTransfer.files)
      files.forEach(function (file) {
        file.fullPath = '/' + file.name
      })
      ondrop(files, pos)
    }

    return false
  }
}

function processEntry (entry, cb) {
  var entries = []

  if (entry.isFile) {
    entry.file(function (file) {
      file.fullPath = entry.fullPath  // preserve pathing for consumer
      cb(null, file)
    }, function (err) {
      cb(err)
    })
  } else if (entry.isDirectory) {
    var reader = entry.createReader()
    readEntries()
  }

  function readEntries () {
    reader.readEntries(function (entries_) {
      if (entries_.length > 0) {
        entries = entries.concat(toArray(entries_))
        readEntries() // continue reading entries until `readEntries` returns no more
      } else {
        doneEntries()
      }
    })
  }

  function doneEntries () {
    parallel(entries.map(function (entry) {
      return function (cb) {
        processEntry(entry, cb)
      }
    }), cb)
  }
}

function toArray (list) {
  return Array.prototype.slice.call(list || [], 0)
}

@@ -1074,42 +1074,8 @@
 ) %7B%0A
-    if (e.target !== elem) return%0A
     

fix dragenter