#include "OpenGLTexture.h"
#include "DeerRender/Log.h"

#include "glad/glad.h"

namespace Deer {
	Texture2D* Deer::Texture2D::create(const uint8_t* data, uint32_t width, uint32_t height, int channels) {
		return new OpenGLTexture2D(data, width, height, channels);
	}

	OpenGLTexture2D::OpenGLTexture2D(const uint8_t* data, uint32_t width, uint32_t height, int channels) {
		m_width = width;
		m_height = height;

		unsigned int internalFormat = 0, dataFormat = 0;
		switch (channels) {
		case 4:
			internalFormat = GL_RGBA8;
			dataFormat = GL_RGBA;
			break;
		case 3:
			internalFormat = GL_RGB8;
			dataFormat = GL_RGB;
			break;
		}

		if (internalFormat == 0 || dataFormat == 0) {
			DEER_CORE_ERROR("Texture format not supported! (Loaded from memory)");
			return;
		}

		glGenTextures(1, &m_textureID);
		glBindTexture(GL_TEXTURE_2D, m_textureID);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 7);

		glTexImage2D(GL_TEXTURE_2D, 0, dataFormat, width, height, 0, dataFormat, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}

	OpenGLTexture2D::~OpenGLTexture2D() {
		glDeleteTextures(1, &m_textureID);
	}

	void OpenGLTexture2D::bind(unsigned int slot) {

		glActiveTexture(GL_TEXTURE0 + slot);
		glBindTexture(GL_TEXTURE_2D, m_textureID);
	}

	void OpenGLTexture2D::unbind(unsigned int slot) {
		glActiveTexture(GL_TEXTURE0 + slot);
		glBindTexture(GL_TEXTURE_2D, 0);
	}

} // namespace Deer