#pragma once
#include <functional>
#include <SDL.h>
#include <string>
#include "Tool/RefObject.h"
#include "Tool/RefPtr.h"
#include "Tool/IntrusiveList.hpp"
#include "Tool/TagGed.h"
#include "math/Transform.hpp"
#include "math/Math.h"
using namespace ember;
class BaseNode : public RefObject, public TagGed, protected IntrusiveListValue<RefPtr<BaseNode>>
{

public:
    typedef std::function<void(float deltaTime)> UpdateCallback;

    using IntrusiveListValue<RefPtr<BaseNode>>::GetNext;
    using IntrusiveListValue<RefPtr<BaseNode>>::GetPrev;

public:
    // 更新时的回调函数
    UpdateCallback cb_update_;
    // 节点名称
    std::string m_Name;
    // 子节点列表
    IntrusiveList<RefPtr<BaseNode>> m_BaseNodes;
    // 指向父对象的指针
    BaseNode *m_Parent = nullptr;
    // 渲染层级
    int m_RenderZOrder = 0;
    // 二维仿射变换
    Transform transform;
    // 迭代的二维仿射变换
    Transform transformIter;
    //  锚点
    Vec2 Anchor = {0.f, 0.f};
    // 大小
    VecSize Size = {0, 0};
    // 透明度
    float Alpha = 1.f;
    // 混合模式
    LE_BlEND_MODE _BlendMode = NONE;
    // 是否显示
    bool Visible = true;
    // 计算渲染信息Flag (为了保证每帧只计算一次)
    bool CalcRenderInfoFlag = true;

public:
    BaseNode(/* args */);
    ~BaseNode();

public:
    virtual void Init();
    virtual void HandleEvents(SDL_Event *e);
    virtual void Update(float deltaTime);
    virtual void PreRender();
    virtual void Render();
    virtual void Clear();

    /// \~chinese
    /// @brief 设置更新时的回调函数
    void SetCallbackOnUpdate(const UpdateCallback &cb);

    void SetChildIterationTransform();

    // 计算渲染信息
    virtual void CalcRenderInfo();
    // 设置名字
    void SetName(std::string name);
    // 获取名字
    std::string GetName();
    // 设置渲染层级
    int GetRenderZOrder();
    // 获取渲染层级
    void SetRenderZOrder(int zOrder);
    // 重新排序
    void Reorder();
    // 添加子对象
    virtual void AddChild(RefPtr<BaseNode> child);
    // 移除子对象
    void RemoveChild(RefPtr<BaseNode> child);
    // 移除所有子对象
    void RemoveAllChild();
    //  被添加时
    virtual void OnAdded(BaseNode *node);
    // 设置迭代的二维仿射变换
    void SetIterationTransform(Transform transform);
    // 获取迭代的二维仿射变换
    Transform GetIterationTransform();
    // 设置二维仿射变换
    void SetTransform(Transform transform);
    // 获取二维仿射变换
    Transform GetTransform();

    // 设置迭代的坐标
    virtual void SetIterationPos(Vec2 pos);
    // 获取迭代的坐标
    Vec2 GetIterationPos();
    // 设置迭代的缩放
    virtual void SetIterationScale(Vec2 scale);
    // 获取迭代的缩放
    Vec2 GetIterationScale();
    // 设置迭代的旋转角度
    virtual void SetIterationRotation(float angle);
    // 获取迭代的旋转角度
    float GetIterationRotation();

    // 设置坐标
    virtual void SetPos(Vec2 pos);
    // 获取坐标
    Vec2 GetPos();
    // 获取世界坐标
    Vec2 GetWorldPos();
    // 设置缩放
    virtual void SetScale(Vec2 scale);
    // 获取缩放
    Vec2 GetScale();
    // 设置旋转角度
    virtual void SetRotation(float angle);
    // 获取旋转角度
    float GetRotation();
    // 设置中心点
    virtual void SetAnchor(Vec2 anchor);
    // 获取中心点
    Vec2 GetAnchor();
    // 设置大小
    virtual void SetSize(VecSize size);
    // 获取大小
    VecSize GetSize();
    // 设置是否显示
    virtual void SetVisible(bool visible);
    // 获取是否显示
    bool GetVisible();
    // 设置透明度
    virtual void SetAlpha(float alpha);
    // 获取透明度
    float GetAlpha();
    // 设置混合模式
    void SetBlendMode(LE_BlEND_MODE mode);
    // 获取混合模式
    LE_BlEND_MODE GetBlendMode();

    //获取父对象
    BaseNode *GetParent();
};
