/**
 * Loops the given clip using this entity's animation mixer
 * @component loop-animation
 */
AFRAME.registerComponent("loop-animation", {
  dependencies: ["animation-mixer"],
  schema: {
    clip: { type: "string", required: true }
  },
  init() {
    const object3DMap = this.el.object3DMap;
    this.model = object3DMap.mesh || object3DMap.scene;

    if (this.model) {
      this.mixer = this.el.components["animation-mixer"].mixer;
    } else {
      this.onModelLoaded = this.onModelLoaded.bind(this);
      this.el.addEventListener("model-loaded", this.onModelLoaded);
    }
  },

  onModelLoaded(event) {
    const animationMixerComponent = this.el.components["animation-mixer"];
    this.model = event.detail.model;
    this.mixer = animationMixerComponent.mixer;

    this.updateClipState(true);

    this.el.removeEventListener(this.onModelLoaded);
  },

  update(oldData) {
    if (oldData.clip !== this.data.clip && this.model) {
      this.updateClipState(true);
    }
  },

  updateClipState(play) {
    const model = this.model;
    const clipName = this.data.clip;

    for (const clip of this.model.animations) {
      if (clip.name === clipName) {
        const action = this.mixer.clipAction(clip, model.parent);

        if (play) {
          action.enabled = true;
          action.setLoop(THREE.LoopRepeat, Infinity).play();
        } else {
          action.stop();
        }

        break;
      }
    }
  },

  destroy() {
    this.updateClipState(false);
    this.el.removeEventListener(this.onModelLoaded);
  }
});