// =====================================================================================================================
//  fennec, a free and open source game engine
//  Copyright © 2025  Medusa Slockbower
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <https://www.gnu.org/licenses/>.
// =====================================================================================================================

#ifndef FENNEC_RENDERERS_OPENGL_LIB_ENUM_H
#define FENNEC_RENDERERS_OPENGL_LIB_ENUM_H

#include <fennec/renderers/opengl/lib/fwd.h>

namespace fennec
{

namespace gl
{

enum buffer_ : GLenum {
	VERTEX             = GL_ARRAY_BUFFER,
	ELEMENT            = GL_ELEMENT_ARRAY_BUFFER,
	UNIFORM            = GL_UNIFORM_BUFFER,
	SHADER_STORAGE     = GL_SHADER_STORAGE_BUFFER,
	QUERY              = GL_QUERY_BUFFER,
	TEXTURE            = GL_TEXTURE_BUFFER,
	TRANSFORM_FEEDBACK = GL_TRANSFORM_FEEDBACK_BUFFER,
	ATOMIC_COUNTER     = GL_ATOMIC_COUNTER_BUFFER,
	PARAMETER          = GL_PARAMETER_BUFFER,
	INDIRECT_DRAW      = GL_DRAW_INDIRECT_BUFFER, INDIRECT_DISPATCH = GL_DISPATCH_INDIRECT_BUFFER,
	COPY_READ          = GL_COPY_READ_BUFFER,     COPY_WRITE        = GL_COPY_WRITE_BUFFER,
	PIXEL_PACK         = GL_PIXEL_PACK_BUFFER,    PIXEL_UNPACK      = GL_PIXEL_UNPACK_BUFFER,
};

enum buffer_flag_ : GLbitfield {
	READ           = GL_MAP_READ_BIT,
	WRITE          = GL_MAP_WRITE_BIT,
	DYNAMIC        = GL_DYNAMIC_STORAGE_BIT,
	PERSISTENT     = GL_MAP_PERSISTENT_BIT,
	COHERENT       = GL_MAP_COHERENT_BIT,
	CLIENT         = GL_CLIENT_STORAGE_BIT,
	EXPLICIT_FLUSH = GL_MAP_FLUSH_EXPLICIT_BIT,
	INVALIDATE     = GL_MAP_INVALIDATE_BUFFER_BIT,
};

enum access_ : GLbitfield {
	READ_ONLY      = GL_READ_ONLY,
	WRITE_ONLY     = GL_WRITE_ONLY,
	READ_WRITE     = GL_READ_WRITE,
};

enum texture_ : GLenum {
	TEX_1D   = GL_TEXTURE_1D,
	TEX_1D_V = GL_TEXTURE_1D_ARRAY,

	TEX_2D      = GL_TEXTURE_2D,
	TEX_2D_V    = GL_TEXTURE_2D_ARRAY,
	TEX_2D_MS   = GL_TEXTURE_2D_MULTISAMPLE,
	TEX_2D_MS_V = GL_TEXTURE_2D_MULTISAMPLE_ARRAY,
	TEX_RECT    = GL_TEXTURE_RECTANGLE,

	TEX_CUBEMAP   = GL_TEXTURE_CUBE_MAP,
	TEX_CUBEMAP_V = GL_TEXTURE_CUBE_MAP_ARRAY,

	TEX_3D = GL_TEXTURE_3D,

	TEX_BUFFER  = GL_TEXTURE_BUFFER,
};

enum type_ : GLenum {
	BOOL   = GL_BOOL,
	BVEC2  = GL_BOOL_VEC2,
	BVEC3  = GL_BOOL_VEC3,
	BVEC4  = GL_BOOL_VEC4,

	BYTE   = GL_BYTE,
	SHORT  = GL_SHORT,
	INT    = GL_INT,
	IVEC2  = GL_INT_VEC2,
	IVEC3  = GL_INT_VEC3,
	IVEC4  = GL_INT_VEC4,

	UBYTE  = GL_UNSIGNED_BYTE,
	USHORT = GL_UNSIGNED_SHORT,
	UINT   = GL_UNSIGNED_INT,
	UVEC2  = GL_UNSIGNED_INT_VEC2,
	UVEC3  = GL_UNSIGNED_INT_VEC3,
	UVEC4  = GL_UNSIGNED_INT_VEC4,

	HALF    = GL_HALF_FLOAT,
	FLOAT   = GL_FLOAT,
	VEC2    = GL_FLOAT_VEC2,
	VEC3    = GL_FLOAT_VEC3,
	VEC4    = GL_FLOAT_VEC4,
	DOUBLE  = GL_DOUBLE,
	DVEC2   = GL_DOUBLE_VEC2,
	DVEC3   = GL_DOUBLE_VEC3,
	DVEC4   = GL_DOUBLE_VEC4,

	UBYTE332      = GL_UNSIGNED_BYTE_3_3_2,
	UBYTE233R     = GL_UNSIGNED_BYTE_2_3_3_REV,
	USHORT565     = GL_UNSIGNED_SHORT_5_6_5,
	USHORT565R    = GL_UNSIGNED_SHORT_5_6_5_REV,
	USHORT4444    = GL_UNSIGNED_SHORT_4_4_4_4,
	USHORT4444R   = GL_UNSIGNED_SHORT_4_4_4_4_REV,
	USHORT5551    = GL_UNSIGNED_SHORT_5_5_5_1,
	USHORT1555R   = GL_UNSIGNED_SHORT_1_5_5_5_REV,
	UINT8888      = GL_UNSIGNED_INT_8_8_8_8,
	UINT8888R     = GL_UNSIGNED_INT_8_8_8_8_REV,
	UINTAAA2      = GL_UNSIGNED_INT_10_10_10_2,
	UINT2AAAR     = GL_UNSIGNED_INT_2_10_10_10_REV,
	UINT24_8      = GL_UNSIGNED_INT_24_8,

	UINTABBFR     = GL_UNSIGNED_INT_10F_11F_11F_REV,
	UINT5999R     = GL_UNSIGNED_INT_5_9_9_9_REV,
	FLOAT32UINT24 = GL_FLOAT_32_UNSIGNED_INT_24_8_REV,

	SAMPLER_1D          = GL_SAMPLER_1D,
	SAMPLER_1D_V        = GL_SAMPLER_1D_ARRAY,
	SHADOW_SAMPLER_1D   = GL_SAMPLER_1D_SHADOW,
	SHADOW_SAMPLER_1D_V = GL_SAMPLER_1D_ARRAY_SHADOW,

	SAMPLER_2D             = GL_SAMPLER_2D,
	SAMPLER_2D_V           = GL_SAMPLER_2D_ARRAY,
	SAMPLER_RECT_2D        = GL_SAMPLER_2D_RECT,
	SAMPLER_2D_MS          = GL_SAMPLER_2D_MULTISAMPLE,
	SAMPLER_2D_MS_V        = GL_SAMPLER_2D_MULTISAMPLE_ARRAY,
	SHADOW_SAMPLER_2D      = GL_SAMPLER_2D_SHADOW,
	SHADOW_SAMPLER_2D_V    = GL_SAMPLER_2D_ARRAY_SHADOW,
	SHADOW_SAMPLER_RECT_2D = GL_SAMPLER_2D_RECT_SHADOW,
	SAMPLER_CUBEMAP        = GL_SAMPLER_CUBE,
	SHADOW_SAMPLER_CUBEMAP = GL_SAMPLER_CUBE_SHADOW,
	SAMPLER_3D             = GL_SAMPLER_3D,
	SAMPLER_BUFFER         = GL_SAMPLER_BUFFER,

	ISAMPLER_1D       = GL_INT_SAMPLER_1D,
	ISAMPLER_1D_V     = GL_INT_SAMPLER_1D_ARRAY,
	ISAMPLER_2D       = GL_INT_SAMPLER_2D,
	ISAMPLER_2D_V     = GL_INT_SAMPLER_2D_ARRAY,
	ISAMPLER_RECT_2D  = GL_INT_SAMPLER_2D_RECT,
	ISAMPLER_2D_MS    = GL_INT_SAMPLER_2D_MULTISAMPLE,
	ISAMPLER_2D_MS_V  = GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
	ISAMPLER_CUBEMAP  = GL_INT_SAMPLER_CUBE,
	ISAMPLER_3D       = GL_INT_SAMPLER_3D,
	ISAMPLER_BUFFER   = GL_INT_SAMPLER_BUFFER,

	USAMPLER_1D       = GL_INT_SAMPLER_1D,
	USAMPLER_1D_V     = GL_INT_SAMPLER_1D_ARRAY,
	USAMPLER_2D       = GL_INT_SAMPLER_2D,
	USAMPLER_2D_V     = GL_INT_SAMPLER_2D_ARRAY,
	USAMPLER_RECT_2D  = GL_INT_SAMPLER_2D_RECT,
	USAMPLER_2D_MS    = GL_INT_SAMPLER_2D_MULTISAMPLE,
	USAMPLER_2D_MS_V  = GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY,
	USAMPLER_CUBEMAP  = GL_INT_SAMPLER_CUBE,
	USAMPLER_3D       = GL_INT_SAMPLER_3D,
	USAMPLER_BUFFER   = GL_INT_SAMPLER_BUFFER,

	IMAGE_1D       = GL_IMAGE_1D,
	IMAGE_1D_V     = GL_IMAGE_1D_ARRAY,
	IMAGE_2D       = GL_IMAGE_2D,
	IMAGE_2D_V     = GL_IMAGE_2D_ARRAY,
	IMAGE_RECT_2D  = GL_IMAGE_2D_RECT,
	IMAGE_2D_MS    = GL_IMAGE_2D_MULTISAMPLE,
	IMAGE_2D_MS_V  = GL_IMAGE_2D_MULTISAMPLE_ARRAY,
	IMAGE_CUBEMAP  = GL_IMAGE_CUBE,
	IMAGE_3D       = GL_IMAGE_3D,
	IMAGE_BUFFER   = GL_IMAGE_BUFFER,

	IIMAGE_1D       = GL_INT_IMAGE_1D,
	IIMAGE_1D_V     = GL_INT_IMAGE_1D_ARRAY,
	IIMAGE_2D       = GL_INT_IMAGE_2D,
	IIMAGE_2D_V     = GL_INT_IMAGE_2D_ARRAY,
	IIMAGE_RECT_2D  = GL_INT_IMAGE_2D_RECT,
	IIMAGE_2D_MS    = GL_INT_IMAGE_2D_MULTISAMPLE,
	IIMAGE_2D_MS_V  = GL_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
	IIMAGE_CUBEMAP  = GL_INT_IMAGE_CUBE,
	IIMAGE_3D       = GL_INT_IMAGE_3D,
	IIMAGE_BUFFER   = GL_INT_IMAGE_BUFFER,

	UIMAGE_1D       = GL_UNSIGNED_INT_IMAGE_1D,
	UIMAGE_1D_V     = GL_UNSIGNED_INT_IMAGE_1D_ARRAY,
	UIMAGE_2D       = GL_UNSIGNED_INT_IMAGE_2D,
	UIMAGE_2D_V     = GL_UNSIGNED_INT_IMAGE_2D_ARRAY,
	UIMAGE_RECT_2D  = GL_UNSIGNED_INT_IMAGE_2D_RECT,
	UIMAGE_2D_MS    = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE,
	UIMAGE_2D_MS_V  = GL_UNSIGNED_INT_IMAGE_2D_MULTISAMPLE_ARRAY,
	UIMAGE_CUBEMAP  = GL_UNSIGNED_INT_IMAGE_CUBE,
	UIMAGE_3D       = GL_UNSIGNED_INT_IMAGE_3D,
	UIMAGE_BUFFER   = GL_UNSIGNED_INT_IMAGE_BUFFER,

	AtomicCounter = GL_UNSIGNED_INT_ATOMIC_COUNTER,
};

enum component_ : GLenum {
	ZERO          = GL_ZERO,
	ONE           = GL_ONE,
	R             = GL_RED,
	G             = GL_GREEN,
	B             = GL_BLUE,
	A             = GL_ALPHA,
	RGB           = GL_RGB,
	BGR           = GL_BGR,
	RGBA          = GL_RGBA,
	BGRA          = GL_BGRA,
	RI            = GL_RED_INTEGER,
	GI            = GL_GREEN_INTEGER,
	BI            = GL_BLUE_INTEGER,
	AI            = GL_ALPHA_INTEGER,
	RGBI          = GL_RGB_INTEGER,
	BGRI          = GL_BGR_INTEGER,
	RGBAI         = GL_RGBA_INTEGER,
	BGRAI         = GL_BGRA_INTEGER,
	STENCIL       = GL_STENCIL_INDEX,
	DEPTH         = GL_DEPTH_COMPONENT,
	DEPTH_STENCIL = GL_DEPTH_STENCIL,
};

enum format_ : GLint {
	R8        = GL_R8,
	R8_SNORM  = GL_R8_SNORM,
	R16       = GL_R16,
	R16_SNORM = GL_R16_SNORM,

	RG8        = GL_RG8,
	RG8_SNORM  = GL_RG8_SNORM,
	RG16       = GL_RG16,
	RG16_SNORM = GL_RG16_SNORM,

	RGB332      = GL_R3_G3_B2,
	RGB4        = GL_RGB4,
	RGB5        = GL_RGB5,
	RGB8        = GL_RGB8,
	RGB8_SNORM  = GL_RGB8_SNORM,
	RGB10       = GL_RGB10,
	RGB12       = GL_RGB12,
	RGB16       = GL_RGB16,
	RGB16_SNORM = GL_RGB16_SNORM,

	RGBA2       = GL_RGBA2,
	RGBA4       = GL_RGBA4,
	RGB5_A1     = GL_RGB5_A1,
	RGBA8       = GL_RGBA8,
	RGBA8_SNORM = GL_RGBA8_SNORM,
	RGB10_A2    = GL_RGB10_A2,
	RGB10_A2UI  = GL_RGB10_A2UI,
	RGBA12      = GL_RGBA12,
	RGBA16      = GL_RGBA16,

	SRGB8       = GL_SRGB8,
	SRGBA8      = GL_SRGB8_ALPHA8,

	R16F    = GL_R16F,
	RG16F   = GL_RG16F,
	RGB16F  = GL_RGB16F,
	RGBA16F = GL_RGBA16F,

	R32F    = GL_R32F,
	RG32F   = GL_RG32F,
	RGB32F  = GL_RGB32F,
	RGBA32F = GL_RGBA32F,

	R8I    = GL_R8I,
	RG8I   = GL_RG8I,
	RGB8I  = GL_RGB8I,
	RGBA8I = GL_RGBA8I,

	R16I    = GL_R16I,
	RG16I   = GL_RG16I,
	RGB16I  = GL_RGB16I,
	RGBA16I = GL_RGBA16I,

	R32I    = GL_R32I,
	RG32I   = GL_RG32I,
	RGB32I  = GL_RGB32I,
	RGBA32I = GL_RGBA32I,

	R8UI    = GL_R8UI,
	RG8UI   = GL_RG8UI,
	RGB8UI  = GL_RGB8UI,
	RGBA8UI = GL_RGBA8UI,

	R16UI    = GL_R16UI,
	RG16UI   = GL_RG16UI,
	RGB16UI  = GL_RGB16UI,
	RGBA16UI = GL_RGBA16UI,

	R32UI    = GL_R32UI,
	RG32UI   = GL_RG32UI,
	RGB32UI  = GL_RGB32UI,
	RGBA32UI = GL_RGBA32UI,

	RGB_DXT1 = GL_COMPRESSED_RGB_S3TC_DXT1_EXT,
	RGBA_DXT1 = GL_COMPRESSED_RGBA_S3TC_DXT1_EXT,
	RGBA_DXT3 = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT,
	RGBA_DXT5 = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT,

	SRGB_DXT1 = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT,
	SRGBA_DXT1 = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT,
	SRGBA_DXT3 = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT,
	SRGBA_DXT5 = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT,
};

}

}

#endif // FENNEC_RENDERERS_OPENGL_LIB_ENUM_H
