package JautOGL;

import javax.media.opengl.*;
import javax.media.opengl.glu.*;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferInt;
import java.awt.image.AffineTransformOp;
import java.awt.geom.AffineTransform;
import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.nio.ByteOrder;

import com.sun.opengl.util.BufferUtil;

import java.awt.image.PixelGrabber;


public class TextureLoader {
		
	public void TextureLoader(){
		
	}
	
	int width;
	int height;
	ByteBuffer texture=null;
	
	public Texture load_image(String filename, GL gl){
		
		Texture tmpTex = new Texture(filename, GL.GL_TEXTURE_2D, GL.GL_RGB8,
				GL.GL_RGB, GL.GL_NEAREST, GL.GL_NEAREST,
         		 true, false);
		tmpTex.setTextureID(0);
		
		try{
		tmpTex = readTexture(filename);	
		   IntBuffer texName = IntBuffer.allocate(2);
			gl.glGenTextures(1,texName);
			//model->materials[nummaterials].m_nTexture=texName;
			gl.glBindTexture(GL.GL_TEXTURE_2D, texName.get(0));
			gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S,GL.GL_REPEAT);
			gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T,GL.GL_REPEAT);
			gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_NEAREST);
			gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_NEAREST);
			gl.glTexImage2D(GL.GL_TEXTURE_2D,0,GL.GL_RGB,tmpTex.getWidth(),tmpTex.getHeight(),0,GL.GL_RGB,GL.GL_UNSIGNED_BYTE,tmpTex.getPixels());
			tmpTex.setTextureID(texName.get(0));
			tmpTex.setName(filename);
       }
	   catch(Exception e){
			System.out.println("TextureLoader ERROR");
			e.printStackTrace();
	   }
		
		return tmpTex;
		//////////////////////////////////////////////////////////////////
		/*
		try{
			InputStream is=ClassLoader.getSystemResourceAsStream(filename);
			BufferedInputStream bis=new BufferedInputStream(is);
			BufferedImage bi=ImageIO.read(bis);
			Raster r=bi.getRaster();
			DataBufferByte dbi=(DataBufferByte)r.getDataBuffer();
			byte b[]=dbi.getData();
		
			//ByteBuffer texture=null;
			int texture_size=b.length;
			texture=ByteBuffer.allocateDirect(texture_size);
			ByteOrder newOrder=ByteOrder.nativeOrder();
			texture.order(newOrder);
			texture.put(b,0,texture_size);
		
			int imgWidth=bi.getWidth();
			int imgHeight=bi.getHeight();
			width=imgWidth;
			height=imgHeight;
		}
		catch(Exception e){
			System.out.println("TextureLoader ERROR");
			e.printStackTrace();
		}*/
		
	}
	
	public static Texture readTexture(String filename) throws IOException {
        return readTexture(filename, false);
    }

    public static Texture readTexture(String filename, boolean storeAlphaChannel) throws IOException {
        BufferedImage bufferedImage;
        if (filename.endsWith(".bmp")) {
            bufferedImage = BitmapLoader.loadBitmap(filename);
        } else {
            bufferedImage = readImage(filename);
        }
        return readPixels(bufferedImage, storeAlphaChannel);
    }

    private static BufferedImage readImage(String resourceName) throws IOException {
        return ImageIO.read(ResourceRetriever.getResourceAsStream(resourceName));
    }

    private static Texture readPixels(BufferedImage img, boolean storeAlphaChannel) {
        int[] packedPixels = new int[img.getWidth() * img.getHeight()];

        PixelGrabber pixelgrabber = new PixelGrabber(img, 0, 0, img.getWidth(), img.getHeight(), packedPixels, 0, img.getWidth());
        try {
            pixelgrabber.grabPixels();
        } catch (InterruptedException e) {
            throw new RuntimeException();
        }

        int bytesPerPixel = storeAlphaChannel ? 4 : 3;
        ByteBuffer unpackedPixels = BufferUtil.newByteBuffer(packedPixels.length * bytesPerPixel);

        for (int row = img.getHeight() - 1; row >= 0; row--) {
            for (int col = 0; col < img.getWidth(); col++) {
                int packedPixel = packedPixels[row * img.getWidth() + col];
                unpackedPixels.put((byte) ((packedPixel >> 16) & 0xFF));
                unpackedPixels.put((byte) ((packedPixel >> 8) & 0xFF));
                unpackedPixels.put((byte) ((packedPixel >> 0) & 0xFF));
                if (storeAlphaChannel) {
                    unpackedPixels.put((byte) ((packedPixel >> 24) & 0xFF));
                }
            }
        }

        unpackedPixels.flip();

        
        //added stuff here 
        
        Texture tmpTex = new Texture("", GL.GL_TEXTURE_2D, GL.GL_RGB8,
				GL.GL_RGB, GL.GL_NEAREST, GL.GL_NEAREST,
         		 true, false);
        tmpTex.setPixels(unpackedPixels);
        tmpTex.setWidth(img.getWidth());
        tmpTex.setHeight(img.getHeight());

        return tmpTex;
    }
	public void attach_texture(GLU glu, GL gl){
		IntBuffer texName = IntBuffer.allocate(1);
		gl.glGenTextures(1,texName);
		//model->materials[nummaterials].m_nTexture=texName;
		gl.glBindTexture(GL.GL_TEXTURE_2D, texName.get(0));
		gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_S,GL.GL_REPEAT);
		gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_WRAP_T,GL.GL_REPEAT);
		gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MAG_FILTER,GL.GL_NEAREST);
		gl.glTexParameteri(GL.GL_TEXTURE_2D,GL.GL_TEXTURE_MIN_FILTER,GL.GL_NEAREST);
		gl.glTexImage2D(GL.GL_TEXTURE_2D,0,GL.GL_RGB8,width,height,0,GL.GL_RGB,GL.GL_UNSIGNED_BYTE,texture);
		//glu.gluBuild2DMipmaps(GL.GL_TEXTURE_2D,GL.GL_RGB8,width,height,GL.GL_RGB,GL.GL_UNSIGNED_BYTE,texture);
		
	}
}
