#pragma once
#include <string>
#include <memory>
#include <vector>
#include <unordered_map>
#include <Eigen/Dense>
#include "render/Renderer.h"
#include "render/TextureManager.h"
#include <array>


namespace ZL {
    
struct GlyphInfo {
    // std::shared_ptr<Texture> texture; // Texture for glyph
    Eigen::Vector2f uv;      // u,v координата левого верхнего угла в атласе (0..1)
    Eigen::Vector2f uvSize;  // ширина/высота в UV (0..1)
    
    Eigen::Vector2f size;     // glyph size in pixels
    Eigen::Vector2f bearing;  // offset from baseline
    unsigned int advance = 0; // advance.x in 1/64 pixels
};

class TextRenderer {
public:
    TextRenderer() = default;
    ~TextRenderer();

    bool init(Renderer& renderer, const std::string& ttfPath, int pixelSize, const std::string& zipfilename);
    void drawText(const std::string& text, float x, float y, float scale, bool centered, std::array<float, 4> color = { 1.f,1.f,1.f,1.f });

    // Clear cached meshes (call on window resize / DPI change)
    void ClearCache();

private:
    bool loadGlyphs(const std::string& ttfPath, int pixelSize, const std::string& zipfilename);

    Renderer* r = nullptr;

    std::unordered_map<uint32_t, GlyphInfo> glyphs;

    // OpenGL objects for a dynamic quad
    //unsigned int vao = 0;
    //unsigned int vbo = 0;

    // единый атлас для всех глифов
    std::shared_ptr<Texture> atlasTexture;
    size_t atlasWidth = 0;
    size_t atlasHeight = 0;
    float lineHeight = 32.0f;

	VertexRenderStruct textMesh;

    std::string shaderName = "text2d";

    // caching for static texts
    struct CachedText {
        VertexRenderStruct mesh;
        float width = 0.f; // in pixels, total advance
		float height = 0.f; // optional, not currently used
    };

	// key: text + "|" + scale + "|" + centered
    std::unordered_map<std::string, CachedText> cache;
};

} // namespace ZL