package org.textures;

import org.lwjgl.opengl.GL11C;
import org.lwjgl.opengl.GL30C;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.io.InputStream;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidParameterException;

public class Texture implements AutoCloseable {
    private int textureHandle;

    public Texture(String resource) throws Exception {
        final BufferedImage image = loadImageDataAsARGB(resource);
        final int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

        // generate OpenGL texture buffer
        this.textureHandle = GL11C.glGenTextures();

        GL11C.glBindTexture(GL11C.GL_TEXTURE_2D, this.textureHandle);

        GL11C.glPixelStorei(3317, 1);

        GL11C.glTexParameteri(3553, 10241, 9987);

        GL11C.glTexParameteri(3553, 10240, 9729);

        GL11C.glTexParameteri(3553, 10242, 10497);
        GL11C.glTexParameteri(3553, 10243, 10497);

        GL11C.glTexImage2D(3553, 0, 6408, image.getWidth(), image.getHeight(), 0, 6408, 5121, pixels);


        GL30C.glGenerateMipmap(3553);


        GL11C.glBindTexture(3553, 0);
    }

    /**
     * Load image from disk as array of colors in ARGB format
     *
     * @param resource file path to load
     * @return array of ARGB values
     */
    private BufferedImage loadImageDataAsARGB(String resource) throws Exception {
        InputStream stream = Texture.class.getClassLoader().getResourceAsStream(resource);

        if (stream == null)
            throw new InvalidParameterException("Resource not found: " + resource);

        // buffer raw image data
        BufferedImage rawData = ImageIO.read(stream);
        // create buffer of fixed color layout of ARGB-Bytes
        BufferedImage layoutedData = new BufferedImage(rawData.getWidth(), rawData.getHeight(), BufferedImage.TYPE_INT_ARGB);
        // write raw image data into buffer with known color format
        layoutedData.createGraphics().drawImage(rawData, 0, 0, null);

        return layoutedData;
    }

    public final int getHandle() {
        return this.textureHandle;
    }

    public void close() {
        GL11C.glDeleteTextures(this.textureHandle);
    }
}
