#include "FontManager.h"
#include "Fonts.h"
#include <cctype>

#ifdef _WIN32
#include <windows.h>
#include <Shlobj.h>
#undef DrawText  // 防止 windows.h 的 DrawText 宏与 FontManager::DrawText 方法名冲突
#endif

// ============================================================================
// 单例
// ============================================================================
FontManager& FontManager::GetInstance() {
    static FontManager instance;
    return instance;
}

// ============================================================================
// 内部工具
// ============================================================================
std::vector<int> FontManager::ExtractCodepoints(const char* text) {
    int count = 0;
    int* cps = RLLoadCodepoints(text, &count);
    std::vector<int> result(cps, cps + count);
    RLUnloadCodepoints(cps);
    return result;
}

// ============================================================================
// 字体重建
// ============================================================================
void FontManager::RebuildFont(FontEntry& entry) {
    RLFont newFont;
    float size = (float)(entry.baseSize) * m_dpiScale;
    
    if (entry.fromMemory) {
        newFont = RLLoadFontFromMemory(".ttf", entry.memData, entry.memSize,
            (int)size, NULL, 0);
    }
    else {
        std::vector<int> cps(entry.codepoints.begin(), entry.codepoints.end());
        newFont = RLLoadFontEx(entry.path.c_str(), (int)size,
            cps.empty() ? NULL : cps.data(), (int)cps.size());
    }

    if (newFont.texture.id == 0 || newFont.baseSize <= 0) return;

    if (entry.font.texture.id != 0)
        RLUnloadFont(entry.font);

    entry.font = newFont;
    RLSetTextureFilter(entry.font.texture, RL_E_TEXTURE_FILTER_BILINEAR);
}

// ============================================================================
// 注册命名字体
// ============================================================================
void FontManager::RegisterFont(const char* name, const char* path, int baseSize) {
    if (m_fonts.find(name) != m_fonts.end()) return;

    FontEntry entry;
    entry.path = path;
    entry.baseSize = baseSize;
    entry.fromMemory = false;
    
    // 预加载 ASCII 码点
    auto initCps = ExtractCodepoints("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789.,;:!?()-_=+[]{}|/\\\"'`~@#$%^&*<> ");
    for (int cp : initCps) entry.codepoints.insert(cp);
    
    m_fonts[name] = entry;
    RebuildFont(m_fonts[name]);
}

void FontManager::RegisterFontFromMemory(const char* name, const unsigned char* data, int dataSize, int baseSize) {
    if (m_fonts.find(name) != m_fonts.end()) return;

    FontEntry entry;
    entry.path = name;  // use name as identifier
    entry.baseSize = baseSize;
    entry.fromMemory = true;
    entry.memData = data;
    entry.memSize = dataSize;

    // Memory fonts use NULL codepoints for default character set
    m_fonts[name] = entry;
    RebuildFont(m_fonts[name]);
}

// ============================================================================
// 获取字体
// ============================================================================
RLFont& FontManager::GetFont(const char* name) {
    auto it = m_fonts.find(name);
    if (it != m_fonts.end())
        return it->second.font;

    static RLFont dummy = { 0 };
    return dummy;
}

// ============================================================================
// 更新字体基础大小
// ============================================================================
void FontManager::SetFontBaseSize(const char* name, int baseSize) {
    auto it = m_fonts.find(name);
    if (it == m_fonts.end())
        return;

    FontEntry& entry = it->second;
    if (entry.baseSize == baseSize)
        return;

    entry.baseSize = baseSize;
    RebuildFont(entry);
}

// ============================================================================
// 确保码点已加载
// ============================================================================
void FontManager::EnsureText(const char* name, const char* text) {
    auto it = m_fonts.find(name);
    if (it == m_fonts.end()) return;

    FontEntry& entry = it->second;
    if (entry.fromMemory) return;  // memory fonts use full default glyph set

    auto cps = ExtractCodepoints(text);
    bool needRebuild = false;
    for (int cp : cps) {
        // Skip ASCII (already loaded)
        if (cp < 128) continue;
        if (entry.codepoints.find(cp) == entry.codepoints.end()) {
            entry.codepoints.insert(cp);
            needRebuild = true;
        }
    }
    if (needRebuild)
        RebuildFont(entry);
}

// ============================================================================
// 绘制 & 测量
// ============================================================================
void FontManager::DrawText(const char* name, const char* text, int x, int y, int fontSize, RLColor color) {
    EnsureText(name, text);
    RLFont& font = GetFont(name);
    if (font.texture.id != 0)
        RLDrawTextEx(font, text, { (float)x, (float)y }, (float)fontSize, 1.0f, color);
}

RLVector2 FontManager::MeasureText(const char* name, const char* text, int fontSize) {
    EnsureText(name, text);
    RLFont& font = GetFont(name);
    if (font.texture.id != 0)
        return RLMeasureTextEx(font, text, (float)fontSize, 1.0f);
    return { 0, 0 };
}

// ============================================================================
// DPI 缩放
// ============================================================================
void FontManager::SetDpiScale(float scale) {
    if (scale == m_dpiScale) return;
    m_dpiScale = scale;

    for (auto& pair : m_fonts) {
        if (pair.second.font.texture.id != 0)
            RLUnloadFont(pair.second.font);
        RebuildFont(pair.second);
    }
}

// ============================================================================
// 释放所有字体
// ============================================================================
void FontManager::UnloadAll() {
    for (auto& pair : m_fonts) {
        if (pair.second.font.texture.id != 0)
            RLUnloadFont(pair.second.font);
    }
    m_fonts.clear();
}
