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

#ifndef ANIMTESTBED_ANIMNODE_H
#define ANIMTESTBED_ANIMNODE_H

#include <ozz/base/maths/transform.h>

#include <string>

#include "AnimationController.h"
#include "SkinnedMesh.h"

enum class AnimNodeType { Blend, SpeedScale, AnimSampler };

struct AnimNode {
  AnimNode(AnimationController* animation_controller)
      : m_animation_controller(animation_controller),
        m_time_current(0.f),
        m_is_time_synced(false) {}
  virtual ~AnimNode(){};

  AnimNodeType m_anim_node_type;
  std::string m_name;
  AnimationController* m_animation_controller;

  // When synced then current time is relative to the node's anim duration.:w
  bool m_is_time_synced;
  float m_time_current;
  SyncTrack m_sync_track;

  virtual void Reset() { m_time_current = 0.f; }

  // Mark current node according to is_synced and propagate flag to animation inputs.
  virtual void UpdateIsSynced(bool is_synced) = 0;

  // Evaluate the animation duration of this node. All input nodes must have already evaluated
  // their anim durations.
  virtual void UpdateSyncTrack() = 0;

  // Evaluate current time and propagate time step to inputs.
  virtual void UpdateTime(float dt) = 0;

  // Evaluate the current node and write output to local_matrices.
  virtual void Evaluate(
      ozz::vector<ozz::math::SoaTransform>* local_matrices,
      ozz::math::Transform* root_transform) = 0;

  // Returns a list of animation nodes that provide input for this node.
  virtual void GetInputNodes(std::vector<AnimNode*>& input_nodes) const = 0 ;

  virtual void DrawDebugUi(){};
};

#endif  //ANIMTESTBED_ANIMNODE_H
