/******************************************************************************
*	File		-	text_renderer.h
*	Author		-	Joey Pollack
*	Date		-	2022/08/15 (y/m/d)
*	Mod Date	-	2022/08/15 (y/m/d)
*	Description	-	manage fonts and render text
******************************************************************************/

#ifndef LUNARIUM_TEXT_RENDERER_H_
#define LUNARIUM_TEXT_RENDERER_H_

#include <core/common_defs.h>
#include <utils/op_res.h>

#include <glm/glm.hpp>
#include <vector>
#include <map>

struct FT_LibraryRec_;
typedef struct FT_LibraryRec_ * FT_Library;

struct FT_FaceRec_;
typedef struct FT_FaceRec_*  FT_Face;

namespace lunarium
{
    class Renderer2D;
    class Texture;
    class TextRenderer
    {
    private:
        friend class Renderer2D;
        OpRes Initialize();
        void DrawString(Renderer2D& r, u32 font_id, const char* str, Rectangle bounding_box, Color c, float scale);

        // DEBUG
        Texture* GetDebugTexture();

    public:

        int LoadFont(const char* fontFile, const char* name, float size = 12.0f, int weight = 400);
		int LoadFont(const unsigned char* fontData, int dataSize, const char* name, float size = 12.0f, int weight = 400);
        
	private: // HELPERS
		int CreateFont(const char* name, FT_Face face, float size = 12.0f, int weight = 400);

    private:
        Texture* mDebugTexture;

        struct Character
		{
            u8              glyph;
            u8*             PixelDataBuffer;   // Temporary storage for the character's pixel data - this should be cleanup after the font texture is created
			u32             TextureDataWidthOffset;     // how far into the row does this chars texture data begin
			u32             TextureDataHeightOffset;     // how far into the col does this chars texture data begin
			Sizei			Size;       // Size of glyph
			glm::vec2		Bearing;    // Offset from baseline to left/top of glyph
			int				DownShift;	// Size/Amount of glyph below the baseline
			unsigned int	Advance;    // Offset to advance to next glyph
		};

        struct Font
        {
            Texture* FontTexture;
            std::string Name;
			// The tallest character that does not go below the base line
			// This is also the distance from the string Y position to the baseline
			i32 MaxHeight;

			// This is the max distance a char will go below the baseline
			u32 MaxDownShift;
			std::map<u8, Character> CharSet;
			Font() : MaxHeight(0), MaxDownShift(0)
			{}
        };

        
        FT_Library mFTHandle;
        std::vector<Font> mFonts;

    private:
        void FreeTempPixelData(std::map<u8, Character>& char_set);
    };
}

#endif	// LUNARIUM_TEXT_RENDERER_H_