package speiger.src.coreengine.rendering.texturesOld.stb;

import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;

import javax.imageio.ImageIO;

import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL30;
import org.lwjgl.stb.STBImage;
import org.lwjgl.system.MemoryUtil;

import speiger.src.coreengine.rendering.texturesOld.base.AbstractTexture;
import speiger.src.coreengine.rendering.texturesOld.base.TextureManager;

public class STBDirectTexture extends AbstractTexture
{
	long imageData;
	int width;
	int height;
	
	public STBDirectTexture(BufferedImage imageData)
	{
		this(convert(imageData), imageData.getWidth(), imageData.getHeight());
	}
	
	public STBDirectTexture(ByteBuffer imageData, int width, int height)
	{
		this(MemoryUtil.memAddress(imageData), width, height);
	}
	
	public STBDirectTexture(long imageData, int width, int height)
	{
		this.imageData = imageData;
		this.width = width;
		this.height = height;
		loadTexture();
	}
	
	protected void loadTexture() {
		setTextureID(GL11.glGenTextures());
		bindTexture();
		GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR);
		GL11.glTexParameterf(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MAG_FILTER, GL11.GL_LINEAR);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_S, GL13.GL_CLAMP_TO_BORDER);
		GL11.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_WRAP_T, GL13.GL_CLAMP_TO_BORDER);
		GL11.glTexImage2D(GL11.GL_TEXTURE_2D, 0, GL11.GL_RGBA, width, height, 0, GL11.GL_RGBA, GL11.GL_UNSIGNED_BYTE, imageData);
		GL30.glGenerateMipmap(GL11.GL_TEXTURE_2D);
	}
	
	@Override
	public int getWidth()
	{
		return width;
	}
	
	@Override
	public int getHeight()
	{
		return height;
	}
	
	@Override
	public void reload()
	{
		int old = textureID;
		loadTexture();		
		TextureManager.INSTANCE.removeTexture(old);
	}
	
	@Override
	public void deleteTexture()
	{
		if(imageData != 0) 
		{
			STBImage.nstbi_image_free(imageData);
			imageData = 0;
		}
		super.deleteTexture();
	}
	
	private static ByteBuffer convert(BufferedImage image)
	{
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		try
		{
			ImageIO.write(image, "png", stream);
			ByteBuffer buffer = MemoryUtil.memAlloc(stream.size());
			buffer.put(stream.toByteArray());
			buffer.flip();
			ByteBuffer result = STBImage.stbi_load_from_memory(buffer, new int[1], new int[1], new int[1], 4);
			if(result == null) {
				MemoryUtil.memFree(buffer);
				throw new IOException("Could not load image: " + STBImage.stbi_failure_reason());
			}
			MemoryUtil.memFree(buffer);
			return result;
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
}
