#pragma once
/**
 * @file render_context.h
 * @brief 定义渲染上下文的抽象接口
 *
 * 本文件定义了mirage_render_context抽象类，提供了渲染上下文的基本操作接口，
 * 包括初始化、清理、更新、环境配置和表面设置等功能。实际的渲染上下文实现
 * 将继承此类并实现这些操作。
 */

#include "misc/mirage_type.h"
#include "sokol_gfx.h"

/**
 * @struct mirage_window_state
 * @brief 存储窗口渲染状态的结构
 *
 * 维护与特定窗口关联的渲染资源和状态，包括GPU缓冲区、交换链和渲染设置。
 * 这是一个虚拟基类，不同平台可以提供特定实现。
 */
struct mirage_window_state {
    /**
     * @brief 虚析构函数
     *
     * 确保派生类可以正确清理资源。
     */
    virtual ~mirage_window_state() {
        clear();
    }

    /**
     * @brief 清理资源
     */
    void clear() { on_clear(); }

    /** 顶点缓冲区 */
    sg_buffer buffer{};

    /** 窗口交换链 */
    sg_swapchain swapchain{};

    /** 渲染绑定 */
    sg_bindings bindings{};

    /** 渲染管线 */
    sg_pipeline pipeline{};

    /** 垂直同步标志 */
    bool vsync = true;

    /**
     * @brief 清理资源
     *
     * 虚方法，由派生类实现以释放平台特定资源。
     */
    virtual void on_clear() {}

    /**
     * @brief 呈现渲染内容
     *
     * 虚方法，由派生类实现以将渲染内容呈现到窗口。
     */
    virtual void present() {}

    /**
     * @brief 重建交换链
     * @param size 新的窗口大小
     *
     * 当窗口大小改变时重建交换链。虚方法，由派生类实现。
     */
    virtual void rebuild_swapchain(const Eigen::Vector2i& size) {}
};

/**
 * @class mirage_render_context
 * @brief 渲染上下文的抽象基类
 *
 * 定义了渲染上下文必须实现的操作接口，包括生命周期管理、
 * 时间更新和渲染环境配置等。不同的渲染后端可以通过继承此类
 * 实现特定的渲染逻辑。
 */
class mirage_render_context {
public:
	mirage_render_context() {
		instance_ = this;
	}

	/**
	 * @brief 虚析构函数
	 *
	 * 确保派生类可以正确析构。
	 */
	virtual ~mirage_render_context() {
		instance_ = nullptr;
	}

	//-------------- 生命周期管理 --------------

	/**
	 * @brief 初始化渲染上下文
	 * @return 初始化是否成功
	 *
	 * 在渲染开始前准备渲染上下文的资源和状态。
	 */
	virtual bool init() { return false; }

	/**
	 * @brief 完成初始化
	 *
	 * 在所有初始化步骤结束后调用，用于最终设置或清理。
	 */
	virtual void end_init() {}

	/**
	 * @brief 清理渲染上下文
	 *
	 * 释放渲染上下文占用的资源。
	 */
	virtual void cleanup() { }

	//-------------- 环境和表面设置 --------------

	/**
	 * @brief 获取渲染环境
	 * @return 渲染环境配置
	 *
	 * 返回当前渲染上下文的环境配置，用于底层渲染API。
	 */
	virtual sg_environment get_environment() = 0;

	virtual std::unique_ptr<mirage_window_state> create_window_state(const Eigen::Vector2i& in_window_frame_size, void* in_window_handle) = 0;

	static auto get() { return instance_; }
private:
	inline static mirage_render_context* instance_{};
};

/**
 * @brief 创建渲染上下文实例
 * @return 新创建的渲染上下文指针
 *
 * 工厂函数，创建适合当前平台的渲染上下文实现。
 * 调用者负责管理返回的指针的生命周期。
 */
mirage_render_context* mirage_create_render_context();
