#pragma once

#include <frostbite2D/graphics/types.h>
#include <frostbite2D/graphics/texture.h>
#include <frostbite2D/graphics/shader.h>
#include <frostbite2D/graphics/shader_manager.h>
#include <frostbite2D/graphics/batch.h>
#include <frostbite2D/graphics/camera.h>
#include <string>

namespace frostbite2D {

class Renderer {
public:
  static Renderer& get();
  
  bool init();
  void shutdown();
  
  void beginFrame();
  void endFrame();
  void flush();
  
  void setViewport(int x, int y, int width, int height);
  void setClearColor(float r, float g, float b, float a = 1.0f);
  void setClearColor(const Color& color);
  void clear(uint32_t flags);
  
  void setCamera(Camera* camera);
  Camera* getCamera() { return camera_; }
  
  void drawQuad(const Vec2& pos, const Size& size, float cr = 1.0f, float cg = 1.0f,
                float cb = 1.0f, float ca = 1.0f);
  void drawQuad(const Vec2& pos, const Size& size, Ptr<Texture> texture);
  void drawQuad(const Rect& rect, const Color& color);
  
  void drawSprite(const Vec2& pos, const Size& size, Ptr<Texture> texture);
  void drawSprite(const Vec2& pos, const Rect& srcRect, const Vec2& texSize, 
                  Ptr<Texture> texture, const Color& color = Color(1, 1, 1, 1));
  void setupBlendMode(BlendMode mode);
  
  ShaderManager& getShaderManager() { return shaderManager_; }
  Batch& getBatch() { return batch_; }
  
private:
  Renderer();
  // ~Renderer() 在 shutdown() 中手动调用销毁
  
  void updateUniforms();
  
  ShaderManager shaderManager_;
  Batch batch_;
  Camera* camera_ = nullptr;
  
  uint32_t clearColor_[4] = {0, 0, 0, 255};
  int viewportX_ = 0;
  int viewportY_ = 0;
  int viewportWidth_ = 1280;
  int viewportHeight_ = 720;
  
  bool initialized_ = false;
  
  Renderer(const Renderer&) = delete;
  Renderer& operator=(const Renderer&) = delete;
};

}
