#pragma once

#include <cstdint>

#include "renderer_gl/opengl_capabilities.h"

namespace pp::legacy::gl_runtime {

inline const char* query_opengl_string(std::uint32_t name) noexcept
{
    return reinterpret_cast<const char*>(glGetString(static_cast<GLenum>(name)));
}

inline void query_opengl_integer_scalar(std::uint32_t name, std::int32_t* value) noexcept
{
    GLint queried_value = 0;
    glGetIntegerv(static_cast<GLenum>(name), &queried_value);
    *value = static_cast<std::int32_t>(queried_value);
}

inline const char* query_opengl_indexed_string(std::uint32_t name, std::uint32_t index) noexcept
{
    return reinterpret_cast<const char*>(
        glGetStringi(static_cast<GLenum>(name), static_cast<GLuint>(index)));
}

inline std::uint32_t query_opengl_error() noexcept
{
    return static_cast<std::uint32_t>(glGetError());
}

#if defined(__ANDROID__)
inline bool has_opengl_debug_message_callback() noexcept
{
    return false;
}
#else
inline bool has_opengl_debug_message_callback() noexcept
{
    return glDebugMessageCallback != nullptr;
}

inline void install_opengl_debug_message_callback(GLDEBUGPROC callback, const void* user_param) noexcept
{
    glDebugMessageCallback(callback, user_param);
}
#endif

inline pp::renderer::gl::OpenGlRuntimeInfoDispatch runtime_info_dispatch() noexcept
{
    return pp::renderer::gl::OpenGlRuntimeInfoDispatch {
        .get_string = query_opengl_string,
    };
}

inline pp::renderer::gl::OpenGlExtensionQueryDispatch extension_query_dispatch() noexcept
{
    return pp::renderer::gl::OpenGlExtensionQueryDispatch {
        .get_integer = query_opengl_integer_scalar,
        .get_string_indexed = query_opengl_indexed_string,
    };
}

} // namespace pp::legacy::gl_runtime
