#include <functional>
#include "graphics/animation.hpp"

namespace animation {
  struct Transform;
}

namespace ease2 {
  using EaseFunc = std::function<double(double)>;
  using MotionFunc = std::function<void(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative)>;

  EaseFunc get_easing(const std::string& name);
  MotionFunc get_motion(const std::string& name);

  double sine(double x);
  double out_circle(double x);
  double out_bounce(double x);
  double in_out_back(double x);
  double random(double tick);
  double normal_dist(double tick);

  void move_bounce(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void move_rush(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void scale_squeeze(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void scale_squash(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void scale_stretch(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void scale_grow(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void move_slide(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void move_none(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void scale_both(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
  void move_shake(animation::Transform &tr, sf::Vector2f& pos_out, sf::Vector2f& scale_out, float tick, bool relative);
}
