// curtain.cpp - Implementació de la cortinilla negra
// © 2026 JailDesigner

#include "core/graphics/curtain.hpp"

#include <algorithm>

#include "core/defaults/game.hpp"
#include "core/math/easing.hpp"

namespace Graphics {

    namespace {
        constexpr float SCREEN_H = static_cast<float>(Defaults::Game::HEIGHT);
        constexpr float SCREEN_W = static_cast<float>(Defaults::Game::WIDTH);
    }  // namespace

    Curtain::Curtain(Rendering::Renderer* renderer)
        : renderer_(renderer) {}

    void Curtain::cover(float duration) {
        // Caire superior de -H (fora, a dalt) fins a 0 (tela tapant tota la pantalla).
        from_ = -SCREEN_H;
        to_ = 0.0F;
        duration_ = duration;
        elapsed_ = 0.0F;
        active_ = true;
    }

    void Curtain::reveal(float duration) {
        // Caire superior de 0 (tapant) fins a +H (tela fora per baix).
        from_ = 0.0F;
        to_ = SCREEN_H;
        duration_ = duration;
        elapsed_ = 0.0F;
        active_ = true;
    }

    void Curtain::update(float delta_time) {
        if (!active_) {
            return;
        }
        elapsed_ += delta_time;
    }

    auto Curtain::topY() const -> float {
        if (duration_ <= 0.0F) {
            return to_;
        }
        const float T = std::clamp(elapsed_ / duration_, 0.0F, 1.0F);
        // Ease-in: la tela "cau" accelerant, com per gravetat.
        return Easing::lerp(from_, to_, Easing::easeInQuad(T));
    }

    auto Curtain::isDone() const -> bool {
        return !active_ || elapsed_ >= duration_;
    }

    void Curtain::draw() const {
        if (!active_) {
            return;
        }
        const float TOP = topY();
        // Si la tela ja ha sortit completament per baix, no hi ha res a pintar.
        if (TOP >= SCREEN_H) {
            return;
        }
        renderer_->pushRect(0.0F, TOP, SCREEN_W, SCREEN_H, 0.0F, 0.0F, 0.0F, 1.0F);
    }

}  // namespace Graphics
