//
// Created by martin on 12.11.21.
//

#ifndef ANIMTESTBED_ANIMSAMPLERNODE_H
#define ANIMTESTBED_ANIMSAMPLERNODE_H

#include "../AnimNode.h"

struct AnimSamplerNode : public AnimNode {
  AnimSamplerNode(AnimationController* animation_controller)
      : AnimNode(animation_controller),
        m_override_ratio(false),
        m_anim_ratio(0.f) {
    assert(m_current_time < 100.0f);
    m_anim_node_type = AnimNodeType::AnimSampler;
  };
  virtual ~AnimSamplerNode() {}

  ozz::animation::Animation* m_animation;

  bool m_override_ratio;
  float m_anim_ratio;

  ozz::animation::SamplingCache m_sampling_cache;

  void SetAnimation(ozz::animation::Animation* animation);

  virtual void UpdateIsSynced(bool is_synced) override {
    m_is_time_synced = is_synced;
  }

  virtual void EvalAnimDuration() override {
    m_anim_duration = m_animation->duration();
  }

  virtual void UpdateTime(float dt) override {
    m_current_time += dt;
    if (!m_override_ratio) {
      if (m_is_time_synced) {
        m_anim_ratio = fmodf((float)m_current_time, 1.0f);
        m_current_time = m_anim_ratio;
      } else {
        const float duration = m_animation->duration();
        m_anim_ratio = fmodf((float)m_current_time / duration, 1.0f);
      }
    }

    if (m_anim_ratio < 0.f) {
      m_anim_ratio += 1.0f;
    }
  }

  virtual void Evaluate(
      ozz::vector<ozz::math::SoaTransform>* local_matrices) override;

  virtual void CollectNodeOrdering(
      std::vector<AnimNode*>& anim_nodes) override {
    anim_nodes.push_back(this);
  };

  virtual void DrawDebugUi();
};

#endif  //ANIMTESTBED_ANIMSAMPLERNODE_H
