#include "enter_name.h"
#include <stddef.h>  // Para size_t
#include <algorithm> // Para max, min

// Constructor
EnterName::EnterName()
{
    init();
}

// Inicializa el objeto
void EnterName::init()
{
    // Obtiene el puntero al nombre
    name_ = "A";

    // Inicia la lista de caracteres permitidos
    character_list_ = " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-+-*/=?¿<>!\"#$%&/()";
    position_ = 0;
    num_characters_ = static_cast<int>(character_list_.size());

    // Pone la lista de indices para que refleje el nombre
    updateCharacterIndex();

    // Actualiza el nombre para que ocupe 8 espacios
    updateName();
}

// Incrementa la posición
void EnterName::incPosition()
{
    position_++;
    position_ = std::min(position_, NAME_LENGHT - 1);
    checkIfPositionHasBeenUsed();
}

// Decrementa la posición
void EnterName::decPosition()
{
    --position_;
    position_ = std::max(position_, 0);
}

// Incrementa el índice
void EnterName::incIndex()
{
    ++character_index_[position_];
    if (character_index_[position_] >= num_characters_)
    {
        character_index_[position_] = 0;
    }
    updateName();
}

// Decrementa el índice
void EnterName::decIndex()
{
    --character_index_[position_];
    if (character_index_[position_] < 0)
    {
        character_index_[position_] = num_characters_ - 1;
    }
    updateName();
}

// Actualiza el nombre a partir de la lista de índices
void EnterName::updateName()
{
    name_.clear();
    for (int i = 0; i < NAME_LENGHT; ++i)
    {
        name_.push_back(character_list_[character_index_[i]]);
    }
}

// Actualiza la variable
void EnterName::updateCharacterIndex()
{
    // Rellena de espacios y marca como no usados
    for (size_t i = 0; i < NAME_LENGHT; ++i)
    {
        character_index_[i] = 0;
        position_has_been_used_[i] = false;
    }

    // Coloca los índices en función de los caracteres que forman el nombre
    for (size_t i = 0; i < name_.size(); ++i)
    {
        character_index_[i] = findIndex(name_.at(i));
        position_has_been_used_[i] = true;
    }
}

// Encuentra el indice de un caracter en "character_list_"
int EnterName::findIndex(char character) const
{
    for (size_t i = 0; i < character_list_.size(); ++i)
        if (character == character_list_.at(i))
            return i;
    return 0;
}

// Obtiene el nombre
std::string EnterName::getName() const
{
    return name_;
}

// Obtiene la posición que se está editando
int EnterName::getPosition() const
{
    return position_;
}

// Comprueba la posición y copia el caracter si es necesario
void EnterName::checkIfPositionHasBeenUsed()
{
    auto used = position_has_been_used_[position_];

    if (!used && position_ > 0)
        character_index_[position_] = character_index_[position_ - 1];

    position_has_been_used_[position_] = true;
    updateName();
}