"use strict";

var Rule = function() {
  if (this instanceof Rule) {
    this.association = null;
    this.errors = [];
    this.ifInvalidThenFunction = null;
    this.ifValidThenFunction = null;
    this.successors = [];
    this.valid = true;
  } else {
    return new Rule(); 
  }
};

Rule.prototype = {

  constructor: Rule,

  __invalidate: function(errors) {
    var self = this;
    this.valid = false;
    if (!Array.isArray(errors)) {
      errors = [errors];
    }
    errors.forEach(function(err) {
      if (typeof err === "string") {
        self.errors.push({ association: self.association, error: err });
      } else {
        self.errors.push(err);
      }
    });
  },

  __onValidate: function(done) {
  },

  validate: function(done) {
    var self = this;

    this.__onValidate(function() {
      if (self.valid) {
        if (self.ifValidThenFunction) {
          self.ifValidThenFunction();
        }
        if (self.successors.length > 0) {
          var counter = self.successors.length;

          self.successors.forEach(function(rule) {
            rule.validate(onRuleValidated);

            function onRuleValidated() {
              if (!rule.valid) {
                self.__invalidate(rule.errors);
              }
              counter--;
              if (counter === 0) {
                onValidationsComplete();
              }
            }
          });

          function onValidationsComplete() {
            done();
          }
          return;
        }
      } else {
        if (self.ifInvalidThenFunction) {
          self.ifInvalidThenFunction();
        }
      }
      done();
    });
  },

  ifValidThenValidate: function(rules) {
    if (!Array.isArray(rules)) {
      rules = [rules]
    }
    this.successors = rules;
    return this;
  },

  ifValidThenExecute: function(funcToExecute) {
    this.ifValidThenFunction = funcToExecute;
    return this;
  },

  ifInvalidThenExecute: function(funcToExecute) {
    this.ifInvalidThenFunction = funcToExecute;
    return this;
  }

};

module.exports = Rule;

@@ -8,16 +8,67 @@
 rict%22;%0A%0A
+var RulesValidator = require('./rulesValidator');%0A%0A
 var Rule
@@ -1025,47 +1025,68 @@
     
-var counter = self.successors.length;%0A%0A
+new RulesValidator(self.successors).validate(function() %7B%0A  
     
@@ -1104,30 +1104,29 @@
 successors.f
-orEach
+ilter
 (function(ru
@@ -1134,54 +1134,37 @@
 e) %7B
-%0A            rule.validate(onRuleV
+ return !rule.v
 alid
-ated);%0A%0A
+; %7D)%0A     
     
@@ -1175,70 +1175,57 @@
     
-function onRuleValidated() %7B%0A              if (!rule.valid) %7B%0A
+          .forEach(function(rule) %7B%0A             
     
@@ -1274,34 +1274,32 @@
 ;%0A              
-%7D%0A
               co
@@ -1299,185 +1299,12 @@
     
- counter--;%0A              if (counter === 0) %7B%0A                onValidationsComplete();%0A              %7D%0A            %7D%0A          %7D);%0A%0A          function onValidationsComplete() %7B
+%7D);%0A
 %0A   
@@ -1323,32 +1323,34 @@
 e();%0A          %7D
+);
 %0A          retur

refactor rule.js to consume RuleValidator