package cg;
//--------------------------------------------------------------------
import javax.swing.JFrame;
import com.jogamp.opengl.GL2;
import com.jogamp.opengl.GLAutoDrawable;
import com.jogamp.opengl.GLCapabilities;
import com.jogamp.opengl.GLEventListener;
import com.jogamp.opengl.GLProfile;
import com.jogamp.opengl.awt.GLCanvas;
import com.jogamp.opengl.glu.GLU; 
import com.jogamp.opengl.util.FPSAnimator;
import com.jogamp.opengl.util.gl2.GLUT;
import java.io.File;
import java.io.IOException;
import com.jogamp.opengl.util.texture.Texture;
import com.jogamp.opengl.util.texture.TextureIO;
//--------------------------------------------------------------------
public class Main implements GLEventListener {
	
	GLU glu = new GLU();
	GLUT glut = new GLUT();
	
	static float rtri = 0.0f;
	
	static float env_color[] = { 1.0f, 0.0f, 0.0f, 1.0f };
	
	static float lmodel_ambient[] = { 0.4f, 0.4f, 0.4f, 1.0f };
	
	static float ambient[] = { 0.0f, 0.0f, 0.0f, 1.0f };
	static float diffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	static float specular[] = { 1.0f, 1.0f, 1.0f, 1.0f };

    static float position[] = { 0.0f, 0.0f, 6.0f, 1.0f };
    
    static float direction[] = {0.0f, 0.0f, -1.0f};
    static float cutoff = 15.0f;
    static float exponent = 1.0f;
    
    static float atten_con = 1.0f;
    static float atten_lin = 0.0f;
    static float atten_qua = 0.0f;
	
    //Gold (poliert)
    static float mat_amb_au[] = { 0.25f, 0.22f, 0.06f, 1.0f };
    static float mat_spec_au[] = { 0.80f, 0.72f, 0.21f, 1.0f };
    static float mat_dif_au[] = { 0.35f, 0.31f, 0.09f, 1.0f };
    static float mat_emi_au[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    static float mat_shi_au = 83.2f;
    
    //Silber (poliert)
    static float mat_amb_ar[] = { 0.23f, 0.23f, 0.23f, 1.0f };
    static float mat_spec_ar[] = { 0.77f, 0.77f, 0.77f, 1.0f };
    static float mat_dif_ar[] = { 0.28f, 0.28f, 0.28f, 1.0f };
    static float mat_emi_ar[] = { 0.0f, 0.0f, 0.0f, 1.0f };
    static float mat_shi_ar = 89.6f;
    
	String texturdatei = "eureTexturDateiname.Dateiformat";
	String texturPfad = "src/res/" + texturdatei;
	
	float texmax = 1f;
	
	Texture texture;
	//--------------------------------------------------------------------	
	public static void main(String[] args) {
		 
	      final GLProfile profile = GLProfile.get(GLProfile.GL2);
	      GLCapabilities capabilities = new GLCapabilities(profile);
	      final GLCanvas glcanvas = new GLCanvas(capabilities);

	      final int width = 800;
	      final int height = 600;
	     
	      Main m = new Main();
	      glcanvas.addGLEventListener(m);
	  
	      final JFrame frame = new JFrame ("texturierte v beleuchtete Objekte");
	      frame.add(glcanvas);
	      frame.setSize(width, height);
	      frame.setVisible(true);
	      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

	      final FPSAnimator animator = new FPSAnimator( glcanvas, 60, true );
	      animator.start();
	}
	//--------------------------------------------------------------------
	@Override
	public void init(GLAutoDrawable drawable) {
		
		 GL2 gl = drawable.getGL().getGL2();

		 //--------------------------------------------------------------------
	     gl.glLightModelfv(GL2.GL_LIGHT_MODEL_AMBIENT, lmodel_ambient, 0);
	     
	     gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_AMBIENT, ambient, 0);
	     gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPECULAR, specular, 0);
	     gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_DIFFUSE, diffuse, 0);
	     
	     gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_POSITION, position, 0);
	     
	     gl.glLightfv(GL2.GL_LIGHT0, GL2.GL_SPOT_DIRECTION, direction, 0);
	     
	     gl.glLightf(GL2.GL_LIGHT0, GL2.GL_SPOT_CUTOFF, cutoff);
	     gl.glLightf(GL2.GL_LIGHT0, GL2.GL_SPOT_EXPONENT, exponent);
	     
	     gl.glLightf(GL2.GL_LIGHT0, GL2.GL_CONSTANT_ATTENUATION, atten_con);
		 gl.glLightf(GL2.GL_LIGHT0, GL2.GL_LINEAR_ATTENUATION, atten_lin);
		 gl.glLightf(GL2.GL_LIGHT0, GL2.GL_QUADRATIC_ATTENUATION, atten_qua);
		 //--------------------------------------------------------------------
	     gl.glEnable(GL2.GL_LIGHTING);
	     gl.glEnable(GL2.GL_LIGHT0);
	     
	     gl.glEnable(GL2.GL_NORMALIZE);
	     //--------------------------------------------------------------------
	     //gl.glColorMaterial(GL2.GL_FRONT, GL2.GL_AMBIENT);
	     //gl.glColorMaterial(GL2.GL_FRONT, GL2.GL_DIFFUSE);
	     //gl.glColorMaterial(GL2.GL_FRONT, GL2.GL_SPECULAR);
	     //gl.glColorMaterial(GL2.GL_FRONT, GL2.GL_EMISSION);
	     //gl.glEnable(GL2.GL_COLOR_MATERIAL);
	     gl.glDisable(GL2.GL_COLOR_MATERIAL);
	     //--------------------------------------------------------------------
	     gl.glEnable(GL2.GL_DEPTH_TEST);
	     gl.glDepthFunc(GL2.GL_LESS);
	     //--------------------------------------------------------------------
		 gl.glFrontFace(GL2.GL_CCW);
	     gl.glCullFace(GL2.GL_BACK);
	     
	     try
	      {
	    	 File im = new File(texturPfad);
	         texture = TextureIO.newTexture(im, true);
	      }
	      catch (IOException e)
	      {
	         e.printStackTrace();
	      }
	}
	//--------------------------------------------------------------------
	@Override
	public void display(GLAutoDrawable drawable) {
		
		GL2 gl = drawable.getGL().getGL2();
		
	      gl.glClear( GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT );
	      
	      gl.glMatrixMode( GL2.GL_MODELVIEW );
	      gl.glLoadIdentity();
	      gl.glTranslatef( 0.0f, 0.0f, -6.0f); 

	      texture.enable(gl);
	      texture.bind(gl);
	      gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MAG_FILTER, GL2.GL_NEAREST);
	      gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_MIN_FILTER, GL2.GL_NEAREST);
	      gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_R, GL2.GL_REPEAT);
	      gl.glTexParameteri(GL2.GL_TEXTURE_2D, GL2.GL_TEXTURE_WRAP_S, GL2.GL_CLAMP);
	      
	      gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_MODULATE);
	      //gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_REPLACE);
	      
	      //gl.glTexEnvf(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_MODE, GL2.GL_BLEND);
	      //gl.glTexEnvfv(GL2.GL_TEXTURE_ENV, GL2.GL_TEXTURE_ENV_COLOR, env_color, 0);
	      //--------------------------------------------------------------------
	      gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_AMBIENT, mat_amb_au, 0);
	      gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_DIFFUSE, mat_dif_au, 0);
	      gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SPECULAR, mat_spec_au, 0);
	      gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_EMISSION, mat_emi_au, 0);
	      gl.glMaterialf(GL2.GL_FRONT, GL2.GL_SHININESS, mat_shi_au);
	      //--------------------------------------------------------------------
	      gl.glPushMatrix();
	      gl.glTranslated(1.0f, 0.0f, 0.0f);
	      gl.glRotatef( rtri, 1.0f, 1.0f, 1.0f );
	      drawCube(gl);
	      gl.glPopMatrix();
	      gl.glPushMatrix();

	      texture.disable(gl);
	      //--------------------------------------------------------------------
	      gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_AMBIENT, mat_amb_ar, 0);
	      gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_DIFFUSE, mat_dif_ar, 0);
	      gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_SPECULAR, mat_spec_ar, 0);
	      gl.glMaterialfv(GL2.GL_FRONT, GL2.GL_EMISSION, mat_emi_ar, 0);
	      gl.glMaterialf(GL2.GL_FRONT, GL2.GL_SHININESS, mat_shi_ar);
	      //--------------------------------------------------------------------
	      gl.glTranslated(-1.5f, 0.0f, 0.0f);
	      gl.glRotatef( rtri, 1.0f, 1.0f, 1.0f );
	      glut.glutSolidTeapot(0.7f);
	      gl.glPopMatrix();
	      
	      rtri +=0.2f;
	}
	//--------------------------------------------------------------------
  	// zu texturierendes Objekt wird gezeichnet
    // OpenGL-komform definiert (i.e. aüßere Seiten im Gegenuhrzeigersinn)
    // entspricht dem Vorgabewert GL_CCW für glFrontFace
	//	  v6----- v5
	//	 /|      /|
	//	v1------v0|
	//	| |     | |
	//	| v7----|-v4
	//	|/      |/
	//	v2------v3	
	public void drawCube(GL2 gl) {
		gl.glBegin( GL2.GL_QUADS );
		  //gl.glColor4f(1.0f, 0.0f, 0.0f, 1.0f);
		  //--------------------------------------------------------------------
		  gl.glNormal3f(0.0f, 1.0f, 0.0f);
		  //--------------------------------------------------------------------
		  gl.glTexCoord2f(texmax, texmax);gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // v5 Top Right (Top)
	      gl.glTexCoord2f(0f, texmax);gl.glVertex3f( -1.0f, 1.0f, -1.0f); // v6 Top Left (Top)
	      gl.glTexCoord2f(0f, 0f);gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // v1 Bottom Left (Top)
	      gl.glTexCoord2f(texmax, 0f);gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // v0 Bottom Right (Top)
		  
	      //--------------------------------------------------------------------	      
	      gl.glNormal3f(0.0f, -1.0f, 0.0f);
		  //--------------------------------------------------------------------
	      gl.glTexCoord2f(texmax, texmax);gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // v3 Top Right (Bottom) 
	      gl.glTexCoord2f(0f, texmax);gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // v2 Top Left (Bottom)
	      gl.glTexCoord2f(0f, 0f);gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // v7 Bottom Left (Bottom)
	      gl.glTexCoord2f(texmax, 0f);gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // v4 Bottom Right (Bottom)
		  
	      //--------------------------------------------------------------------
	      gl.glNormal3f(0.0f, 0.0f, 1.0f);
		  //--------------------------------------------------------------------
	      gl.glTexCoord2f(texmax, texmax);gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // v0 Top Right (Front)
	      gl.glTexCoord2f(0f, texmax);gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // v1 Top Left (Front)
	      gl.glTexCoord2f(0f, 0f);gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // v2 Bottom Left (Front) 
	      gl.glTexCoord2f(texmax, 0f);gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // v3 Bottom Right (Front)
		  
	      //--------------------------------------------------------------------
	      gl.glNormal3f(0.0f, 0.0f, -1.0f);
		  //--------------------------------------------------------------------
	      gl.glTexCoord2f(texmax, texmax);gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // v4 Bottom Left (Back)
	      gl.glTexCoord2f(0f, texmax);gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // v7 Bottom Right (Back)
	      gl.glTexCoord2f(0f, 0f);gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // v6 Top Right (Back)
	      gl.glTexCoord2f(texmax, 0f);gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // v5 Top Left (Back)
		  
	      //--------------------------------------------------------------------
	      gl.glNormal3f( -1.0f, 0.0f, 0.0f);
		  //--------------------------------------------------------------------
	      gl.glTexCoord2f(texmax, texmax);gl.glVertex3f( -1.0f, 1.0f, 1.0f ); // v1 Top Right (Left)
	      gl.glTexCoord2f(0f, texmax);gl.glVertex3f( -1.0f, 1.0f, -1.0f ); // v6 Top Left (Left)
	      gl.glTexCoord2f(0f, 0f);gl.glVertex3f( -1.0f, -1.0f, -1.0f ); // v7 Bottom Left (Left)
	      gl.glTexCoord2f(texmax, 0f);gl.glVertex3f( -1.0f, -1.0f, 1.0f ); // v2 Bottom Right (Left)
		  
	      //--------------------------------------------------------------------
	      gl.glNormal3f( 1.0f, 0.0f, 0.0f);
		  //--------------------------------------------------------------------
	      gl.glTexCoord2f(texmax, texmax);gl.glVertex3f( 1.0f, 1.0f, -1.0f ); // v5 Top Right (Right)
	      gl.glTexCoord2f(0f, texmax);gl.glVertex3f( 1.0f, 1.0f, 1.0f ); // v0 Top Left (Right)
	      gl.glTexCoord2f(0f, 0f);gl.glVertex3f( 1.0f, -1.0f, 1.0f ); // v3 Bottom Left (Right)
	      gl.glTexCoord2f(texmax, 0f);gl.glVertex3f( 1.0f, -1.0f, -1.0f ); // v4 Bottom Right (Right)
	      
	      gl.glEnd();
	}
	//--------------------------------------------------------------------
	@Override
	public void dispose(GLAutoDrawable drawable) {}
	//--------------------------------------------------------------------
	@Override
	public void reshape(GLAutoDrawable drawable, int x, int y, int width, int height) {
		
		final GL2 gl = drawable.getGL().getGL2();
		
	      final float h = ( float ) width / ( float ) height;
	      
	      gl.glViewport( 0, 0, width, height );
	      gl.glMatrixMode( GL2.GL_PROJECTION );
	      gl.glLoadIdentity();
	      glu.gluPerspective( 45.0f, h, 1.0, 20.0 ); 
	      gl.glMatrixMode( GL2.GL_MODELVIEW );
	      gl.glLoadIdentity(); 
	}
}