#pragma once
#include <memory>
#include <filesystem>
#include <string>

#include "geometry/rect.h"
#include "misc/mapped_file/mapped_file.h"

struct image_heap_t;

/**
 * @struct font_v_metrics_t
 * @brief 字体垂直度量
 */
struct font_v_metrics_t {
	float ascent;                                                     // 上升高度
	float descent;                                                    // 下降高度
	float line_gap;                                                   // 行间距
	[[nodiscard]] float line_height() const { return ascent - descent + line_gap; } // 行高
};

struct glyph_shaped_t {
	int32_t         glyph_index; // Unicode码点
	Eigen::Vector2f offset;      // 相对位置偏移
	Eigen::Vector2f advance;     // 前进值
	rect_t<>        rect;        // 字形矩形区域
};

class font_face_interface {
public:
	virtual ~font_face_interface() = default;
	bool    load(const std::filesystem::path& in_path);

	void set_font_size(float in_size) { font_size_ = in_size; on_set_font_size(in_size); }
	[[nodiscard]] float get_font_size() const { return font_size_; }

	[[nodiscard]] virtual std::string get_font_name() const = 0;
	[[nodiscard]] virtual std::string get_font_family() const = 0;
	[[nodiscard]] virtual std::string get_font_style() const = 0;

	[[nodiscard]] virtual bool supports_color_emoji() const = 0;

	[[nodiscard]] virtual font_v_metrics_t get_metrics() const = 0;
	[[nodiscard]] virtual std::shared_ptr<image_heap_t> get_glyph_image(int32_t in_glyph_id) const = 0;
	[[nodiscard]] virtual std::shared_ptr<image_heap_t> get_emoji_image(int32_t in_glyph_id) const = 0;

	[[nodiscard]] virtual uint32_t find_glyph_index(uint32_t in_unicode_codepoint) const = 0;
	[[nodiscard]] virtual bool has_glyph(uint32_t in_unicode_codepoint) const { return find_glyph_index(in_unicode_codepoint) > 0; }

	[[nodiscard]] virtual float get_kerning(uint32_t in_first_glyph_id, uint32_t in_second_glyph_id) const = 0;
	[[nodiscard]] virtual glyph_shaped_t shape_glyph(uint32_t in_glyph_id) const = 0;
protected:
	virtual bool on_load() = 0;
	virtual void on_set_font_size(float in_size) {}
protected:
	std::shared_ptr<mapped_file> font_data_;         // 字体文件映射数据
private:
	float                        font_size_ = 16.0f; // 字体大小
};

bool init_font_system();
void destroy_font_system();
std::shared_ptr<font_face_interface> create_font_face(const std::filesystem::path& in_path);
