#ifndef RENDERER2D_HPP
#define RENDERER2D_HPP

#include "open_engine/renderer/editor_camera.hpp"
#include "open_engine/renderer/subtexture2d.hpp"
#include "open_engine/orthographic_camera.hpp"
#include "open_engine/renderer/texture.hpp"
#include "open_engine/renderer/camera.hpp"
#include "open_engine/ref_scope.hpp"

#include <glm/fwd.hpp>

namespace OpenEngine {
    struct Transform
    {
        glm::vec3 position = {0.0f, 0.0f, 0.0f};
        glm::vec3 size = {1.0f, 1.0f, 1.0f};
        float rotation = 0.0f;
    };

    struct Statistics
    {
        uint32_t draw_calls = 0;
        uint32_t quad_count = 0;

        uint32_t GetTotalVertexCount() { return quad_count * 4; };
        uint32_t GetTotalIndexCount() { return quad_count * 6; };
    };

    class Renderer2D
    {
        public:
            static void Init();
            static void Shutdown();

            static void BeginScene(const OrthographicCamera& camera);
            static void BeginScene(const Camera& camera, const glm::mat4& transform);
            static void BeginScene(const EditorCamera& camera);
            static void EndScene();
            static void Flush();

            static void DrawQuad(const Transform& transform_data,
                    const glm::vec4& color, int entity_id);
            static void DrawQuad(const Transform& transform_data,
                    const Ref<Texture2D>& texture, int entity_id,
                    float tiling_factor = 1.0f);
            static void DrawQuad(const Transform& transform_data,
                    const Ref<Texture2D>& texture, const glm::vec4& color,
                    int entity_id, float tiling_factor = 1.0f);
            static void DrawQuad(const Transform& transform_data,
                    const Ref<Subtexture2D>& subtexture, int entity_id,
                    float tiling_factor = 1.0f);

            static void DrawQuad(const glm::mat4& transform,
                    const glm::vec4& color, int entity_id);
            static void DrawQuad(const glm::mat4& transform,
                    const Ref<Texture2D>& texture, int entity_id,
                    float tiling_factor = 1.0f);
            static void DrawQuad(const glm::mat4& transform,
                    const Ref<Texture2D>& texture, const glm::vec4& color,
                    int entity_id, float tiling_factor = 1.0f);
            static void DrawQuad(const glm::mat4& transform,
                    const Ref<Subtexture2D>& subtexture, int entity_id,
                    float tiling_factor = 1.0f);

            static void ResetStats();
            static const Statistics& GetStats();

        private:
            static void FlushAndReset();

            static void StartBatch();
            static void NextBatch();
    };
}

#endif // RENDERER2D_HPP
