'use strict';

var fs   = require('fs');
var path = require('path');
var util = require('util');
var _    = require('lodash');

var Blender = module.exports = function() {
  this._methods = [];
  this._flavors = [];
  this.generator = {
    'initializing' : {},
    'prompting'    : {},
    'configuring'  : {},
    'default'      : {},
    'writing'      : {},
    'install'      : {},
    'end'          : {}
  };
};

Blender.prototype.blend = function() {
  this._mergeMethods();
  this._mergeFlavors();
  return this.generator;
};

Blender.prototype.methods = function(methods) {
  this._methods = methods;
  this._checkMethods();
};

Blender.prototype.flavors = function(flavors) {
  this._flavors = flavors;
  this._checkFlavors();
};

Blender.prototype._checkMethods = function() {
  if (!_.isArray(this._methods)) this._methods = [this._methods];
  this._methods.forEach(function(mixin) {
    if (!_.isPlainObject(mixin)) throw new Error(util.format('%j must be a plain object', mixin));
  }, this);
};

Blender.prototype._checkFlavors = function() {
  if (!_.isArray(this._flavors)) this._flavors = [this._flavors];
  this._flavors.forEach(function(flavor) {
    if (!fs.existsSync(path.resolve(flavor))) {
      throw new Error(util.format('Flavor directory "%s" does not exists.', flavor));
    }
  }, this);
};

Blender.prototype._mergeMethods = function() {
  this._methods.forEach(function(mixin) {
    _.merge(this.generator, mixin);
  }, this);
};

Blender.prototype._mergeFlavors = function() {
  Object.keys(this.generator).forEach(function(queue) {
    this._flavors.forEach(function(flavor) {
      var file = path.join(path.resolve(flavor), util.format('%s.js', queue));
      if (fs.existsSync(file)) _.merge(this.generator[queue], require(file));
    }, this);
  }, this);
};

@@ -125,22 +125,8 @@
 );%0A%0A
-var Blender = 
 modu
@@ -134,32 +134,50 @@
 e.exports = 
-function
+Blender;%0A%0Afunction Blender
 () %7B%0A  this.
@@ -414,19 +414,30 @@
 %7D%0A  %7D;%0A%7D
-;
 %0A%0A
+var proto = 
 Blender.
@@ -445,16 +445,24 @@
 rototype
+;%0A%0Aproto
 .blend =
@@ -552,33 +552,21 @@
 or;%0A%7D;%0A%0A
-Blender.
 proto
-type
 .methods
@@ -643,33 +643,21 @@
 ();%0A%7D;%0A%0A
-Blender.
 proto
-type
 .flavors
@@ -734,33 +734,21 @@
 ();%0A%7D;%0A%0A
-Blender.
 proto
-type
 ._checkM
@@ -992,33 +992,21 @@
 s);%0A%7D;%0A%0A
-Blender.
 proto
-type
 ._checkF
@@ -1292,33 +1292,21 @@
 s);%0A%7D;%0A%0A
-Blender.
 proto
-type
 ._mergeM
@@ -1421,33 +1421,21 @@
 s);%0A%7D;%0A%0A
-Blender.
 proto
-type
 ._mergeF

Remove redundant code.