#pragma once

#include <frostbite2D/2d/sprite.h>
#include <frostbite2D/graphics/camera.h>
#include <frostbite2D/graphics/render_texture.h>
#include <functional>

namespace frostbite2D {

/// @brief 离屏画布节点。
///
/// 子节点通过 `AddCanvasChild()` 挂到内部画布树，只会在重绘到离屏纹理时参与渲染，
/// 不会像普通场景子节点那样直接显示到屏幕。
class CanvasActor : public Sprite {
public:
  CanvasActor();
  ~CanvasActor() override = default;

  bool Init(int width, int height);
  bool SetCanvasSize(int width, int height);
  Vec2 GetCanvasSize() const {
    return Vec2(static_cast<float>(canvasWidth_), static_cast<float>(canvasHeight_));
  }

  void SetClearColor(const Color& color);
  const Color& GetClearColor() const { return clearColor_; }

  void SetDirty();
  bool IsDirty() const { return dirty_; }
  bool Redraw();
  void SetCustomDrawCallback(std::function<void()> callback);
  void ClearCustomDrawCallback();

  void AddCanvasChild(RefPtr<Actor> child);
  void RemoveCanvasChild(RefPtr<Actor> child);
  void RemoveAllCanvasChildren();
  Actor* GetCanvasRoot() const { return canvasRoot_.Get(); }
  ActorList& GetCanvasChildren() { return canvasRoot_->GetChildren(); }
  const ActorList& GetCanvasChildren() const { return canvasRoot_->GetChildren(); }

  Ptr<Texture> GetOutputTexture() const;
  Ptr<RenderTexture> GetRenderTexture() const { return renderTexture_; }
  bool IsCanvasReady() const { return renderTexture_ && renderTexture_->IsValid(); }
  Camera& GetCanvasCamera() { return canvasCamera_; }
  const Camera& GetCanvasCamera() const { return canvasCamera_; }

  void OnUpdate(float deltaTime) override;
  void Render() override;

private:
  bool redrawInternal();
  void syncCanvasResources();

  RefPtr<Actor> canvasRoot_;
  Ptr<RenderTexture> renderTexture_ = nullptr;
  Camera canvasCamera_;
  Color clearColor_ = Colors::Transparent;
  int canvasWidth_ = 0;
  int canvasHeight_ = 0;
  bool dirty_ = true;
  std::function<void()> customDrawCallback_;
};

} // namespace frostbite2D
