#include "scoreboard.h"
#include <fstream>
#include <sstream>

// Constructor
ScoreBoard::ScoreBoard(SDL_Renderer *renderer, Resource *resource, Asset *asset, options_t *options, board_t *board)
{
    // Obten punteros a objetos
    this->resource = resource;
    this->asset = asset;
    this->renderer = renderer;
    this->board = board;
    this->options = options;

    // Reserva memoria para los objetos
    //playerTexture = resource->getTexture("player.png");
    itemTexture = resource->getTexture("items.png");
    sprite = new AnimatedSprite(renderer, resource->getAnimation("player.ani"));
    sprite->setCurrentAnimation("walk_menu");
    text = new Text(resource->getOffset("smb2.txt"), resource->getTexture("smb2.png"), renderer);

    // Inicializa las variables
    counter = 0;
    colorChangeSpeed = 4;
    paused = false;
    timePaused = 0;
    totalTimePaused = 0;

    // Inicializa el vector de colores
    const std::vector<std::string> vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
    for (auto v : vColors)
    {
        color.push_back(stringToColor(options->palette, v));
    }
}

// Destructor
ScoreBoard::~ScoreBoard()
{
    delete sprite;
    delete text;
}

// Pinta el objeto en pantalla
void ScoreBoard::render()
{
    // Anclas
    const int line1 = 19 * BLOCK;
    const int line2 = line1 + (2 * BLOCK);

    // Dibuja el fondo del marcador
    const SDL_Rect rect = {0, 18 * BLOCK, PLAY_AREA_WIDTH, GAMECANVAS_HEIGHT - PLAY_AREA_HEIGHT};
    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
    SDL_RenderFillRect(renderer, &rect);

    // Dibuja las vidas
    const int desp = (counter / 40) % 8;
    const int frame = desp % 4;
    sprite->setCurrentFrame(frame);
    sprite->setPosY(line2);
    for (int i = 0; i < board->lives; ++i)
    {
        sprite->setPosX(8 + (16 * i) + desp);
        const int index = i % color.size();
        sprite->getTexture()->setColor(color[index].r, color[index].g, color[index].b);
        sprite->render();
    }

    // Muestra si suena la música
    if (board->music)
    {
        const color_t c = board->color;
        SDL_Rect clip = {0, 8, 8, 8};
        itemTexture->setColor(c.r, c.g, c.b);
        itemTexture->render(renderer, 20 * BLOCK, line2, &clip);
    }

    // Escribe los textos
    const std::string timeTxt = std::to_string((clock.minutes % 60) / 10) + std::to_string(clock.minutes % 10) + clock.separator + std::to_string((clock.seconds % 60) / 10) + std::to_string(clock.seconds % 10);
    const std::string itemsTxt = std::to_string(board->items / 100) + std::to_string((board->items % 100) / 10) + std::to_string(board->items % 10);
    this->text->writeColored(BLOCK, line1, "Items collected ", board->color);
    this->text->writeColored(17 * BLOCK, line1, itemsTxt, stringToColor(options->palette, "white"));
    this->text->writeColored(20 * BLOCK, line1, " Time ", board->color);
    this->text->writeColored(26 * BLOCK, line1, timeTxt, stringToColor(options->palette, "white"));

    const std::string roomsTxt = std::to_string(board->rooms / 100) + std::to_string((board->rooms % 100) / 10) + std::to_string(board->rooms % 10);
    this->text->writeColored(22 * BLOCK, line2, "Rooms", stringToColor(options->palette, "white"));
    this->text->writeColored(28 * BLOCK, line2, roomsTxt, stringToColor(options->palette, "white"));
}

// Actualiza las variables del objeto
void ScoreBoard::update()
{
    counter++;
    sprite->update();

    if (!paused)
    { // Si está en pausa no se actualiza el reloj
        clock = getTime();
    }
}

// Obtiene el tiempo transcurrido de partida
ScoreBoard::clock_t ScoreBoard::getTime()
{
    const Uint32 timeElapsed = SDL_GetTicks() - board->iniClock - totalTimePaused;

    clock_t time;
    time.hours = timeElapsed / 3600000;
    time.minutes = timeElapsed / 60000;
    time.seconds = timeElapsed / 1000;
    time.separator = (timeElapsed % 1000 <= 500) ? ":" : " ";

    return time;
}

// Recarga la textura
void ScoreBoard::reLoadTexture()
{
    sprite->getTexture()->reLoad();
    //playerTexture->reLoad();
    itemTexture->reLoad();
    text->reLoadTexture();
}

// Recarga la paleta
void ScoreBoard::reLoadPalette()
{
    // Reinicia el vector de colores
    const std::vector<std::string> vColors = {"blue", "magenta", "green", "cyan", "yellow", "white", "bright_blue", "bright_magenta", "bright_green", "bright_cyan", "bright_yellow", "bright_white"};
    color.clear();
    for (auto v : vColors)
    {
        color.push_back(stringToColor(options->palette, v));
    }
}

// Pone el marcador en modo pausa
void ScoreBoard::pause()
{
    paused = true;
    timePaused = SDL_GetTicks();
}

// Quita el modo pausa del marcador
void ScoreBoard::resume()
{
    paused = false;
    totalTimePaused += SDL_GetTicks() - timePaused;
}