/*Copyright (C) 2010-2023 Duncan Deveaux

This file is part of Hikou no mizu.

Hikou no mizu is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Hikou no mizu is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Hikou no mizu.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef DEF_TEXT
#define DEF_TEXT

#include "Drawable.hpp"
#include "Tools/Utf8.hpp"
#include "Structs/Color.hpp"

#include <vector>
#include <string>

class Font;
class Glyph;

/// Struct to pair a glyph and its associated kerning value
struct GlyphKerning
{
    GlyphKerning(const Glyph &glyphRef, float kerningVal) :
    glyph(glyphRef), kerning(kerningVal) {}

    const Glyph &glyph;
    float kerning;
};

/// Similar to a Box, but uses {left, right, top, bottom} instead of
/// {left, top, width, height}, useful to encode both the height (bottom - top)
/// and the height over the glyph origin (-top) at the same time
struct BoundingBox
{
    BoundingBox() : left(0.f), right(0.f), top(0.f), bottom(0.f) {}
    float left, right, top, bottom;
};

class Text : public Drawable
{
    public:
        Text();
        Text(const Utf8::utf8_string &text, Font &font);
        void draw() override;

        void setFont(Font &font);
        const Font *getFont() const;

        void setText(const Utf8::utf8_string &text);
        const std::string &getText() const;

        void setColor(const Color &color);

        float getWidth() const;
        float getHeight() const;
        float getOriginHeight() const;

        /// Returns the bounding box of the text
        /// from glyph ix_begin (included) to ix_end (excluded)
        BoundingBox getBoundingBox(std::size_t ix_begin,
                                   std::size_t ix_end) const;

    private:
        void loadGlyphs();

        Font *m_font;

        Utf8::utf8_string m_text; ///< Utf8-encoded source text
        std::vector<GlyphKerning> m_glyphs; ///< Glyphs and kerning values

        Color m_color;
        float m_width, m_height, m_originHeight;
};

#endif
