#include "Sprite.h"
#include "EngineCore/Game.h"
#include "Text.h"

void Sprite::Init()
{
    this->Size = m_texture->TextureSize;
    RenderBase::Init();
}

Sprite::Sprite(std::string imgPath, int Index)
{
    this->imgPath = imgPath;
    this->Index = Index;
    m_texture = new Texture(imgPath, Index);
    Init();
    CalcRenderInfoLogic(); // 第一次计算
}

Sprite::Sprite(std::string PngPath)
{
    m_texture = new Texture(PngPath);
    Init();
    CalcRenderInfoLogic(); // 第一次计算
}

Sprite::~Sprite()
{
}

RefPtr<Texture> Sprite::GetTexture()
{
    return m_texture;
}

void Sprite::CalcRenderInfoLogic()
{
    // 计算缩放因子和翻转状态
    float scaleX = transformIter.scale.x * transform.scale.x;
    float scaleY = transformIter.scale.y * transform.scale.y;

    // X轴和Y轴上是否翻转的标志
    bool flipX = scaleX < 0;
    bool flipY = scaleY < 0;

    _RenderGuidanceInfo.flip = SDL_FLIP_NONE;
    // 更新翻转状态
    if (flipX)
        _RenderGuidanceInfo.flip = static_cast<SDL_RendererFlip>(SDL_FLIP_HORIZONTAL | _RenderGuidanceInfo.flip);
    if (flipY)
        _RenderGuidanceInfo.flip = static_cast<SDL_RendererFlip>(SDL_FLIP_VERTICAL | _RenderGuidanceInfo.flip);

    // 纹理数据里带的偏移数据 有这个偏移才能保证动画播放时视觉中心点在一个点上
    float texturePosX = flipX ? -(m_texture->TextureSize.width + m_texture->TexturePos.x) + SDL_abs(transform.position.x * 2) : m_texture->TexturePos.x;
    float texturePosY = flipY ? -(m_texture->TextureSize.height + m_texture->TexturePos.y) + SDL_abs(transform.position.y * 2) : m_texture->TexturePos.y;

    // 先计算Img坐标与精灵坐标合成后的真实坐标
    float RealPosX = transform.position.x + texturePosX;
    float RealPosY = transform.position.y + texturePosY;

    // 计算在世界中的位置
    float baseX = transformIter.position.x + RealPosX;
    float baseY = transformIter.position.y + RealPosY;

    // 获取当前帧的原始尺寸
    int frameWidth = Size.width;
    int frameHeight = Size.height;

    // 原始锚点偏移（基于帧尺寸）
    float origAnchorOffsetX = int(frameWidth * Anchor.x);
    float origAnchorOffsetY = int(frameHeight * Anchor.y);

    // 缩放的绝对值
    float absScaleX = SDL_fabs(scaleX);
    float absScaleY = SDL_fabs(scaleY);
    // 缩放后的尺寸
    float scaledWidth = frameWidth * absScaleX;
    float scaledHeight = frameHeight * absScaleY;
    // 缩放后的锚点偏移
    float scaledAnchorOffsetX = int(origAnchorOffsetX * absScaleX);
    float scaledAnchorOffsetY = int(origAnchorOffsetY * absScaleY);

    // 计算缩放后的锚点偏移与原锚点偏移的差值
    float scaleOffsetX = scaledAnchorOffsetX - origAnchorOffsetX;
    float scaleOffsetY = scaledAnchorOffsetY - origAnchorOffsetY;

    // 最终位置计算：世界位置 + 缩放锚点差值 - 缩放后的锚点偏移 + 纹理数据里带的偏移数据 (计算出绘制点的左上角)
    float Xpos = baseX - scaleOffsetX;
    float Ypos = baseY - scaleOffsetY;

    Xpos = (int)Xpos; // 强制转换为整数
    Ypos = (int)Ypos; // 强制转换为整数

    // 更新渲染信息
    _RenderGuidanceInfo.rect = {Xpos, Ypos, scaledWidth, scaledHeight};

    // 如果有阴影 计算阴影的渲染信息
    if (ShadowFlag)
        CalculateShadowData();
    _RenderGuidanceInfo.AnchorPos = {scaledAnchorOffsetX, scaledAnchorOffsetY};
    // 设置纹理透明度
    SDL_SetTextureAlphaMod(m_texture->GetTexture(), this->Alpha * 255);

    // 屏幕内检测
    int screenWidth = Game::GetInstance().Screen_W;
    int screenHeight = Game::GetInstance().Screen_H;
    bool isInScreen = (Xpos + scaledWidth >= 0 && Xpos <= screenWidth && Ypos + scaledHeight >= 0 && Ypos <= screenHeight);
    _RenderGuidanceInfo.IsInScreen = isInScreen;

    // this->Size = {scaledWidth, scaledHeight};
    _RenderGuidanceInfo.rotation = transformIter.rotation + transform.rotation;

    CalcRenderInfoFlag = false;
}

void Sprite::SetClipRect(SDL_Rect clipRect)
{
    CropFlag = true;
    CropRect = clipRect;
}

void Sprite::UnsetClipRect()
{
    CropFlag = false;
}

void Sprite::PreRender()
{
    if (CalcRenderInfoFlag && Visible)
        CalcRenderInfoLogic();
}

void Sprite::Render()
{
    if (!Visible)
        return;
    SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
    if (!m_texture)
        return;

    if (_RenderGuidanceInfo.IsInScreen && _RenderGuidanceInfo.Visible)
    {
        // 如果有阴影绘制阴影
        if (ShadowFlag)
        {
            std::array<int, 6> indices = {0, 1, 2, 1, 3, 2};
            SDL_RenderGeometry(renderer, m_texture->GetTexture(), vertices.data(), vertices.size(), indices.data(), indices.size());
        }

        if (_RenderGuidanceInfo.rotation != 0.f || _RenderGuidanceInfo.flip != SDL_FLIP_NONE)
        {
            SDL_FPoint AnchorPos = _RenderGuidanceInfo.AnchorPos;
            SDL_RenderCopyExF(renderer, m_texture->GetTexture(), NULL, &_RenderGuidanceInfo.rect, _RenderGuidanceInfo.rotation, &AnchorPos, _RenderGuidanceInfo.flip);
        }
        else
        {
            SDL_RenderCopyF(renderer, m_texture->GetTexture(), NULL, &_RenderGuidanceInfo.rect);
            // // 设置绘制颜色
            // SDL_SetRenderDrawColor(renderer, 255, 0, 0, 128);
            // // 绘制填充矩形
            // SDL_RenderFillRectF(renderer, &_RenderGuidanceInfo.rect);
        }
        Game::GetInstance().m_RenderCount++;
    }
}

void Sprite::Clear()
{
}

void Sprite::SetBlendMode(SDL_BlendMode blendMode)
{
    if (GetBlendMode() != blendMode)
        m_texture->SetBlendMode(blendMode);
}

SDL_BlendMode Sprite::GetBlendMode()
{
    return m_texture->GetBlendMode();
}

void Sprite::SetShadow()
{
    ShadowFlag = true;
    CalcRenderInfo();
}

void Sprite::CalculateShadowData()
{
    const float shearX = 1.3f;
    SDL_FRect guidance = _RenderGuidanceInfo.rect;
    float shadowW = guidance.w;        // 影子宽度（建议与角色宽度一致）
    float shadowH = guidance.h * 0.33; // 影子高度（可根据需求调整，比如角色高度的1/4）

    // 计算角色脚部中点坐标（底部中心，即需要重叠的锚点）
    float roleFootX = guidance.x + guidance.w / 2.0f + 3; // 角色X中心 + 位置偏移
    float roleFootY = guidance.y + guidance.h - 5;        // 角色底部Y坐标（脚的位置）

    // 计算错切后的顶点（局部坐标）
    vertices = {
        // 左上角（局部坐标）
        SDL_Vertex{{0.0f, 0.0f}, {0, 0, 0, 110}, {0.0f, 0.0f}},
        // 右上角（局部坐标）
        SDL_Vertex{{shadowW, 0.0f}, {0, 0, 0, 110}, {1.0f, 0.0f}},
        // 左下角（局部坐标）
        SDL_Vertex{{0.0f + shearX * shadowH, shadowH}, {0, 0, 0, 110}, {0.0f, 1.0f}},
        // 右下角（局部坐标）
        SDL_Vertex{{shadowW + shearX * shadowH, shadowH}, {0, 0, 0, 110}, {1.0f, 1.0f}}};

    bool flipHorizontal = (_RenderGuidanceInfo.flip & SDL_FLIP_HORIZONTAL) != 0; // 检查水平翻转标志
    bool flipVertical = (_RenderGuidanceInfo.flip & SDL_FLIP_VERTICAL) != 0;     // 检查垂直翻转标志
    // 应用纹理坐标翻转（核心逻辑）
    for (auto &v : vertices)
    {
        // 水平翻转：反转u坐标（0→1，1→0）
        if (flipHorizontal)
        {
            v.tex_coord.x = 1.0f - v.tex_coord.x;
        }
        // 垂直翻转：反转v坐标（0→1，1→0）
        if (flipVertical)
        {
            v.tex_coord.y = 1.0f - v.tex_coord.y;
        }
    }

    // 计算影子底部中点并对齐角色脚部（与之前逻辑一致）
    float shadowFootX = (vertices[2].position.x + vertices[3].position.x) / 2.0f;
    float shadowFootY = shadowH;
    float offsetX = roleFootX - shadowFootX;
    float offsetY = roleFootY - shadowFootY;

    // 应用位置偏移
    for (auto &v : vertices)
    {
        v.position.x += offsetX;
        v.position.y += offsetY;
    }
}
