#include "debug.h"
#include <algorithm> // Para max
#include "asset.h"	 // Para Asset
#include "text.h"	 // Para Text
#include "texture.h" // Para Texture
#include "utils.h"
#include "screen.h"
#include "asset.h"

// [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
Debug *Debug::get()
{
	return Debug::debug_;
}

// Constructor
Debug::Debug()
	// Copia la dirección de los objetos
	: screen_(Screen::get()),
	  renderer_(Screen::get()->getRenderer()),
	  asset_(Asset::get())
{
	// Reserva memoria para los punteros
	texture_ = new Texture(renderer_, asset_->get("debug.png"));
	text_ = new Text(asset_->get("debug.txt"), texture_, renderer_);
}

// Destructor
Debug::~Debug()
{
	delete texture_;
	delete text_;
}

// Actualiza las variables
void Debug::update()
{
}

// Dibuja en pantalla
void Debug::render()
{
	int y = y_;
	int w = 0;

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

	y = 0;
	for (auto l : log_)
	{
		text_->writeColored(x_ + 10, y, l, Color(255, 255, 255));
		y += text_->getCharacterSize() + 1;
	}
}

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

// Añade un texto para mostrar
void Debug::add(std::string text)
{
	slot_.push_back(text);
}

// Borra la información de debug
void Debug::clear()
{
	slot_.clear();
}

// Añade un texto para mostrar en el apartado log
void Debug::addToLog(std::string text)
{
	log_.push_back(text);
}

// Borra la información de debug del apartado log
void Debug::clearLog()
{
	log_.clear();
}

// Establece el valor de la variable
void Debug::setEnabled(bool value)
{
	enabled_ = value;
}

// Obtiene el valor de la variable
bool Debug::getEnabled()
{
	return enabled_;
}

// Cambia el valor de la variable
void Debug::switchEnabled()
{
	enabled_ = !enabled_;
}