#include "Chr_Animation.h"
#include "Global/Global_Game.h"
#include "Actor/Object/CharacterObject.h"
#include "Asset/Character/Chr_Equipment.h"

std::string Chr_Animation::FormatImgPath(std::string ImgPath, Animation::ReplaceData data)
{
    size_t pos = ImgPath.find("%04d");
    if (pos != std::string::npos)
    {
        ImgPath.replace(pos, 4, "%02d%02d");
    }
    char buffer[256];
    snprintf(buffer, sizeof(buffer), ImgPath.c_str(), data.Param1, data.Param2);
    std::string newPath = buffer;
    return newPath;
}

void Chr_Animation::CreateSkinmationBySlot(std::string actionName, std::string slotName, std::string path)
{
    // 皮肤在没有穿戴的情况下 格式化参数为0
    if (slotName == "skin_avatar")
    {
        // 如果穿戴了皮肤时装 读取variation
        RefPtr<Equipment> Equip = ((CharacterObject *)m_Parent)->_EquipmentManager->GetEquip(slotName);
        if (Equip)
        {
            Animation::ReplaceData Data(0, 0);
            for (auto &Variation : Equip->JobAni[this->chr_parent->Job])
            {
                Data.Param1 = Variation.ImgFormat[0];
                Data.Param2 = Variation.ImgFormat[1];
                // 构造好Ani以后 统一设置为不可见 然后放入ActionAnis表
                RefPtr<Animation> Ani = new Animation(path, FormatImgPath, Data);
                Ani->SetVisible(false);

                Ani->SetRenderZOrder(Variation.Layer);
                this->AddChild(Ani);
                ActionAnis[actionName].push_back(Ani);

                // 构造一下阴影对象 //TODO
                // RefPtr<Animation> ShadowAni = new Animation(path, FormatImgPath, Data);
                // ShadowAni->SetVisible(false);

                // chr_parent->_Shadow->AddChild(ShadowAni);
                // chr_parent->_Shadow->ActionAnis[actionName].push_back(ShadowAni);
            }
        }
    }
    else
    {
        RefPtr<Equipment> Equip = ((CharacterObject *)m_Parent)->_EquipmentManager->GetEquip(slotName);
        if (Equip)
        {
            // SDL_Log("CreateSkinmationBySlot %s", slotName.c_str());
            Animation::ReplaceData Data(0, 0);
            for (auto &Variation : Equip->JobAni[this->chr_parent->Job])
            {
                Data.Param1 = Variation.ImgFormat[0];
                Data.Param2 = Variation.ImgFormat[1];

                // 读取装备路径
                std::string EquipPath = Tool_TruncatePath(Equip->m_EquipmentPath);
                // 组装动画路径
                std::string AniPath = EquipPath + Variation.AnimationGroup + path.substr(path.find_last_of("/"), path.length());

                // 构造好Ani以后 统一设置为不可见 然后放入ActionAnis表
                RefPtr<Animation> Ani = new Animation(AniPath, FormatImgPath, Data);
                Ani->SetVisible(false);
                Ani->SetRenderZOrder(Variation.Layer);
                this->AddChild(Ani);
                ActionAnis[actionName].push_back(Ani);
            }
        }
    }
}

void Chr_Animation::Init(CharacterObject *parent)
{
    // 调用RenderBase类的初始化 才能挂上标签
    RenderBase::Init();
    parent->AddChild(this);
    chr_parent = parent;
    GlobalCharacterScript::CharacterConfig Config = Global_Game::GetInstance().CharacterConfigs[parent->Job];
    
    // 遍历所有动作Ani路径
    for (const auto &pair : Config.animationPath)
    {
        std::string ActionName = pair.first;
        std::string Path = std::string("character/" + Config.jobTag + "/" + Tool_toLowerCase(pair.second));

        // 遍历所有时装部位构造Ani
        for (auto &AvatarPartPair : AvatarPart)
        {
            std::string AvatarPartName = AvatarPartPair.first;
            CreateSkinmationBySlot(ActionName, AvatarPartName, Path);
        }
    }
    // 设置初始动作
    SetAction("rest");
}

void Chr_Animation::SetAction(std::string actionName)
{
    // 先将原动作的Ani设置为不可见
    for (auto Ani : ActionAnis[CurrentActionTag])
    {
        Ani->Reset();
        Ani->SetVisible(false);
    }
    // 再将新动作的Ani设置为可见
    for (auto Ani : ActionAnis[actionName])
    {
        Ani->SetVisible(true);
    }
    CurrentActionTag = actionName;

    // 设置阴影的动作
    if(chr_parent->_Shadow)chr_parent->_Shadow->SetAction(actionName);
}
