var EventEmitter = require('events').EventEmitter

var sublevel = module.exports = function (nut, prefix, createStream) {
  var emitter = new EventEmitter()
  emitter.sublevels = {}
  prefix = prefix || []
  createStream = createStream || function (e) { return e }
  emitter.put = function (key, value, opts, cb) {
    if('function' === typeof opts) cb = opts, opts = {}

    nut.apply([{
      key: key, value: value,
      prefix: prefix.slice(), type: 'put'
    }], opts, function (err) {
      if(err) return cb(err)
      emitter.emit('put', key, value); cb(null)
    })
  }

  emitter.prefix = function () {
    return prefix.slice()
  }

  emitter.del = function (key, opts, cb) {
    if('function' === typeof opts) cb = opts, opts = {}

    nut.apply([{
      key: key,
      prefix: prefix.slice(), type: 'del'
    }], opts, function (err) {
      if(err) return cb(err)
      emitter.emit('del', key); cb(null)
    })
  }

  emitter.batch = function (ops, opts, cb) {
    if('function' === typeof opts)
      cb = opts, opts = {}
    ops = ops.map(function (op) {
      return {
        key:           op.key,
        value:         op.value,
        prefix:        op.prefix || prefix,
        keyEncoding:   op.keyEncoding,    // *
        valueEncoding: op.valueEncoding,  // * (TODO: encodings on sublevel)
      }
    })
    nut.apply(ops, opts, function (err) {
      if(err) return cb(err)
      emitter.emit('batch', ops); cb(null)
    })
  }

  emitter.get = function (key, opts, cb) {
    if('function' === typeof opts) 
      cb = opts, opts = {}
    nut.get(key, prefix, opts, cb)
  }

  emitter.sublevel = function (name) {
    return emitter.sublevels[name] =
      emitter.sublevels[name] || sublevel(nut, prefix.concat(name), createStream)
  }

  emitter.pre = function (key, hook) {
    if('function' === typeof key) return nut.pre([prefix], key)
    if('string'   === typeof key) return nut.pre([prefix, key], hook)
    //TODO: {lt, lte, gt, gte}
    throw new Error('not implemented')
  }

  emitter.post = function (key, hook) {
    if('function' === typeof key) return nut.post([prefix], key)
    if('string'   === typeof key) return nut.post([prefix, key], hook)

    //TODO: handle ranges, needed for level-live-stream, etc.
    throw new Error('not implemented')
  }

  emitter.createReadStream = function (opts) {
    opts = opts || {}
    opts.prefix = prefix
    var stream
    var it = nut.iterator(opts, function (err, it) {
      stream.setIterator(it)
    })
    stream = createStream(opts, nut.createDecoder(opts))
    if(it) stream.setIterator(it)
    return stream
  }

  return emitter
}

@@ -199,16 +199,82 @@
 x %7C%7C %5B%5D%0A
+  function errback (err) %7B if (err) emitter.emit('error', error)%7D%0A
   create
@@ -324,16 +324,16 @@
 urn e %7D%0A
-
   emitte
@@ -421,32 +421,57 @@
  opts, opts = %7B%7D
+%0A    if(!cb) cb = errback
 %0A%0A    nut.apply(
@@ -549,32 +549,38 @@
 ut'%0A    %7D%5D, opts
+ %7C%7C %7B%7D
 , function (err)
@@ -833,16 +833,41 @@
 pts = %7B%7D
+%0A    if(!cb) cb = errback
 %0A%0A    nu
@@ -1151,24 +1151,50 @@
 , opts = %7B%7D%0A
+    if(!cb) cb = errback%0A%0A
     ops = op
@@ -2089,39 +2089,8 @@
 ok)%0A
-    //TODO: %7Blt, lte, gt, gte%7D%0A
     
@@ -2606,24 +2606,25 @@
 (it)%0A    %7D)%0A
+%0A
     stream =
@@ -2668,16 +2668,16 @@
 (opts))%0A
-
     if(i
@@ -2698,24 +2698,25 @@
 terator(it)%0A
+%0A
     return s

handle if there is no callback