// Parte un texto en UTF-8 en palabras. Viene hecho: no es el tema del laboratorio.
#ifndef WORDS_H
#define WORDS_H

#include <cstddef>
#include <string>
#include <vector>

// Una palabra es una secuencia de letras: ASCII, o las de dos bytes que empiezan con 0xC3 (á, é, ñ,
// ü...), salvo × y ÷. Lo demás separa, incluidos ¿, ¡, « y la raya. Pasa a minúsculas también
// Á, É, Ñ: tolower de C trabaja por byte y no las cambiaría.
inline std::vector<std::string> split_words(const std::string& text) {
    std::vector<std::string> words;
    std::string current;
    std::size_t i = 0;
    while (i < text.size()) {
        unsigned char first = static_cast<unsigned char>(text[i]);
        if ((first >= 'a' && first <= 'z') || (first >= 'A' && first <= 'Z')) {
            current += static_cast<char>(first >= 'a' ? first : first + ('a' - 'A'));
            i++;
            continue;
        }
        if (first == 0xC3 && i + 1 < text.size()) {
            unsigned char second = static_cast<unsigned char>(text[i + 1]);
            if (second >= 0x80 && second != 0x97 && second != 0xB7) {
                // En este bloque, cada mayúscula está 0x20 antes que su minúscula.
                current += static_cast<char>(first);
                current += static_cast<char>(second < 0x9F ? second + 0x20 : second);
                i += 2;
                continue;
            }
        }
        if (!current.empty()) {
            words.push_back(current);
            current.clear();
        }
        // Saltar el carácter completo: los bytes 10xxxxxx continúan al anterior.
        i++;
        while (i < text.size() && (static_cast<unsigned char>(text[i]) & 0xC0) == 0x80) {
            i++;
        }
    }
    if (!current.empty()) {
        words.push_back(current);
    }
    return words;
}

#endif
