#include "EngineFrame/Component/Text.h"
#include "Text.h"
#include "EngineCore/Game.h"
Text::Text()
{
}

Text::Text(std::string Str, TTF_Font *font, SDL_Color color)
{
    m_text = Str;
    m_font = font;
    m_text_color = color;
    Init(Str, font, color);
}

Text::Text(std::string Str, TTF_Font *font, SDL_Color textColor, SDL_Color strokeColor, int strokeSize)
{
    m_text = Str;
    m_font = font;
    m_text_color = textColor;
    m_stroke_color = strokeColor;
    m_stroke_size = strokeSize;
    Init(Str, font, textColor, strokeColor, strokeSize);
}

Text::~Text()
{
}

void Text::Init(std::string Str, TTF_Font *font, SDL_Color color)
{
    // 标记该组件需要渲染和更新
    addTag(Tag::RENDER);
    addTag(Tag::UPDATE);

    // TTF_SetFontOutline(font, 1);
    // 先渲染为表面
    SDL_Surface *textSurface = TTF_RenderUTF8_Blended(font, Str.c_str(), color);
    if (!textSurface)
    {
        SDL_LogError(0, "文字渲染为表面失败！TTF_Error:%s", TTF_GetError());
    }
    // 再将表面转换为纹理
    SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
    m_texture = SDL_CreateTextureFromSurface(renderer, textSurface);
    if (!m_texture)
    {
        SDL_LogError(0, "表面转换为纹理失败！SDL_Error:%s", SDL_GetError());
    }
    // 设置纹理过滤模式为最近邻，避免缩放模糊
    SDL_SetTextureScaleMode(m_texture, SDL_ScaleModeNearest);
    Size.x = textSurface->w;
    Size.y = textSurface->h;
    TextureSize.x = textSurface->w;
    TextureSize.y = textSurface->h;

    // 释放表面
    SDL_FreeSurface(textSurface);
}

void Text::Init(std::string Str, TTF_Font *font, SDL_Color textColor, SDL_Color strokeColor, int strokeSize)
{
    // 先保存原始字体的轮廓设置
    int originalOutline = TTF_GetFontOutline(font);

    // 设置字体轮廓大小（描边宽度）
    TTF_SetFontOutline(font, strokeSize);

    // 渲染描边（使用描边颜色）
    SDL_Surface *strokeSurface = TTF_RenderUTF8_Blended(font, Str.c_str(), strokeColor);
    if (!strokeSurface)
    {
        SDL_LogError(0, "描边渲染为表面失败！TTF_Error:%s", TTF_GetError());
        TTF_SetFontOutline(font, originalOutline); // 恢复原始设置
        return;
    }

    // 恢复字体轮廓设置，用于渲染文字本身
    TTF_SetFontOutline(font, 0);

    // 渲染文字本身（使用文字颜色）
    SDL_Surface *textSurface = TTF_RenderUTF8_Blended(font, Str.c_str(), textColor);
    if (!textSurface)
    {
        SDL_LogError(0, "文字渲染为表面失败！TTF_Error:%s", TTF_GetError());
        SDL_FreeSurface(strokeSurface);
        TTF_SetFontOutline(font, originalOutline); // 恢复原始设置
        return;
    }

    // 创建一个合并描边和文字的表面
    SDL_Renderer *renderer = Game::GetInstance().GetRenderer();

    // 计算最终纹理大小（描边会增加额外尺寸）
    int finalWidth = strokeSurface->w;
    int finalHeight = strokeSurface->h;

    // 创建一个临时表面用于合并描边和文字
    SDL_Surface *finalSurface = SDL_CreateRGBSurfaceWithFormat(
        0, finalWidth, finalHeight, 32, SDL_PIXELFORMAT_RGBA32);
    if (!finalSurface)
    {
        SDL_LogError(0, "创建最终表面失败！SDL_Error:%s", SDL_GetError());
        SDL_FreeSurface(textSurface);
        SDL_FreeSurface(strokeSurface);
        TTF_SetFontOutline(font, originalOutline);
        return;
    }

    // 将描边绘制到最终表面
    SDL_Rect strokeRect = {0, 0, strokeSurface->w, strokeSurface->h};
    SDL_BlitSurface(strokeSurface, nullptr, finalSurface, &strokeRect);

    // 计算文字在描边中间的位置
    SDL_Rect textRect = {
        strokeSize, // X偏移（描边宽度）
        strokeSize, // Y偏移（描边宽度）
        textSurface->w,
        textSurface->h};
    SDL_BlitSurface(textSurface, nullptr, finalSurface, &textRect);

    // 将合并后的表面转换为纹理
    m_texture = SDL_CreateTextureFromSurface(renderer, finalSurface);
    if (!m_texture)
    {
        SDL_LogError(0, "表面转换为纹理失败！SDL_Error:%s", SDL_GetError());
    }

    // 设置尺寸信息
    Size.x = finalSurface->w;
    Size.y = finalSurface->h;
    TextureSize.x = finalSurface->w;
    TextureSize.y = finalSurface->h;

    // 释放所有临时表面
    SDL_FreeSurface(textSurface);
    SDL_FreeSurface(strokeSurface);
    SDL_FreeSurface(finalSurface);

    // 恢复字体原始轮廓设置
    TTF_SetFontOutline(font, originalOutline);
}

void Text::HandleEvents(SDL_Event *e)
{
}

void Text::Update(float deltaTime)
{
}

void Text::Render()
{
    SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
    if (!renderer || !m_texture)
        return;
    SDL_Rect dstrect = {Pos.x, Pos.y, Size.x, Size.y};

    SDL_RenderCopy(renderer, m_texture, NULL, &dstrect);
}

void Text::Clear()
{
}

void Text::SetPos(SDL_Point pos)
{
    Pos = pos;
}

SDL_Point Text::GetPos()
{
    return Pos;
}

void Text::SetText(std::string Str)
{
    if (Str == m_text)
        return;
    if (!m_font)
    {
        SDL_LogError(0, "SetText失败：字体指针为空！");
        return;
    }

    // 如果有原纹理先删除原纹理
    if (m_texture)
    {
        SDL_DestroyTexture(m_texture);
        m_texture = nullptr; // 置空指针
    }
    m_text = Str;
    // 根据是否有描边选择对应的Init方法
    if (m_stroke_size > 0)
    {
        Init(Str, m_font, m_text_color, m_stroke_color, m_stroke_size);
    }
    else
    {
        Init(Str, m_font, m_text_color);
    }
}

std::string Text::GetText()
{
    return m_text;
}