package ru.dbotthepony.kstarbound.client.gl

import org.lwjgl.opengl.GL45.*

// GL_INVALID_ENUM
// GL_INVALID_VALUE
// GL_INVALID_OPERATION
// GL_STACK_OVERFLOW
// GL_STACK_UNDERFLOW
// GL_OUT_OF_MEMORY

sealed class OpenGLError(message: String?, val statusCode: Int) : RuntimeException(message)

class OpenGLUnknownError(statusCode: Int, message: String? = null) : OpenGLError(message ?: "Unknown OpenGL error occurred: $statusCode", statusCode)

class OpenGLInvalidEnumException(message: String? = null) : OpenGLError(message ?: "Invalid enum provided", GL_INVALID_ENUM)
class OpenGLInvalidValueException(message: String? = null) : OpenGLError(message ?: "Invalid value provided", GL_INVALID_VALUE)
class OpenGLInvalidOperationException(message: String? = null) : OpenGLError(message ?: "Invalid operation in this context or invalid arguments provided", GL_INVALID_OPERATION)
class OpenGLStackOverflowException(message: String? = null) : OpenGLError(message ?: "Stack overflow in OpenGL", GL_STACK_OVERFLOW)
class OpenGLStackUnderflowException(message: String? = null) : OpenGLError(message ?: "Stack underflow in OpenGL", GL_STACK_UNDERFLOW)
class OpenGLOutOfMemoryException(message: String? = null) : OpenGLError(message ?: "Out of Memory in OpenGL", GL_OUT_OF_MEMORY)

fun checkForGLError(message: String? = null) {
	when (val errorCode = glGetError()) {
		GL_NO_ERROR -> {}
		GL_INVALID_ENUM -> throw OpenGLInvalidEnumException(message)
		GL_INVALID_VALUE -> throw OpenGLInvalidValueException(message)
		GL_INVALID_OPERATION -> throw OpenGLInvalidOperationException(message)
		GL_STACK_OVERFLOW -> throw OpenGLStackOverflowException(message)
		GL_STACK_UNDERFLOW -> throw OpenGLStackUnderflowException(message)
		GL_OUT_OF_MEMORY -> throw OpenGLOutOfMemoryException(message)
		else -> throw OpenGLUnknownError(errorCode, message)
	}
}
