'use strict';

const Q = require('q');
const ptr = require('path-to-regexp');

class MenuElement {
  constructor(name, ref, order, active) {
    this.name = name || 'Untitled';
    this.ref = ref || '#';
    this.order = order !== undefined ? order : -1;
    this.active = active || false;
  }
}

class Menu {
  constructor(name) {
    this.name = name;
    this.elements = [];
    this.fn = null;
    this.rendered = null;
  }

  addElement(name, ref, order, active) {
    this.elements.push({
      name: name,
      ref: ref,
      order: order
    });
  }

  render(cleverCore, req, cb, hash) {

    const waitersPromise = [];

    if(!cleverCore.resolve) {
      console.log(hash)
      console.log(cleverCore)
    }

    function generateElement(el, index) {
      const menuEl = new Menu.MenuElement(el.name, el.ref, el.order);
      const defer = Q.defer();
      waitersPromise.push(defer.promise);
      if(typeof menuEl.ref === 'function') {
        menuEl.ref(cleverCore, req, defer, menuEl);
        defer.resolve();
      } else {
        menuEl.active = ptr(req.route.path).test(menuEl.ref);
        defer.resolve();
      }
      return menuEl;
    }

    // Caching the rendered
    if(this.rendered) return cb(null, this.rendered);

    const self = this;

    self.rendered = {};
    self.rendered.name = self.name;

    const fnElements = [];

    self.elements.forEach(function (el, index) {
      fnElements.push(generateElement(el, index));
    });

    if(self.fn) {
      const defer = Q.defer();
      waitersPromise.push(defer.promise);
      self.fn(cleverCore, function(err, rawElements) {
        if(err) return defer.reject(err);
        rawElements.forEach(function (el, index) {
          fnElements.push(generateElement(el, index));
        });
        defer.resolve();
      });
    }

    Q.all(waitersPromise).done(function() {
      self.rendered.elements = fnElements;
      cb(null, self.rendered);
    }, function(err) {
      cb(err);
    });
  }

  deleteCache() {
    this.rendered = null;
  }

}

Menu.MenuElement = MenuElement;

module.exports = Menu;

@@ -115,32 +115,37 @@
 ame, ref, order,
+ sub,
  active) %7B%0A    t
@@ -253,16 +253,77 @@
 r : -1;%0A
+    this.sub = sub %7C%7C null; // if submenu, assign a function%0A
     this
@@ -519,22 +519,19 @@
  order, 
-active
+sub
 ) %7B%0A    
@@ -603,16 +603,40 @@
 r: order
+,%0A      sub: sub %7C%7C null
 %0A    %7D);
@@ -912,16 +912,24 @@
 el.order
+, el.sub
 );%0A     
@@ -1019,19 +1019,19 @@
  menuEl.
-ref
+sub
  === 'fu
@@ -1056,19 +1056,19 @@
  menuEl.
-ref
+sub
 (cleverC
@@ -1103,44 +1103,10 @@
     
-  defer.resolve();%0A      %7D else %7B%0A  
+%7D%0A
     
@@ -1159,34 +1159,32 @@
 uEl.ref);%0A      
-  
 defer.resolve();
@@ -1184,24 +1184,16 @@
 olve();%0A
-      %7D%0A
       re

active submenu