import GPUInterpolationTransition from '../../transitions/gpu-interpolation-transition';
import GPUSpringTransition from '../../transitions/gpu-spring-transition';
import log from '../../utils/log';
const TRANSITION_TYPES = {
  interpolation: GPUInterpolationTransition,
  spring: GPUSpringTransition
};
export default class AttributeTransitionManager {
  constructor(device, {
    id,
    timeline
  }) {
    this.id = void 0;
    this.isSupported = void 0;
    this.device = void 0;
    this.timeline = void 0;
    this.transitions = void 0;
    this.needsRedraw = void 0;
    this.numInstances = void 0;
    if (!device) throw new Error('AttributeTransitionManager is constructed without device');
    this.id = id;
    this.device = device;
    this.timeline = timeline;
    this.transitions = {};
    this.needsRedraw = false;
    this.numInstances = 1;
    this.isSupported = device.features.has('transform-feedback-webgl2');
  }

  finalize() {
    for (const attributeName in this.transitions) {
      this._removeTransition(attributeName);
    }
  }

  update({
    attributes,
    transitions,
    numInstances
  }) {
    this.numInstances = numInstances || 1;

    for (const attributeName in attributes) {
      const attribute = attributes[attributeName];
      const settings = attribute.getTransitionSetting(transitions);
      if (!settings) continue;

      this._updateAttribute(attributeName, attribute, settings);
    }

    for (const attributeName in this.transitions) {
      const attribute = attributes[attributeName];

      if (!attribute || !attribute.getTransitionSetting(transitions)) {
        this._removeTransition(attributeName);
      }
    }
  }

  hasAttribute(attributeName) {
    const transition = this.transitions[attributeName];
    return transition && transition.inProgress;
  }

  getAttributes() {
    const animatedAttributes = {};

    for (const attributeName in this.transitions) {
      const transition = this.transitions[attributeName];

      if (transition.inProgress) {
        animatedAttributes[attributeName] = transition.attributeInTransition;
      }
    }

    return animatedAttributes;
  }

  run() {
    if (!this.isSupported || this.numInstances === 0) {
      return false;
    }

    for (const attributeName in this.transitions) {
      const updated = this.transitions[attributeName].update();

      if (updated) {
        this.needsRedraw = true;
      }
    }

    const needsRedraw = this.needsRedraw;
    this.needsRedraw = false;
    return needsRedraw;
  }

  _removeTransition(attributeName) {
    this.transitions[attributeName].cancel();
    delete this.transitions[attributeName];
  }

  _updateAttribute(attributeName, attribute, settings) {
    const transition = this.transitions[attributeName];
    let isNew = !transition || transition.type !== settings.type;

    if (isNew) {
      if (!this.isSupported) {
        log.warn(`WebGL2 not supported by this browser. Transition for ${attributeName} is disabled.`)();
        return;
      }

      if (transition) {
        this._removeTransition(attributeName);
      }

      const TransitionType = TRANSITION_TYPES[settings.type];

      if (TransitionType) {
        this.transitions[attributeName] = new TransitionType({
          attribute,
          timeline: this.timeline,
          device: this.device
        });
      } else {
        log.error(`unsupported transition type '${settings.type}'`)();
        isNew = false;
      }
    }

    if (isNew || attribute.needsRedraw()) {
      this.needsRedraw = true;
      this.transitions[attributeName].start(settings, this.numInstances);
    }
  }

}
//# sourceMappingURL=attribute-transition-manager.js.map