#include <psemek/gfx/pixel.hpp>
#include <psemek/util/to_string.hpp>

#include <psemek/log/log.hpp>

namespace psemek::gfx
{

	std::size_t pixel_size(GLint internal_format)
	{
		switch (internal_format)
		{
			case gl::RGBA32F: return 16;
			case gl::RGBA32I: return 16;
			case gl::RGBA32UI: return 16;
#ifndef PSEMEK_GLES
			case gl::RGBA16: return 8;
#endif
			case gl::RGBA16F: return 8;
			case gl::RGBA16I: return 8;
			case gl::RGBA16UI: return 8;
			case gl::RGBA8: return 4;
			case gl::RGBA8UI: return 4;
			case gl::SRGB8_ALPHA8: return 4;
			case gl::RGB10_A2: return 4;
			case gl::RGB10_A2UI: return 4;
			case gl::R11F_G11F_B10F: return 4;
			case gl::RG32F: return 8;
			case gl::RG32I: return 8;
			case gl::RG32UI: return 8;
#ifndef PSEMEK_GLES
			case gl::RG16: return 4;
#endif
			case gl::RG16F: return 4;
			case gl::RGB16I: return 4;
			case gl::RGB16UI: return 4;
			case gl::RG8: return 2;
			case gl::RG8I: return 2;
			case gl::RG8UI: return 2;
			case gl::R32F: return 4;
			case gl::R32I: return 4;
			case gl::R32UI: return 4;
			case gl::R16F: return 2;
			case gl::R16I: return 2;
			case gl::R16UI: return 2;
			case gl::R8: return 1;
			case gl::R8I: return 1;
			case gl::R8UI: return 1;
#ifndef PSEMEK_GLES
			case gl::RGBA16_SNORM: return 8;
#endif
			case gl::RGBA8_SNORM: return 4;
			case gl::RGB32F: return 12;
			case gl::RGB32I: return 12;
			case gl::RGB32UI: return 12;
#ifndef PSEMEK_GLES
			case gl::RGB16_SNORM: return 6;
#endif
			case gl::RGB16F: return 6;
#ifndef PSEMEK_GLES
			case gl::RGB16: return 6;
#endif
			case gl::RGB8_SNORM: return 3;
			case gl::RGB8: return 3;
			case gl::RGB8I: return 3;
			case gl::RGB8UI: return 3;
			case gl::SRGB8: return 3;
			case gl::RGB9_E5: return 4;
#ifndef PSEMEK_GLES
			case gl::RG16_SNORM: return 4;
#endif
			case gl::RG8_SNORM: return 2;
#ifndef PSEMEK_GLES
			case gl::R16_SNORM: return 2;
#endif
			case gl::R8_SNORM: return 1;
			case gl::DEPTH_COMPONENT32F: return 4;
			case gl::DEPTH_COMPONENT24: return 3;
			case gl::DEPTH_COMPONENT16: return 2;
			case gl::DEPTH32F_STENCIL8: return 5;
			case gl::DEPTH24_STENCIL8: return 4;
			// Assume uncompressed size as an upper bound
#ifndef PSEMEK_GLES
			case gl::COMPRESSED_RG_RGTC2: return 2;
			case gl::COMPRESSED_SIGNED_RG_RGTC2: return 2;
			case gl::COMPRESSED_RED_RGTC1: return 1;
			case gl::COMPRESSED_SIGNED_RED_RGTC1: return 1;
#endif
		};

		log::warning() << "Unknown pixel format: 0x" << std::hex << internal_format;
		return 0;
	}

}
