/*
文件名:AnimationClass.nut
路径:Core/BaseClass/AnimationClass/AnimationClass.nut
创建日期:2024-05-07	23:25
文件用途:动画类
*/
class Animation extends Actor {

    //Ani是否可用
    IsUsability = true;

    //当前帧数
    CurrentFrameIndex = 0;
    //总帧数
    TotalFrameIndex = 0;
    //当前帧时间
    CurrentIndexT = 0;
    //当前帧
    CurrentFrame = null;
    //下帧延迟
    NextFrameDelay = 9999999;
    //状态机对象(只有存在时才有KeyFlag)
    StateMachine = null;

    //Ani的标签
    AnimationFlag = null;
    //帧对象数组
    FrameArr = null;
    //图片精灵帧对象
    SpriteArr = null;

    //Ani类型
    Type = "normal";
    //Ani路径
    AniPath = null;

    //附加选项
    AdditionalOptions = null;

    constructor(...) {
        base.constructor();

        //精灵帧数组
        SpriteArr = [];
        //帧数组
        FrameArr = [];

        //判断是否有特殊处理
        if (vargv.len() > 1) {
            AdditionalOptions = vargv[1];
        }
        //初始化数据
        InitData(vargv[0]);
    }


    function InitData(Data) {
        local Buf;
        if (type(Data) == "table") {
            Buf = Data;
        }
        //从PVF数据加载
        else if (type(Data) == "string") {
            Data = String.RegRealPath(Data);
            Buf = sq_DeepCopy(ScriptData.GetAni(Data));
            //还需要判断一下有没有als
            local AlsBuf = ScriptData.GetFile(Data + ".als");
            if (AlsBuf) {
                local m_data = ScriptData.GetFileData(Data + ".als", function(DataTable, Data) {
                    local Anilist = {};
                    while (!Data.Eof()) {
                        local Pack = Data.Get();
                        if (Pack == "[use animation]") {
                            local AniPath = Data.Get();
                            local AniKey = Data.Get();
                            if (!(AniKey in Anilist))
                                Anilist[AniKey] <- {};
                            Anilist[AniKey].path <- AniPath;
                        } else if (Pack == "[none effect add]") {
                            local AniLayer = [Data.Get(), Data.Get()];
                            local AniKey = Data.Get();
                            if (!(AniKey in Anilist))
                                Anilist[AniKey] <- {};
                            Anilist[AniKey].layer <- AniLayer;
                        } else if (Pack == "[add]") {
                            local AniLayer = [Data.Get(), Data.Get()];
                            local AniKey = Data.Get();
                            if (!(AniKey in Anilist))
                                Anilist[AniKey] <- {};
                            Anilist[AniKey].layer <- AniLayer;
                        }
                    }
                    DataTable.Anilist <- Anilist;
                    DataTable.dirpath <- DataTable.filepath.slice(0, DataTable.filepath.lastfind("/") + 1);
                });
                foreach(Index, Info in m_data.Anilist) {
                    local anibuf = Animation(m_data.dirpath + Info.path.tolower());
                    anibuf.SetZOrder(Info.layer[1]);
                    Addchild(anibuf);
                }
            }
        }

        if (Buf) {
            AniPath = Buf.filepath;
            AnimationFlag = Buf.Flag;
            FrameArr = Buf.Frame;
            foreach(FrameObj in FrameArr) {
                //如果有附加处理 格式化
                if (AdditionalOptions && AdditionalOptions.rawin("ImgFormat")) FrameObj.Img_Path = AdditionalOptions["ImgFormat"](FrameObj.Img_Path);

                local SpriteFramebuf = CL_SpriteFrameObject("sprite/" + FrameObj.Img_Path, FrameObj.Img_Index);
                local Spritebuf = CL_SpriteObject();
                Spritebuf.SetFrame(SpriteFramebuf);

                //线性减淡
                if ("GRAPHIC_EFFECT_LINEARDODGE" in FrameObj.Flag) {
                    Spritebuf.SetMode(0);
                }

                //坐标
                Spritebuf.SetPosition(FrameObj.Pos);


                SpriteArr.append(Spritebuf);
            }
        } else {
            error("创建Ani失败,找不到Ani数据");
        }

        //初始化完毕 如果是第一次初始化 而非重新构造 设置大小为第0帧大小否则天空 地板等依靠大小的初始化会有问题
        if (CurrentIndexT == 0) SetSize(SpriteArr[0].GetSize());
        //记录总帧数
        TotalFrameIndex = FrameArr.len();
    }

    //被添加时  要刷新一下当前帧
    function OnAddchild(Parent) {
        FlushFrame(0);
    }

    //重置Ani
    function Reset() {
        IsUsability = true;
        FlushFrame(0);
    }

    //赋予状态机
    function BindenvStateMachine(gM) {
        StateMachine = gM;
    }

    //获取当前帧信息
    function GetCurrentFrameInfo() {
        return FrameArr[CurrentFrameIndex];
    }

    function FlushFrame(Index) {
        //同步当前帧
        CurrentFrameIndex = Index;
        //移除上一帧
        if (CurrentFrame) Removechild(CurrentFrame);
        //当前帧更换为本帧
        CurrentFrame = SpriteArr[CurrentFrameIndex];
        Addchild(SpriteArr[CurrentFrameIndex]);

        local FrameInfo = FrameArr[CurrentFrameIndex];
        local FlagBuf = FrameInfo.Flag;
        NextFrameDelay = FrameInfo.Delay;
        //关键帧
        if ("SET_FLAG" in FlagBuf) {
            if (StateMachine && StateMachine.State != -1) StateMachine.ChangeAniKeyFlag(FlagBuf.SET_FLAG);
        }
        //播放音效
        if ("PLAY_SOUND" in FlagBuf) {
            Sq_PlaySoundEffect(FlagBuf.PLAY_SOUND);
        }
        //缩放
        if ("IMAGE_RATE" in FlagBuf) {
            SetScale(FlagBuf.IMAGE_RATE.x, FlagBuf.IMAGE_RATE.y);
        }

        //Ani对象的大小同步为精灵帧对象的大小
        if (CurrentFrame) SetSize(CurrentFrame.GetSize());
    }

    //override
    function OnUpdate(dt) {
        //可用性检查
        if (IsUsability) {
            //累加当前帧时间
            CurrentIndexT += dt;

            //当前帧时间 超过 当前帧延迟就需要切换帧了
            if (CurrentIndexT >= NextFrameDelay) {
                CurrentIndexT = 0;
                //如果当前帧小于总帧数就切换
                if (CurrentFrameIndex<(TotalFrameIndex - 1)) {
                    FlushFrame(CurrentFrameIndex + 1);
                }
                //说明播放完毕了
                else {
                    //如果有循环
                    if ("LOOP" in AnimationFlag) {
                        FlushFrame(0);
                    }
                    //没有循环触发状态机回调
                    else {
                        //将不再可用
                        IsUsability = false;
                        if (StateMachine && StateMachine.State != -1) StateMachine.ChangeAniEndFlag();
                    }
                }
            }
        }
        //Animation类下只会有精灵 因此不需要对子对象进行更新
        // base.OnUpdate(dt);
    }
}