#include "render/texture_sampler.h"
#include <algorithm> // For std::clamp
#include <iostream>

// 默认构造函数，设置标准配置
texture_sampler_builder::texture_sampler_builder() {
    // 初始化默认值
    desc_ = {};  // 零初始化所有字段

    // 根据sg_sampler_desc默认值设置
    desc_.min_filter = SG_FILTER_NEAREST;
    desc_.mag_filter = SG_FILTER_NEAREST;
    desc_.mipmap_filter = SG_FILTER_NEAREST;
    desc_.wrap_u = SG_WRAP_REPEAT;
    desc_.wrap_v = SG_WRAP_REPEAT;
    desc_.wrap_w = SG_WRAP_REPEAT;
    desc_.min_lod = 0.0f;
    desc_.max_lod = std::numeric_limits<float>::max();
    desc_.border_color = SG_BORDERCOLOR_OPAQUE_BLACK;
    desc_.compare = SG_COMPAREFUNC_NEVER;
    desc_.max_anisotropy = 1;
}

// 常用采样器类型的静态工厂方法
texture_sampler_builder texture_sampler_builder::create_default() {
    return texture_sampler_builder();
}

texture_sampler_builder texture_sampler_builder::create_pixel_art() {
    return texture_sampler_builder()
        .with_all_filters(SG_FILTER_NEAREST)
        .with_wrap(SG_WRAP_CLAMP_TO_EDGE);
}

texture_sampler_builder texture_sampler_builder::create_bilinear() {
    return texture_sampler_builder()
        .with_min_filter(SG_FILTER_LINEAR)
        .with_mag_filter(SG_FILTER_LINEAR)
        .with_mipmap_filter(SG_FILTER_NEAREST);
}

texture_sampler_builder texture_sampler_builder::create_trilinear() {
    return texture_sampler_builder()
        .with_all_filters(SG_FILTER_LINEAR);
}

texture_sampler_builder texture_sampler_builder::create_tileable() {
    return texture_sampler_builder()
        .with_all_filters(SG_FILTER_LINEAR)
        .with_wrap(SG_WRAP_REPEAT);
}

texture_sampler_builder texture_sampler_builder::create_linear_clamp() {
    return texture_sampler_builder()
        .with_all_filters(SG_FILTER_LINEAR)
        .with_wrap(SG_WRAP_CLAMP_TO_EDGE);
}

texture_sampler_builder texture_sampler_builder::create_shadow_map(sg_compare_func compare_func) {
    return texture_sampler_builder()
        .with_min_filter(SG_FILTER_LINEAR)
        .with_mag_filter(SG_FILTER_LINEAR)
        .with_wrap(SG_WRAP_CLAMP_TO_EDGE)
        .with_compare(compare_func)
        .with_border_color(SG_BORDERCOLOR_OPAQUE_WHITE);
}

texture_sampler_builder texture_sampler_builder::create_anisotropic(uint32_t anisotropy) {
    return texture_sampler_builder()
        .with_all_filters(SG_FILTER_LINEAR)
        .with_max_anisotropy(anisotropy);
}

// 流式接口配置方法
texture_sampler_builder& texture_sampler_builder::with_min_filter(sg_filter filter) {
    desc_.min_filter = filter;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_mag_filter(sg_filter filter) {
    desc_.mag_filter = filter;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_mipmap_filter(sg_filter filter) {
    desc_.mipmap_filter = filter;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_filters(sg_filter min_filter, sg_filter mag_filter, sg_filter mip_filter) {
    desc_.min_filter = min_filter;
    desc_.mag_filter = mag_filter;
    desc_.mipmap_filter = mip_filter;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_all_filters(sg_filter filter) {
    return with_filters(filter, filter, filter);
}

texture_sampler_builder& texture_sampler_builder::with_wrap_u(sg_wrap wrap) {
    desc_.wrap_u = wrap;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_wrap_v(sg_wrap wrap) {
    desc_.wrap_v = wrap;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_wrap_w(sg_wrap wrap) {
    desc_.wrap_w = wrap;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_wrap(sg_wrap wrap) {
    desc_.wrap_u = wrap;
    desc_.wrap_v = wrap;
    desc_.wrap_w = wrap;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_wrap(sg_wrap wrap_u, sg_wrap wrap_v, sg_wrap wrap_w) {
    desc_.wrap_u = wrap_u;
    desc_.wrap_v = wrap_v;
    desc_.wrap_w = wrap_w;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_lod_range(float min_lod, float max_lod) {
    // 确保min_lod <= max_lod
    if (min_lod > max_lod) {
        std::swap(min_lod, max_lod);
    }

    desc_.min_lod = min_lod;
    desc_.max_lod = max_lod;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_min_lod(float min_lod) {
    desc_.min_lod = min_lod;
    // 确保min_lod <= max_lod
    if (min_lod > desc_.max_lod) {
        desc_.max_lod = min_lod;
    }
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_max_lod(float max_lod) {
    desc_.max_lod = max_lod;
    // 确保min_lod <= max_lod
    if (desc_.min_lod > max_lod) {
        desc_.min_lod = max_lod;
    }
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_border_color(sg_border_color color) {
    desc_.border_color = color;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_compare(sg_compare_func compare) {
    desc_.compare = compare;
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_max_anisotropy(uint32_t anisotropy) {
    // 确保各向异性在有效范围内
    desc_.max_anisotropy = std::clamp(anisotropy, 1u, 16u);
    return *this;
}

texture_sampler_builder& texture_sampler_builder::with_label(const char* label) {
    desc_.label = label;
    return *this;
}

sg_sampler_desc texture_sampler_builder::build() const {
    return desc_;
}

std::shared_ptr<texture_sampler> texture_sampler_builder::create() const {
	return std::make_shared<texture_sampler>(build());
}

std::shared_ptr<texture_sampler> texture_sampler_builder::get_sampler(sampler_type in_type) {
	// 尝试从sampler_map_中查找
	const auto& it = sampler_map_.find(in_type);
	if (it != sampler_map_.end()) {
		return it->second;
	}

	// 如果没有找到，创建新的采样器并存储
	switch (in_type) {
		case sampler_type::default_:
			return sampler_map_[in_type] = create_default().create();
		case sampler_type::pixel_art:
			return sampler_map_[in_type] = create_pixel_art().create();
		case sampler_type::bilinear:
			return sampler_map_[in_type] = create_bilinear().create();
		case sampler_type::trilinear:
			return sampler_map_[in_type] = create_trilinear().create();
		case sampler_type::tileable:
			return sampler_map_[in_type] = create_tileable().create();
		case sampler_type::linear_clamp:
			return sampler_map_[in_type] = create_linear_clamp().create();
		case sampler_type::shadow_map:
			return sampler_map_[in_type] = create_shadow_map().create();
		case sampler_type::anisotropic:
			return sampler_map_[in_type] = create_anisotropic().create();
	}

	// 未知类型
	std::cerr << "Unknown sampler type: " << static_cast<int>(in_type) << std::endl;
	return nullptr;
}

void texture_sampler_builder::clear() {
	sampler_map_.clear();
}

texture_sampler::texture_sampler(const sg_sampler_desc& desc) {
	sampler_ = sg_make_sampler(desc);
}

texture_sampler::~texture_sampler() {
	if (sampler_.id != SG_INVALID_ID) {
		if (sg_isvalid())
			sg_destroy_sampler(sampler_);
	}
}

