#include <debugging.h>
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include <opengl.h>

void message_callback(int32_t source, int32_t type, uint32_t id, int32_t severity, size_t length, char const* message, void const* user_param)
{
	char* src_str;
	switch (source) {
	case GL_DEBUG_SOURCE_API: 
            src_str = "API";
            break;
	case GL_DEBUG_SOURCE_WINDOW_SYSTEM: 
            src_str = "WINDOW SYSTEM";
            break;
	case GL_DEBUG_SOURCE_SHADER_COMPILER: 
            src_str = "SHADER COMPILER";
            break;
	case GL_DEBUG_SOURCE_THIRD_PARTY: 
            src_str = "THIRD PARTY";
            break;
	case GL_DEBUG_SOURCE_APPLICATION: 
            src_str = "APPLICATION";
            break;
	case GL_DEBUG_SOURCE_OTHER: 
            src_str = "OTHER";
            break;
	}

	char* type_str;
	switch (type) {
	case GL_DEBUG_TYPE_ERROR: 
            type_str = "ERROR";
            break;
	case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR: 
            type_str = "DEPRECATED_BEHAVIOR";
            break;
	case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR: 
            type_str = "UNDEFINED_BEHAVIOR";
            break;
	case GL_DEBUG_TYPE_PORTABILITY: 
            type_str = "PORTABILITY";
            break;
	case GL_DEBUG_TYPE_PERFORMANCE: 
            type_str = "PERFORMANCE";
            break;
	case GL_DEBUG_TYPE_MARKER: 
            type_str = "MARKER";
            break;
	case GL_DEBUG_TYPE_OTHER: 
            type_str = "OTHER";
            break;
	}

	char* severity_str;
        switch (severity) {
	case GL_DEBUG_SEVERITY_NOTIFICATION:
            severity_str = "NOTIFICATION";
            break;
	case GL_DEBUG_SEVERITY_LOW:
            severity_str = "LOW";
            break;
	case GL_DEBUG_SEVERITY_MEDIUM: 
            severity_str = "MEDIUM";
            break;
	case GL_DEBUG_SEVERITY_HIGH: 
            severity_str = "HIGH";
            break;
	}
	
        printf("[%s] %s (%s): %d, %s\n", src_str, type_str, severity_str, id, message);
}

void enable_debugging() {
    glEnable(GL_DEBUG_OUTPUT);
    glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, NULL, GL_FALSE);
    glDebugMessageCallback((GLDEBUGPROC)message_callback, NULL);
}
