#include "game/scenes/sprite_mover.hpp"

#include <algorithm>

namespace Scenes {

    void SpriteMover::moveTo(int x0, int y0, int x1, int y1, int duration_ms, EaseFn ease) {
        x0_ = x0;
        y0_ = y0;
        x1_ = x1;
        y1_ = y1;
        duration_ms_ = std::max(0, duration_ms);
        elapsed_ms_ = 0;
        ease_ = (ease != nullptr) ? ease : Easing::linear;
        cur_x_ = x0;
        cur_y_ = y0;
    }

    void SpriteMover::setPosition(int x, int y) {
        cur_x_ = x;
        cur_y_ = y;
        x0_ = x1_ = x;
        y0_ = y1_ = y;
        duration_ms_ = 0;
        elapsed_ms_ = 0;
    }

    void SpriteMover::tick(int delta_ms) {
        if (duration_ms_ <= 0) {
            cur_x_ = x1_;
            cur_y_ = y1_;
            return;
        }
        elapsed_ms_ = std::min(elapsed_ms_ + delta_ms, duration_ms_);
        const float T = static_cast<float>(elapsed_ms_) / static_cast<float>(duration_ms_);
        const float EASED = ease_(T);
        cur_x_ = Easing::lerpInt(x0_, x1_, EASED);
        cur_y_ = Easing::lerpInt(y0_, y1_, EASED);
    }

    auto SpriteMover::progress() const -> float {
        if (duration_ms_ <= 0) {
            return 1.0F;
        }
        return static_cast<float>(elapsed_ms_) / static_cast<float>(duration_ms_);
    }

}  // namespace Scenes
