var stampit  = require('../object/stampit')
var kindOf   = require('../lang/kindOf')
var flatten  = require('../array/flatten')
var slice    = require('../array/slice')
// var isStream = require('../lang/isStream')
var forEach  = require('../collection/forEach')

module.exports = stampit()
  .methods({
    task: loader,
    run: run,
    exc: execute
  })
  .initializers([
    function () {
      this.tasks = {}
    }
  ])

function run (name) {
  return this.tasks[name] || this.queue[name]
}

function execute (name) {
  var len = this.tasks[name].length
  if (len < 2) return this.tasks[name]()
  var i = -1
  while (++i < len) this.tasks[name][i]()
}

// create task loader
function loader (name, laoders) {
  var args = slice(arguments, 1)

  // get loader stack from cache
  var cached = this.tasks[name] || []

  if (!args.length) return cached

  var stack = buildStack(args, this.tasks).stack
  this.tasks[name] = stack.length < 2 ? stack[0] : flatten(stack)
  return this
}

// private method
function buildStack (args, cache) {
  // args isArray check not needed here. private function. one call made from this.loader()
  // if (!Array.isArray(args)) throw new TypeError('Loaders#buildStack expects an array.')

  var len = args.length
  var i = 0
  var stack = []
  var other = []
  // making this function private therefore I will need to pass the cache in manually
  // as a result the following line is commented out.
  // cache = cache || this.tasks

  while (len--) {
    var arg = args[i++]
    var kind = kindOf(arg)

    if (kind === 'string' && cache[arg]) stack.push(cache[arg])
    else if (kind === 'function') stack.push(arg)
    else if (kind === 'array') stack.push.apply(stack, buildStack(arg, cache).stack)
    // else if (isStream(arg)) stack.push(arg)
    else other.push(arg)
  }

  var res = {}
  res.stack = stack //flatten(stack)
  res.args = other
  return res
}

// function then (fn) {
//   var that = this
//   return function () {
//     return fn(that.apply(null, arguments))
//   }
// }

// function runner (arr) {
//   var len = arr.length
//   var i = 0
//   while (len--) {
//     this.tasks[name][i++](arr)
//     obj[prop](arr[i++])
//   }
// }


@@ -41,22 +41,70 @@
 t')%0Avar 
-kindOf
+forEach  = require('../collection/forEach')%0Avar slice 
    = req
@@ -116,19 +116,19 @@
 '../
-lang/kindOf
+array/slice
 ')%0Av
@@ -169,30 +169,30 @@
 atten')%0Avar 
-slice 
+kindOf
    = require
@@ -196,27 +196,27 @@
 ire('../
-array/slice
+lang/kindOf
 ')%0A// va
@@ -259,56 +259,34 @@
 am')
-%0Avar forEach  = require('../collection/forEach')
+ // not using Streams yet.
 %0A%0Amo
@@ -1154,16 +1154,56 @@
 oader()%0A
+  // the following in is commented out.%0A
   // if 
@@ -1360,24 +1360,23 @@
  %5B%5D%0A
+%0A
   // 
-making this
+this is a
  fun
@@ -1798,16 +1798,51 @@
 .stack)%0A
+    // -- not using Streams yet...%0A
     // e
@@ -1948,25 +1948,8 @@
 tack
- //flatten(stack)
 %0A  r
@@ -1983,298 +1983,4 @@
 s%0A%7D%0A
-%0A// function then (fn) %7B%0A//   var that = this%0A//   return function () %7B%0A//     return fn(that.apply(null, arguments))%0A//   %7D%0A// %7D%0A%0A// function runner (arr) %7B%0A//   var len = arr.length%0A//   var i = 0%0A//   while (len--) %7B%0A//     this.tasks%5Bname%5D%5Bi++%5D(arr)%0A//     obj%5Bprop%5D(arr%5Bi++%5D)%0A//   %7D%0A// %7D%0A%0A

update cache/loader -- minor edits