#include "core/system/debug.hpp"

#ifdef _DEBUG

#include <algorithm>  // Para max
#include <memory>     // Para __shared_ptr_access, shared_ptr

#include "core/rendering/text.hpp"            // Para Text
#include "core/resources/resource_cache.hpp"  // Para Resource
#include "utils/color.hpp"                    // Para Color
#include "utils/defines.hpp"                  // Para PlayArea

// [SINGLETON]
Debug* Debug::debug = nullptr;

// [SINGLETON] Crearemos el objeto con esta función estática
void Debug::init() {
    Debug::debug = new Debug();
}

// [SINGLETON] Destruiremos el objeto con esta función estática
void Debug::destroy() {
    delete Debug::debug;
}

// [SINGLETON] Con este método obtenemos el objeto y podemos trabajar con él
auto Debug::get() -> Debug* {
    return Debug::debug;
}

// Dibuja en pantalla
void Debug::render() {
    auto text = Resource::Cache::get()->getText("aseprite");
    int y = y_;
    int w = 0;

    for (const auto& s : slot_) {
        text->write(x_, y, s);
        w = (std::max(w, (int)s.length()));
        y += text->getCharacterSize() + 1;
        if (y > PlayArea::HEIGHT - text->getCharacterSize()) {
            y = y_;
            x_ += w * text->getCharacterSize() + 2;
        }
    }

    y = 0;
    for (const auto& l : log_) {
        text->writeColored(x_ + 10, y, l, Color::index(Color::Cpc::WHITE));
        y += text->getCharacterSize() + 1;
    }
}

// Establece la posición donde se colocará la información de debug
void Debug::setPos(SDL_FPoint p) {
    x_ = p.x;
    y_ = p.y;
}

#endif  // _DEBUG