// @flow weak

import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import dataUpdate from '../core/dataUpdate';
import withTransitions from '../core/withTransitions';
import defaultKeyAccessor from '../core/defaultKeyAccessor';

export const propTypes = {
  /**
   * An array of data objects.
   */
  data: PropTypes.array.isRequired,
  /**
   * The CSS class name of the root g element.
   */
  className: PropTypes.string,
  /**
   * The function that returns a string key given a data object.
   */
  keyAccessor: PropTypes.func,
  /**
   * The component that will be used to render each node.
   */
  nodeComponent: PropTypes.func.isRequired,
};

export default class NodeGroup extends PureComponent {
  static propTypes = propTypes;

  static defaultProps = {
    keyAccessor: defaultKeyAccessor,
  };

  constructor(props) {
    super(props);

    (this:any).removeUDID = this.removeUDID.bind(this);
    this.WrappedComponent = withTransitions(props.nodeComponent);
  }

  state = {
    nodes: [],
    udids: {},
  }

  componentDidMount() {
    this.updateNodes(this.props);
  }

  componentWillReceiveProps(next) {
    if (this.props.data !== next.data) {
      this.updateNodes(next);
    }
  }

  WrappedComponent = null;
  removed = new Map();

  updateNodes(props) {
    this.setState((prevState) => {
      return dataUpdate(props, prevState, this.removed);
    });
  }

  removeUDID(udid) {
    this.removed.set(udid, true);
  }

  render() {
    const { props: { keyAccessor, className }, WrappedComponent, state } = this;

    const props = Object.assign({}, this.props);

    Object.keys(propTypes).forEach((prop) => {
      delete props[prop];
    });

    return (
      <g className={className}>
        {state.nodes.map((node, index) => {
          const udid = keyAccessor(node);
          const type = state.udids[udid];

          return (
            <WrappedComponent
              key={udid}
              udid={udid}
              type={type}
              node={node}
              index={index}
              removeUDID={this.removeUDID}
              {...props}
            />
          );
        })}
      </g>
    );
  }
}

@@ -400,17 +400,25 @@
 he root 
-g
+container
  element
@@ -562,32 +562,129 @@
 pes.func,%0A  /**%0A
+   * The wrapping component nodes will be rendered into.%0A   */%0A  component: PropTypes.any,%0A  /**%0A
    * The compone
@@ -889,24 +889,73 @@
 ltProps = %7B%0A
+    className: 'node-group',%0A    component: 'g',%0A
     keyAcces
@@ -1655,36 +1655,8 @@
 rops
-: %7B keyAccessor, className %7D
 , Wr
@@ -1687,17 +1687,16 @@
 = this;%0A
-%0A
     cons
@@ -1697,17 +1697,22 @@
   const 
-p
+childP
 rops = O
@@ -1728,21 +1728,16 @@
 ign(%7B%7D, 
-this.
 props);%0A
@@ -1797,17 +1797,22 @@
  delete 
-p
+childP
 rops%5Bpro
@@ -1839,18 +1839,59 @@
 urn 
-(%0A      %3Cg
+React.createElement(%0A      props.component,%0A      %7B
  cla
@@ -1896,18 +1896,24 @@
 lassName
-=%7B
+: props.
 classNam
@@ -1917,20 +1917,18 @@
 Name
-%7D%3E
+ %7D,
 %0A      
-  %7B
 stat
@@ -1962,26 +1962,24 @@
 %3E %7B%0A        
-  
 const udid =
@@ -1979,16 +1979,22 @@
  udid = 
+props.
 keyAcces
@@ -2004,18 +2004,16 @@
 (node);%0A
-  
         
@@ -2049,26 +2049,24 @@
 %5D;%0A%0A        
- 
- 
 return (%0A   
@@ -2062,18 +2062,16 @@
 eturn (%0A
-  
         
@@ -2102,18 +2102,16 @@
         
- 
- 
 key=%7Budi
@@ -2105,34 +2105,32 @@
      key=%7Budid%7D%0A
-  
             udid
@@ -2149,18 +2149,16 @@
         
- 
- 
 type=%7Bty
@@ -2161,18 +2161,16 @@
 =%7Btype%7D%0A
-  
         
@@ -2197,18 +2197,16 @@
         
- 
- 
 index=%7Bi
@@ -2209,24 +2209,102 @@
 x=%7Bindex%7D%0A  
+          prevScale=%7Bstate.prevScale%7D%0A            currScale=%7Bstate.currScale%7D%0A
             
@@ -2348,23 +2348,24 @@
     
-  
 %7B...
-p
+childP
 rops%7D%0A
-  
     
@@ -2381,18 +2381,16 @@
         
-  
 );%0A     
@@ -2394,24 +2394,11 @@
     
- 
- 
 %7D)
-%7D%0A      %3C/g%3E
+,
 %0A   

allow setting of wrapping component