/*
 * MIT License
 * Author: Mark Allyn
 *
 * left_panel.h — FreeType-based text renderer and the left-side
 * description/control panel common to all scope displays.
 *
 * TextRenderer handles FreeType initialisation, glyph atlas building,
 * and per-string quad generation.  It is shared by the Graticule for
 * bearing labels and by each scope for its description text.
 *
 * LeftPanel wraps TextRenderer for the fixed description pane on the
 * left side of the window.
 */

#pragma once
#include <glad/glad.h>
#include <string>
#include <vector>
#include <array>
#include "settings.h"

// ================================================================
// TextRenderer — FreeType glyph-atlas renderer
// ================================================================

struct GlyphMetric {
    float atlasU, atlasV;    // top-left of glyph in atlas [0,1]
    float atlasW, atlasH;    // glyph size in atlas [0,1]
    float bearX, bearY;      // pixel bearing (offset from cursor origin)
    float sizeW, sizeH;      // glyph pixel dimensions
    float advanceX;          // horizontal advance in pixels
};

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

    // Load font; build atlas at given pixel height.
    // shaderDir: path with trailing slash.
    bool init(const std::string& fontPath,
              int pixelHeight,
              const std::string& shaderDir);

    // Draw text at screen position (x, y = top of first line, top-left origin).
    // scale: relative size multiplier (1.0 = loaded size).
    // centred: centre each glyph string around the given x.
    void renderText(const std::string& text,
                    float x, float y,
                    float scale,
                    float r, float g, float b,
                    float viewportW, float viewportH,
                    bool centred = false) const;

    // Measure rendered width of a string at given scale.
    float measureWidth(const std::string& text, float scale) const;

    int basePixelHeight() const { return pixelH_; }

private:
    GLuint atlasTex_ = 0;
    GLuint prog_     = 0;
    GLuint vao_      = 0;
    GLuint vbo_      = 0;  // dynamic quad buffer

    int   pixelH_    = 16;
    int   atlasW_    = GLYPH_ATLAS_SIZE;
    int   atlasH_    = GLYPH_ATLAS_SIZE;

    static const int FIRST_CHAR = 32;
    static const int LAST_CHAR  = 127;
    static const int CHAR_COUNT = LAST_CHAR - FIRST_CHAR;

    std::array<GlyphMetric, LAST_CHAR - FIRST_CHAR> metrics_{};
    bool initialised_ = false;
};

// ================================================================
// LeftPanel — description + control table for one scope
// ================================================================

class LeftPanel {
public:
    explicit LeftPanel(TextRenderer& tr) : tr_(tr) {}

    // Replace the displayed text lines.
    void setLines(const std::vector<std::string>& lines) { lines_ = lines; }

    // Add a blank separator line.
    void addBlank() { lines_.push_back(""); }

    // Render the panel.  panelW/H: dimensions in screen pixels.
    void render(float panelW, float panelH,
                float viewportW, float viewportH) const;

private:
    TextRenderer& tr_;
    std::vector<std::string> lines_;

    static constexpr float MARGIN_X  = 10.0f;
    static constexpr float MARGIN_Y  = 12.0f;
    static constexpr float LINE_GAP  = 4.0f;   // extra pixels between lines
};
