"use strict";

exports.__esModule = true;
exports.default = exports.AnimationAdapter = void 0;
var _set2 = _interopRequireDefault(require("lodash/fp/set"));
var _reduce2 = _interopRequireDefault(require("lodash/fp/reduce"));
var _pipe2 = _interopRequireDefault(require("lodash/fp/pipe"));
var _values2 = _interopRequireDefault(require("lodash/fp/values"));
var _identity2 = _interopRequireDefault(require("lodash/fp/identity"));
var _negate2 = _interopRequireDefault(require("lodash/fp/negate"));
var _some2 = _interopRequireDefault(require("lodash/fp/some"));
var _pickBy2 = _interopRequireDefault(require("lodash/fp/pickBy"));
var _noop2 = _interopRequireDefault(require("lodash/fp/noop"));
var _isString2 = _interopRequireDefault(require("lodash/fp/isString"));
var _isNil2 = _interopRequireDefault(require("lodash/fp/isNil"));
var _isArray2 = _interopRequireDefault(require("lodash/fp/isArray"));
var _includes2 = _interopRequireDefault(require("lodash/fp/includes"));
var _get2 = _interopRequireDefault(require("lodash/fp/get"));
var _getOr2 = _interopRequireDefault(require("lodash/fp/getOr"));
var _every2 = _interopRequireDefault(require("lodash/fp/every"));
var _assign2 = _interopRequireDefault(require("lodash/fp/assign"));
var _react = _interopRequireDefault(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
var _animation = _interopRequireDefault(require("../animation"));
var _transition = _interopRequireDefault(require("../transition"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
const AnimationAdapter = ({
  animated,
  onAnimationEnd = _noop2.default,
  name,
  children
}) => {
  return _react.default.Children.map(children, child => /*#__PURE__*/_react.default.cloneElement(child, {
    animated,
    onAnimationEnd: () => onAnimationEnd(name)
  }));
};
exports.AnimationAdapter = AnimationAdapter;
AnimationAdapter.propTypes = process.env.NODE_ENV !== "production" ? {
  name: _propTypes.default.string.isRequired,
  onAnimationEnd: _propTypes.default.func,
  animated: _propTypes.default.bool
} : {};
const pickByWithKey = _pickBy2.default.convert({
  cap: true
});
const walker = (type, handler) => children => {
  return _react.default.Children.map(children, (child, index) => {
    if ((0, _isNil2.default)(child) || (0, _isString2.default)(child)) return child;
    const newChild = child.type === type ? handler(child) : child;
    if (_react.default.Children.count(newChild.props.children) === 0) return newChild;
    return /*#__PURE__*/_react.default.cloneElement(newChild, {}, walker(type, handler)(newChild.props.children));
  });
};
const reduceChildren = fun => acc => children => {
  let newAcc = acc;
  _react.default.Children.map(children, child => {
    newAcc = fun(newAcc, child);
    return child;
  });
  return newAcc;
};
const getAnimationNames = reduceChildren((acc, child) => {
  if ((0, _isString2.default)(child)) return acc;
  const {
    type,
    props: {
      children
    }
  } = child;
  if (_animation.default !== type && _transition.default !== type && AnimationAdapter !== type) return [...acc, ...getAnimationNames(children)];
  const {
    props: {
      name
    }
  } = child;
  return [name, ...acc, ...getAnimationNames(children)];
})([]);
const mergeAnimationStates = (animations, children) => {
  const names = getAnimationNames(children);
  return (0, _pipe2.default)(pickByWithKey((value, key) => (0, _includes2.default)(key, names)), (0, _assign2.default)((0, _reduce2.default)((acc, name) => (0, _set2.default)(name, false, acc), {}, names)))(animations);
};
class AnimationScheduler extends _react.default.Component {
  static getDerivedStateFromProps(props, state) {
    const {
      children
    } = props;
    const {
      animations
    } = state;
    return {
      animations: mergeAnimationStates(animations, children)
    };
  }
  constructor(props) {
    super(props);
    const {
      children
    } = props;
    this.state = {
      animations: mergeAnimationStates({}, children)
    };
  }
  isAnimated(after) {
    if ((0, _isNil2.default)(after)) return true;
    const {
      animations
    } = this.state;
    const isAnimated = (0, _every2.default)(name => (0, _getOr2.default)(false, name, animations), (0, _isArray2.default)(after) ? after : [after]);
    return isAnimated;
  }
  handlerAnimationEnd(name) {
    this.setState((0, _set2.default)(['animations', name], true), () => {
      const hasPendingAnimation = (0, _pipe2.default)((0, _get2.default)('state.animations'), _values2.default, (0, _some2.default)((0, _negate2.default)(_identity2.default)))(this);
      const {
        onAnimationEnd = _noop2.default
      } = this.props;
      if (!hasPendingAnimation) return onAnimationEnd();
    });
  }
  processAnimation(child) {
    const {
      animated: parentAnimated
    } = this.props;
    const {
      animated,
      onAnimationEnd = _noop2.default,
      after
    } = child.props;
    return /*#__PURE__*/_react.default.cloneElement(child, {
      animated: parentAnimated ? this.isAnimated(after) || animated : animated,
      onAnimationEnd: name => {
        this.handlerAnimationEnd(name);
        return onAnimationEnd(name);
      }
    });
  }
  render() {
    const {
      children
    } = this.props;
    return (0, _pipe2.default)(walker(_animation.default, this.processAnimation.bind(this)), walker(_transition.default, this.processAnimation.bind(this)), walker(AnimationAdapter, this.processAnimation.bind(this)))(children);
  }
}
AnimationScheduler.propTypes = process.env.NODE_ENV !== "production" ? {
  onAnimationEnd: _propTypes.default.func,
  animated: _propTypes.default.bool,
  children: _propTypes.default.node
} : {};
var _default = exports.default = AnimationScheduler;
//# sourceMappingURL=index.js.map