package es1.rotatecube1;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.os.SystemClock;
import android.view.MotionEvent;
  
public class CubeRenderer implements GLSurfaceView.Renderer 
{
  public float angle = 0.0f;
  private Cube cube = new Cube();
        
  public void onSurfaceCreated(GL10 gl, EGLConfig config) 
  {
    // Set the background frame color to grey
    gl.glClearColor(0.5f, 0.5f, 0.5f, 1.0f);
    // Do not render back faces
    gl.glEnable( GL10.GL_CULL_FACE );
    gl.glCullFace ( GL10.GL_BACK );
  }
    
  public void onDrawFrame(GL10 gl) 
  {
    // Redraw background color
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
    // Set GL_MODELVIEW transformation mode
    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();   // Reset the matrix to identity matrix
          
    SystemClock.sleep ( 100 );  //delay for 0.1 second
    angle += 1;        //increment angle by 6 degrees

    // Move objects away from view point to observe
    gl.glTranslatef(0.0f, 0.0f, -10.0f);
    // Rotate about a diagonal of cube 
    gl.glRotatef(angle, 1.0f, 1.0f, 1.0f);
    // Draw the cube    
    cube.draw(gl);                                        
  }
    
  @Override
  public void onSurfaceChanged(GL10 gl, int width, int height) 
  {
    gl.glViewport(0, 0, width, height);
    gl.glMatrixMode(GL10.GL_PROJECTION);
    gl.glLoadIdentity();  // Reset projection matrix
    // Setup viewing volume
    GLU.gluPerspective(gl, 45.0f, (float)width / (float)height, 0.1f, 100.0f);
    gl.glViewport(0, 0, width, height);

    gl.glMatrixMode(GL10.GL_MODELVIEW);
    gl.glLoadIdentity();  // Reset transformation matrix
  }
}

class Cube 
{
  private FloatBuffer vertexBuffer;
  private FloatBuffer colorBuffer;
  private ByteBuffer  indexBuffer;
	        
  // Coordinates of 8 vertices of 6 cube faces 
  private float vertices[] = {
          -1.0f, -1.0f, -1.0f,
           1.0f, -1.0f, -1.0f,
           1.0f,  1.0f, -1.0f,
          -1.0f,  1.0f, -1.0f,
          -1.0f, -1.0f,  1.0f,
	   1.0f, -1.0f,  1.0f,
	   1.0f,  1.0f,  1.0f,
	  -1.0f,  1.0f,  1.0f
  };
  // Colors of vertices
  private float colors[] = {
          0.0f,  1.0f,  0.0f,  1.0f,
          0.0f,  1.0f,  0.0f,  1.0f,
          1.0f,  0.5f,  0.0f,  1.0f,
          1.0f,  0.5f,  0.0f,  1.0f,
          1.0f,  0.0f,  0.0f,  1.0f,
          1.0f,  0.0f,  0.0f,  1.0f,
          0.0f,  0.0f,  1.0f,  1.0f,
          1.0f,  0.0f,  1.0f,  1.0f
  };
	
  // indices of 12 triangles ( 6 squares ) in GL_CCW
  // using coordinates of vertices[] array 
  private byte indices[] = {
          5, 4, 0, 1, 5, 0,
          6, 5, 1, 2, 6, 1,
          7, 6, 2, 3, 7, 2,
          4, 7, 3, 0, 4, 3,
          6, 7, 4, 5, 6, 4,
          1, 0, 3, 2, 1, 3
  };
	                
  public Cube() {
    // initialize vertex Buffer for cube  
    // argument=(# of coordinate values * 4 bytes per float)
    ByteBuffer byteBuf = ByteBuffer.allocateDirect(vertices.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    // create a floating point buffer from the ByteBuffer
    vertexBuffer = byteBuf.asFloatBuffer();
    // add the coordinates to the FloatBuffer
    vertexBuffer.put(vertices);
    // set the buffer to read the first vertex coordinates 
    vertexBuffer.position(0);

    // Do the same to color values 
    byteBuf = ByteBuffer.allocateDirect(colors.length * 4);
    byteBuf.order(ByteOrder.nativeOrder());
    colorBuffer = byteBuf.asFloatBuffer();
    colorBuffer.put(colors);
    colorBuffer.position(0);
	                
    // indices are integer
    indexBuffer = ByteBuffer.allocateDirect(indices.length);
    indexBuffer.put(indices);
    indexBuffer.position(0);
  }

  // Typical drawing routine using vertex array
  public void draw(GL10 gl) 
  { 
     // Vertices of a front face are in counterclockwise order 
     gl.glFrontFace(GL10.GL_CCW);
	            
     gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
     gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
	            
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
     gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
	             
     gl.glDrawElements(GL10.GL_TRIANGLES, 36, GL10.GL_UNSIGNED_BYTE, 
	                            indexBuffer);
	                
     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
     gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
  }
}
