

/**
 * Makes it simple to manage a list of child nodes within a react-hig element
 */
export default class HIGNodeList {
  constructor({ type, HIGConstructor, onAdd }) {
    if (!type) {
      throw new Error('type is required');
    }

    if (!HIGConstructor) {
      throw new Error('HIGConstructor is required');
    }

    if (!onAdd) {
      throw new Error('onInsert is required');
    }

    /**
     * This is the constructor function for the HIGElement
     */
    this.type = type;

    this.listItems = listItems

    this.types = listItems.map( item =>)

    /**
     * This is the constructor function for the hig-vanilla partial
     */
    this.HIGConstructor = HIGConstructor;

    /**
     * This is a function which calls the hig add* method. It takes two hig instances
     */
    this.onAdd = onAdd;

    this.nodes = [];
    this.mounted = false;
  }

  insertBefore(instance, insertBeforeIndex) {
    if (!(instance instanceof this.type)) {
      throw new Error(`unknown type ${instance}`);
    }

    // Update the model
    const beforeChild = this._item(insertBeforeIndex);

    if (beforeChild) {
      this._insertBefore(instance, beforeChild);
    } else {
      this._appendChild(instance);
    }

    if (this.mounted) {
      if (beforeChild) {
        this.onAdd(instance.hig, beforeChild.hig);
        instance.mount();
      } else {
        this.onAdd(instance.hig);
        instance.mount();
      }
    }
  }
  _appendChild(node) {
    this.nodes.push(node);
  }

  _insertBefore(node, beforeNode) {
    const index = this.nodes.indexOf(beforeNode);
    this.nodes.splice(index, 0, node);
  }

  removeChild(node) {
    const index = this.nodes.indexOf(node);
    this.nodes.splice(index, 1);
    node.unmount();
  }

  _item(index) {
    return this.nodes[index];
  }

  componentDidMount() {
    this.nodes.forEach(node => {
      this.onAdd(node.hig);
      node.mount();
    });

    this.mounted = true;
  }

  createElement(ElementConstructor, props) {
    switch (ElementConstructor) {
      case this.type:
        return new this.type(this.HIGConstructor, props);
      default:
        throw new Error(`Unknown type ${ElementConstructor.name}`);
    }
  }

  get length() {
    return this.nodes.length;
  }

  forEach(handler) {
    this.nodes.forEach(handler);
  }

  map(handler) {
    return this.nodes.map(handler);
  }

  find(callback) {
    return this.nodes.find(callback);
  }
}

@@ -134,46 +134,29 @@
 tor(
-%7B type, HIGConstructor, onAdd %7D
+%5BlistItems%5D
 ) %7B%0A   
+ //
  if 
@@ -164,24 +164,27 @@
 !type) %7B%0A   
+ //
    throw new
@@ -210,31 +210,37 @@
 uired');%0A   
+ //
  %7D%0A%0A   
+ //
  if (!HIGCon
@@ -250,24 +250,27 @@
 uctor) %7B%0A   
+ //
    throw new
@@ -306,31 +306,37 @@
 uired');%0A   
+ //
  %7D%0A%0A   
+ //
  if (!onAdd)
@@ -337,24 +337,27 @@
 onAdd) %7B%0A   
+ //
    throw new
@@ -387,24 +387,27 @@
 uired');%0A   
+ //
  %7D%0A%0A    /**%0A
@@ -472,24 +472,27 @@
 %0A     */%0A   
+ //
  this.type =
@@ -566,17 +566,77 @@
 map(
- 
 item =%3E
-)
+ %7B%0A      item.type%0A    %7D);%0A%0A    // this.addFunctions%0A    %0A    
 %0A%0A  
@@ -716,24 +716,27 @@
 %0A     */%0A   
+ //
  this.HIGCon
@@ -864,24 +864,27 @@
 %0A     */%0A   
+ //
  this.onAdd 
@@ -995,47 +995,106 @@
 ) %7B%0A
+%0A
     
-if (!(instance instanceof this.type
+var onAdd = this.listItems.find(instance).onAdd%0A    if (!(this.types.indexOf(instance) === -1
 )) %7B
@@ -1408,37 +1408,32 @@
 hild) %7B%0A        
-this.
 onAdd(instance.h
@@ -1499,29 +1499,24 @@
 e %7B%0A        
-this.
 onAdd(instan
@@ -1992,21 +1992,68 @@
 %7B%0A      
-this.
+const onAdd = this.listItems.find(node).onAdd%0A      
 onAdd(no
@@ -2173,98 +2173,182 @@
     
-switch (ElementConstructor) %7B%0A      case this.type:%0A        return new this.type(this.HIGC
+var type = this.listItems.find(ElementConstructor).type%0A    var constructor = this.listItems.find(ElementConstructor).HIGConstructor;%0A%0A    if (type) %7B%0A      return new type(c
 onst
@@ -2371,20 +2371,17 @@
     
-  default:%0A 
+%7D else %7B%0A
     
@@ -2445,24 +2445,182 @@
 e%7D%60);%0A    %7D%0A
+    // switch (ElementConstructor) %7B%0A    //   case this.type:%0A    //     return new this.type(this.HIGConstructor, props);%0A    //   default:%0A       %0A    // %7D%0A
   %7D%0A%0A  get l

refactor HIGNodeList