//
// Created by 46944 on 25-4-1.
//

#include "freetype_interface.h"

#include "pixel.h"
#include "freetype/ftadvanc.h"
#include "freetype/ftcolor.h"
#include "freetype/ftglyph.h"
#include "freetype/ftlcdfil.h"
#include "geometry/dpi_helper.h"
#include "interface/image_interface.h"

FT_Library library_;

void freetype_bitmap_deleter(image_heap_t* in_data) {
	if (in_data == nullptr) {
		return;
	}
	if (in_data->data != nullptr) {
		const auto data = (uint8_t*)in_data->data;
		delete[] data;
		in_data->data = nullptr;
	}
	delete in_data;
}

std::string freetype_interface::get_font_family() const {
	if (face_ == nullptr) {
		return "unknown font";
	}
	return face_->family_name ? face_->family_name : "unknown font";
}

std::string freetype_interface::get_font_style() const {
	if (face_ == nullptr) {
		return "unknown font";
	}
	return face_->style_name ? face_->style_name : "unknown font";
}

bool freetype_interface::supports_color_emoji() const {
	return FT_HAS_COLOR(face_) || FT_HAS_SBIX(face_) || FT_HAS_SVG(face_);
}

font_v_metrics_t freetype_interface::get_metrics() const {
	font_v_metrics_t metrics{};
	// 使用当前字体大小下的度量信息
	metrics.ascent = face_->size->metrics.ascender >> 6;
	metrics.descent = -face_->size->metrics.descender >> 6; // FreeType中descent为负值
	metrics.line_height = face_->size->metrics.height >> 6;
	return metrics;
}

std::shared_ptr<image_heap_t> freetype_interface::get_glyph_image(int32_t in_glyph_id) const {
	if (in_glyph_id == 0) {
		return nullptr;
	}

	// 加载字形
	FT_Load_Glyph(face_, in_glyph_id, FT_LOAD_RENDER);
	if (face_->glyph->format != FT_GLYPH_FORMAT_BITMAP) {
		return nullptr;
	}
	// FT_Render_Glyph(face_->glyph, FT_RENDER_MODE_LCD);

	auto& bitmap = face_->glyph->bitmap;

	// 创建位图
	// 这里使用了一个自定义的删除器来释放位图数据
	std::shared_ptr<image_heap_t> image(new image_heap_t(), freetype_bitmap_deleter);
	image->width                            = bitmap.width;
	image->height                           = bitmap.rows;
	image->pixel_format                     = SG_PIXELFORMAT_R8;
	image->data                             = new uint8_t[image->width * image->height];
	std::memcpy(image->data, face_->glyph->bitmap.buffer, image->width * image->height);

	return image;
}

std::shared_ptr<image_heap_t> freetype_interface::get_emoji_image(int32_t in_glyph_id) const {
	if (in_glyph_id == 0) {
		return nullptr;
	}

	// 加载字形
	FT_Load_Glyph(face_, in_glyph_id, FT_LOAD_RENDER | FT_LOAD_COLOR | FT_LOAD_FORCE_AUTOHINT);
	if (face_->glyph->format != FT_GLYPH_FORMAT_BITMAP) {
		return nullptr;
	}

	FT_Bitmap& bitmap = face_->glyph->bitmap;

	// 创建位图
	// 这里使用了一个自定义的删除器来释放位图数据
	std::shared_ptr<image_heap_t> image(new image_heap_t(), freetype_bitmap_deleter);
	image->width        = bitmap.width;
	image->height       = bitmap.rows;
	image->pixel_format = SG_PIXELFORMAT_BGRA8;
	image->data         = new uint8_t[image->width * image->height * 4];

	// 初始化为透明
	clear_bitmap(image.get());
	attach_bitmap(bitmap, image.get());

	return image;
}

uint32_t freetype_interface::find_glyph_index(uint32_t in_unicode_codepoint) const {
	return FT_Get_Char_Index(face_, in_unicode_codepoint);
}

float freetype_interface::get_kerning(uint32_t in_first_glyph_id, uint32_t in_second_glyph_id) const {
	if (!FT_HAS_KERNING(face_)) {
		return 0.0f;
	}
	FT_Vector kerning;
	if (FT_Get_Kerning(face_, in_first_glyph_id, in_second_glyph_id, FT_KERNING_DEFAULT, &kerning) != 0) {
		return 0.0f;
	}
	return kerning.x >> 6;
}

glyph_shaped_t freetype_interface::shape_glyph(uint32_t in_glyph_id) const {
	glyph_shaped_t out{};

	// 加载字形 - 使用 FT_LOAD_DEFAULT 而非 FT_LOAD_NO_BITMAP
	if (FT_Load_Glyph(face_, in_glyph_id, FT_LOAD_DEFAULT | FT_LOAD_FORCE_AUTOHINT) != 0) {
		return out;
	}

	// 获取字形度量
	FT_GlyphSlot slot = face_->glyph;

	// 设置基本信息
	out.glyph_index = in_glyph_id;

	// 计算字形的前进量 (26.6 固定小数点格式转为浮点数)
	out.advance.x() = slot->advance.x >> 6;
	out.advance.y() = slot->metrics.vertAdvance >> 6;

	// 字形偏移量
	out.offset.x() = static_cast<float>(slot->bitmap_left);
	out.offset.y() = static_cast<float>(-slot->bitmap_top);

	// 水平基线
	out.hori_bearing.x() = static_cast<float>(slot->metrics.horiBearingX) / 64.0f;
	out.hori_bearing.y() = static_cast<float>(slot->metrics.horiBearingY) / -64.0f;
	// 垂直基线
	out.vert_bearing.x() = static_cast<float>(slot->metrics.vertBearingX) / 64.0f;
	out.vert_bearing.y() = static_cast<float>(slot->metrics.vertBearingY) / 64.0f;

	// 字形矩形 - 直接使用位图尺寸
	if (slot->format == FT_GLYPH_FORMAT_BITMAP) {
		// 位图字形
		out.rect.set_position({ 0, 0 });
		out.rect.set_size({
			static_cast<float>(slot->bitmap.width),
			static_cast<float>(slot->bitmap.rows)
		});
	} else {
		// 非位图字形 - 使用轮廓边界盒
		FT_Glyph glyph;
		if (FT_Get_Glyph(slot, &glyph) != 0) {
			return out;
		}

		FT_BBox bbox;
		FT_Glyph_Get_CBox(glyph, FT_GLYPH_BBOX_PIXELS, &bbox);

		out.rect.set_position({ bbox.xMin, bbox.yMin });
		out.rect.set_size({
			static_cast<float>(bbox.xMax - bbox.xMin),
			static_cast<float>(bbox.yMax - bbox.yMin)
		});

		FT_Done_Glyph(glyph);
	}

	return out;
}

bool freetype_interface::on_load() {
	return FT_New_Memory_Face(library_, font_data_->get_u8(), font_data_->get_size(), 0, &face_) == 0;
}

void freetype_interface::on_set_font_size(float in_size) {
	font_face_interface::on_set_font_size(in_size);
	const FT_F26Dot6 font_size = static_cast<FT_F26Dot6>(in_size * 64);
	FT_Set_Char_Size(face_, 0, font_size, dpi_helper::dpi_x(), dpi_helper::dpi_y());
}

void freetype_interface::clear_bitmap(image_heap_t* in_image) {
	memset(in_image->data, 0, in_image->width * in_image->height * 4);
}

void freetype_interface::attach_bitmap(const FT_Bitmap& in_bitmap, image_heap_t* in_image) {
	// 将FreeType位图数据复制到新分配的内存中
	switch (in_bitmap.pixel_mode) {
		case FT_PIXEL_MODE_BGRA:
			// 彩色emoji (BGRA -> RGBA)
				for (unsigned int y = 0; y < in_bitmap.rows; y++) {
					for (unsigned int x = 0; x < in_bitmap.width; x++) {
						unsigned char* src = in_bitmap.buffer + (y * in_bitmap.pitch + x * 4);
						unsigned char* dst = (uint8_t*)in_image->data + (y * in_image->width + x) * 4;

						// BGRA -> RGBA
						dst[0] += src[2]; // R <- B
						dst[1] += src[1]; // G <- G
						dst[2] += src[0]; // B <- R
						dst[3] += src[3]; // A <- A
					}
				}
		break;

		case FT_PIXEL_MODE_GRAY:
			// 灰度图转RGBA
				for (unsigned int y = 0; y < in_bitmap.rows; y++) {
					for (unsigned int x = 0; x < in_bitmap.width; x++) {
						unsigned char  gray = in_bitmap.buffer[y * in_bitmap.pitch + x];
						unsigned char* dst  = (uint8_t*) in_image->data + (y * in_image->width + x) * 4;

						dst[0] = gray; // R
						dst[1] = gray; // G
						dst[2] = gray; // B
						dst[3] = gray; // A
					}
				}
		break;

		default:
		break;
	}
}

bool init_font_system() {
	if (FT_Init_FreeType(&library_)) {
		return false;
	}
	FT_Library_SetLcdFilter(library_, FT_LCD_FILTER_DEFAULT);
	return true;
}

void destroy_font_system() {
	FT_Done_FreeType(library_);
}

std::shared_ptr<font_face_interface> create_font_face(const std::filesystem::path& in_path) {
	auto font_face = std::make_shared<freetype_interface>();
	if (!font_face->load(in_path)) {
		return nullptr;
	}
	return font_face;
}
