#ifndef JES_FONT_H
#define JES_FONT_H

#include "jes/Ref.h"
#include <ft2build.h>
#include FT_FREETYPE_H
#include "gl3w.h"
#include <unordered_map>
#include "GLTexture.h"

namespace jes
{
    class Font
    {
    public:
        class Glyph
        {
        public:
            Glyph();
            bool load(FT_Face face, FT_ULong char_code);
            int get_advance() { return m_advance; }
            void render()
            {
                m_texture->bind();
                glEnableVertexAttribArray(0);
                glBindBuffer(GL_ARRAY_BUFFER, m_vbo_id);
                glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, 0, 0);
                glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
            }
        protected:
            bool m_loaded;
            int m_advance;
            GLTextureRef m_texture;
            GLuint m_vbo_id;
        };
        typedef Ref<Glyph> GlyphRef;

        Font();
        ~Font();
        bool load(FT_Library ft, const char * fname, size_t size);
        int get_line_height() { return m_line_height; }
        int get_advance() { return m_advance; }
        int get_baseline_offset() { return m_baseline_offset; }
        GlyphRef get_glyph(FT_ULong char_code)
        {
            auto it = m_glyphs.find(char_code);
            if (it != m_glyphs.end())
                return it->second;
            GlyphRef g = load_glyph(char_code);
            m_glyphs[char_code] = g;
            return g;
        }
    protected:
        GlyphRef load_glyph(FT_ULong char_code);

        FT_Face m_face;
        int m_line_height;
        int m_advance;
        int m_baseline_offset;
        bool m_loaded;
        std::unordered_map<FT_ULong, GlyphRef> m_glyphs;
    };

    typedef Ref<Font> FontRef;
}

#endif
