var stream = require('stream')
var through = require('through')

module.exports = Bricoleur

function Bricoleur (opts) { 
  if (!opts) opts = {}

  var self = this

  // MODULE SCOPE
  var _ = {}
  _.brico = new stream.Stream
  _.brico.readable = true
  _.brico.writable = true

  // UTILITIES
  function handleMapData (mod) {
    if (!self.moduleMap) self.moduleMap = []
    self.moduleMap.push(mod)
  }

  // HANDLE SOCKET CONNECTIONS
  this.addSocket = function (id) { // send modulemap! & user environment data
    self[id] = new stream.Stream
    self[id].writable = true
    self[id].readable = true
    self[id].pipe(_.brico).pipe(self[id])
    self[id].end = function () {
      console.log(id+' closed')
    }
  }

  // META STREAM INTERFACE
  this.metaStream = through(metaWrite,metaEnd,{autoDestroy:false})
  function metaWrite (chunk) {
    var data = JSON.parse(chunk)
    if (data.process) handleMapData(data) // map data
    if (data.fresh && data.fresh === true) console.log(JSON.parse(chunk)) // update map when module changes
    if (data.host) console.log(data)
  }
  function metaEnd () {
    console.log('map ready')
  }

  // API / COMMANDS
  var api = {
    make: function (mod) {
      var libName = mod.id.toUpperCase()
      var lib = require(libName)
      _[mod.id] = new lib() 
      if (process.browser && mod.html) _[mod.id].render(html)
    },
    unmake: function (mod) {
      _[mod.id].destroy()
    },
    conn: function (conss) { // fix ugliness
      conns.forEach(function handleConnection (conn) {
        if (conn.match(/\+/) !== null) {
          var modA = conn.split('+')[0]
          , modB = conn.split('+')[1]
          _[modA].pipe(_[modB])
        }
        if (conn.match(/\-/) !== null) {
          var modA = conn.split('-')[0]
          , modB = conn.split('-')[1]
          modA.unpipe(modB)
        }
      })
    }
  }
  this.cmd = function (params) {
    var cmd = params[0]
    if (!api[cmd]) console.error('command '+cmd+' unknown')
    if (api[cmd]) api[cmd](params.slice(1))
  }
}

@@ -205,77 +205,111 @@
 o = 
-new stream.Stream%0A  _.brico.readable = true%0A  _.brico.writable = true
+through(function write (chunk) %7B%0A    this.queue(chunk)%0A  %7D, function end () %7B%0A    this.emit('end')%0A  %7D)
 %0A%0A  
@@ -561,144 +561,71 @@
 %5D = 
-new stream.Stream%0A    self%5Bid%5D.writable = true%0A    self%5Bid%5D.readable = true%0A    self%5Bid%5D.pipe(_.brico).pipe(self%5Bid%5D)%0A    self%5Bid%5D.end =
+through(function write (chunk) %7B%0A      this.queue(chunk)%0A    %7D,
  fun
@@ -630,16 +630,20 @@
 unction 
+end 
 () %7B%0A   
@@ -671,25 +671,49 @@
 losed')%0A    
-%7D
+  this.emit('end')%0A    %7D)
 %0A  %7D%0A%0A  // M
@@ -1159,16 +1159,57 @@
 api = %7B%0A
+    loadEnv: function (user,cb) %7B%0A    %7D,%0A
     make
@@ -1215,32 +1215,35 @@
 e: function (mod
+,cb
 ) %7B%0A      var li
@@ -1395,16 +1395,56 @@
 r(html)%0A
+      // verify module creation somehow%0A
     %7D,%0A 
@@ -1463,24 +1463,27 @@
 unction (mod
+,cb
 ) %7B%0A      _%5B
@@ -1532,16 +1532,19 @@
 n (conss
+,cb
 ) %7B // f

fix for memory leak