import java.io.*;
import javax.media.opengl.*;
import javax.media.opengl.glu.GLU;
import com.sun.opengl.util.FPSAnimator;
import com.sun.opengl.util.texture.*;

/**
 * CS400 3DMotionCapture
 * CMCAnimationThread
 * 
 * Display animation according to the data given from MarkerTracking class
 * Due to the I/O input slowness, this program always run after CMCVideoThread. 
 * To notify to CMCAnimation, you should update this program at the end of display function.
 * 
 * @author Kohei Shinkawa
 * @deprecated
 * */
public class CMCAnimationThread implements Runnable, GLEventListener {

	private GLU glu = new GLU();
	private GLJPanel canvas; 
	double[][] coordsArray; 
	private FPSAnimator animator;
	private CMCThreadInfo info;
	private Texture JackFace, rightHand, leftHand;  
	private boolean loaded =  false;

	public CMCAnimationThread(double[][] coords, GLJPanel canvas, int fps, CMCThreadInfo info){	
		this.info = info;
		this.canvas = canvas;
		
		animator = new FPSAnimator(this.canvas, fps);
		animator.setRunAsFastAsPossible(true);
		new FPSAnimator(new GLJPanel(), fps);
		coordsArray = coords;
		canvas.addGLEventListener(this);
		canvas.requestFocus();
	}
	
	public void run() {
		/*Animator calls display at the constant rate*/
		animator.start();	
	}

	public void display(GLAutoDrawable glDrawable) {
		
		if(info.isInit() && info.isReady()){
			System.out.println("Anime Black");

			final GL gl = glDrawable.getGL();
			gl.glLoadIdentity();
			gl.glMatrixMode(GL.GL_MODELVIEW);
			
			gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			gl.glClear(GL.GL_COLOR_BUFFER_BIT);
			info.setInit(false);
			info.setReady(false);

		}
		else if(!info.isReady() || !info.isDone()){
			/*Wait for CMCVideoThread*/
			//System.out.println("Anime: Wait");
			}
		
		else if((info.getCurFrame() > info.getEndFrame()-1 && !info.isRewind())|| (info.getCurFrame() <= info.getEndFrame()-1 && info.isRewind()) ) {
			/*Stop since it's end of frames*/ 			//System.out.println("Anime: Stop");
			}
		
		else{
			//System.out.println("Anime");
			if(info.getCurFrame() >= coordsArray.length) info.setCurFrame(coordsArray.length-1);
			final GL gl = glDrawable.getGL();
			if(!loaded){
				try {
					System.err.println("Loading texture...");
					JackFace = TextureIO.newTexture(new File("Skin/JackFace.jpg"), true);
					leftHand = TextureIO.newTexture(new File("Skin/lefthand.jpg"), true);
					rightHand =  TextureIO.newTexture(new File("Skin/righthand.jpg"), true);
				} catch (IOException e) {
					e.printStackTrace();
				}
				finally{
					loaded = true;
				}
			}
			
			double height = info.getHeight();
			double width = info.getWidth();
			//int curFrame = info.getCurFrame();
			
			gl.glLoadIdentity();
			glu.gluOrtho2D((double) 0,(double) width,(double) height,(double) 0);
			gl.glMatrixMode(GL.GL_MODELVIEW);
			
			gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			gl.glClear(GL.GL_COLOR_BUFFER_BIT);

			draw(gl);
			if(info.isPlay()){
				if(!info.isRewind()){ info.setCurFrame(info.getCurFrame() +1);}
				else if(info.getCurFrame() > 0) {info.setCurFrame(info.getCurFrame()- 1);}
			}
			/*Set flag for CMCVideoThread*/
			info.setReady(false);
			}	
		
	}
	
	private void draw(GL gl){
		double height = info.getHeight();
		double width = info.getWidth();
		int curFrame = info.getCurFrame();
		
		/*
		 * head
		 * left shoulder
		 * right shoulder
		 * right elbow
		 * left elbow
		 * right hand
		 * left hand
		 * left hip
		 * right hip
		 * right knee
		 * left knee
		 * right foot
		 * left foot*/

		Double[] head = {coordsArray[curFrame][0]*width, coordsArray[curFrame][1]*height, coordsArray[curFrame][2]}; 
		Double[] rshol = {coordsArray[curFrame][3]*width, coordsArray[curFrame][4]*height, coordsArray[curFrame][5]}; 
		Double[] lshol = {coordsArray[curFrame][6]*width, coordsArray[curFrame][7]*height, coordsArray[curFrame][8]}; 
		Double[] rmidarm = {coordsArray[curFrame][9]*width, coordsArray[curFrame][10]*height, coordsArray[curFrame][11]}; 
		Double[] lmidarm = {coordsArray[curFrame][12]*width, coordsArray[curFrame][13]*height, coordsArray[curFrame][14]}; 
		Double[] rhand = {coordsArray[curFrame][15]*width, coordsArray[curFrame][16]*height, coordsArray[curFrame][17]}; 
		Double[] lhand = {coordsArray[curFrame][18]*width, coordsArray[curFrame][19]*height, coordsArray[curFrame][20]}; 
		//Double[] lhand = {coordsArray[curFrame][21]*width, coordsArray[curFrame][22]*height, coordsArray[curFrame][23]}; 
		//Double[] rhand = {coordsArray[curFrame][24]*width, coordsArray[curFrame][25]*height, coordsArray[curFrame][26]}; 
		Double[] rhip = {coordsArray[curFrame][21]*width, coordsArray[curFrame][22]*height, coordsArray[curFrame][23]}; 
		Double[] lhip = {coordsArray[curFrame][24]*width, coordsArray[curFrame][25]*height, coordsArray[curFrame][26]}; 
		//Double[] lhip = {coordsArray[curFrame][15]*width, coordsArray[curFrame][16]*height, coordsArray[curFrame][17]}; 
		//Double[] rhip = {coordsArray[curFrame][18]*width, coordsArray[curFrame][19]*height, coordsArray[curFrame][20]}; 
		Double[] rknee = {coordsArray[curFrame][27]*width, coordsArray[curFrame][28]*height, coordsArray[curFrame][29]}; 
		Double[] lknee = {coordsArray[curFrame][30]*width, coordsArray[curFrame][31]*height, coordsArray[curFrame][32]}; 
		Double[] rfoot = {coordsArray[curFrame][33]*width, coordsArray[curFrame][34]*height, coordsArray[curFrame][35]}; 
		Double[] lfoot = {coordsArray[curFrame][36]*width, coordsArray[curFrame][37]*height, coordsArray[curFrame][38]};
	
		//System.out.println(curFrame);
		gl.glColor3f(1f, 1f, 1f); 
		
		/*Adding textures*/
		if(head[0] > 0) {
			 if (JackFace != null) {
				 
				 	JackFace.bind();
				 	JackFace.enable();
		            gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
		            //gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR);
		            TextureCoords coords = JackFace.getImageTexCoords();

		            gl.glBegin(GL.GL_QUADS);
		            gl.glTexCoord2f(coords.left(), coords.bottom());
		            gl.glVertex2d(head[0]-30, head[1]+45);
		            gl.glTexCoord2f(coords.right(), coords.bottom());
		            gl.glVertex2d(head[0]+30, head[1]+45);
		            gl.glTexCoord2f(coords.right(), coords.top());
		            gl.glVertex2d(head[0]+30, head[1]-45);
		            gl.glTexCoord2f(coords.left(), coords.top());
		            gl.glVertex2d(head[0]-30, head[1]-45);
		            gl.glEnd();
		            //System.out.println("Face!");
		            JackFace.disable();

		        }else{
		            System.out.println("Hello");
		        }
		} 
		
		if(rhand[0] > 0) {
			 if (rightHand != null) {
				 
				 rightHand.bind();
				 rightHand.enable();
		            gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
		            //gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR);
		            TextureCoords coords = rightHand.getImageTexCoords();

		            gl.glBegin(GL.GL_QUADS);
		            gl.glTexCoord2f(coords.left(), coords.bottom());
		            gl.glVertex2d(rhand[0]-30, rhand[1]+40);
		            gl.glTexCoord2f(coords.right(), coords.bottom());
		            gl.glVertex2d(rhand[0]+30, rhand[1]+40);
		            gl.glTexCoord2f(coords.right(), coords.top());
		            gl.glVertex2d(rhand[0]+30, rhand[1]-40);
		            gl.glTexCoord2f(coords.left(), coords.top());
		            gl.glVertex2d(rhand[0]-30, rhand[1]-40);
		            gl.glEnd();
		            //System.out.println("Hand!");
		            rightHand.disable();

		        }else{
		            //System.out.println("Hello");
		        }
		} 
		
		if(lhand[0] > 0) {
			 if (leftHand != null) {
				 
				 leftHand.bind();
				 leftHand.enable();
		            gl.glTexEnvi(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
		            //gl.glTexParameteri(gl.GL_TEXTURE_2D,gl.GL_TEXTURE_MAG_FILTER,gl.GL_LINEAR);
		            TextureCoords coords = leftHand.getImageTexCoords();

		            gl.glBegin(GL.GL_QUADS);
		            gl.glTexCoord2f(coords.left(), coords.bottom());
		            gl.glVertex2d(lhand[0]-30, lhand[1]+40);
		            gl.glTexCoord2f(coords.right(), coords.bottom());
		            gl.glVertex2d(lhand[0]+30, lhand[1]+40);
		            gl.glTexCoord2f(coords.right(), coords.top());
		            gl.glVertex2d(lhand[0]+30, lhand[1]-40);
		            gl.glTexCoord2f(coords.left(), coords.top());
		            gl.glVertex2d(lhand[0]-30, lhand[1]-40);
		            gl.glEnd();
		            //System.out.println("Hand!");
		            leftHand.disable();

		        }else{
		            System.out.println("Hello");
		        }
		} 
		
		/*Draw Points*/
		gl.glPointSize(10.0f);
		gl.glBegin(GL.GL_POINTS);
		
		//if(head[0] > 0) gl.glVertex2d(head[0], head[1]);
		gl.glColor3f(1f, 1f, 1f); 

		if(rshol[0] > 0) gl.glVertex3d(rshol[0], rshol[1], 0);
		if(lshol[0] > 0) gl.glVertex3d(lshol[0], lshol[1], 0);
		if(rmidarm[0] > 0) gl.glVertex3d(rmidarm[0], rmidarm[1], 0);
		if(lmidarm[0] > 0) gl.glVertex3d(lmidarm[0], lmidarm[1], 0);
		//if(rhand[0] > 0) gl.glVertex2d(rhand[0], rhand[1]);
		//if(lhand[0] > 0) gl.glVertex2d(lhand[0], lhand[1]);
		if(rhip[0] > 0) gl.glVertex3d(rhip[0], rhip[1],0);
		if(lhip[0] > 0) gl.glVertex3d(lhip[0], lhip[1], 0);

		if(rknee[0] > 0) gl.glVertex3d(rknee[0], rknee[1],0);
		if(lknee[0] > 0) gl.glVertex3d(lknee[0], lknee[1],0);
		if(rfoot[0] > 0) gl.glVertex3d(rfoot[0], rfoot[1],0);
		if(lfoot[0] > 0) gl.glVertex3d(lfoot[0], lfoot[1],0);

		gl.glEnd();		
		
		
		/*Drawing the body parts (right now it's just bunch of lines)*/
		gl.glLineWidth(2.0f);
		gl.glColor3f(1f, 1f, 1f); 

		gl.glBegin(GL.GL_LINES);		
		
		/*Right arm*/
		if(rshol[0]> 0 && rmidarm[0] > 0){
			gl.glVertex3d(rshol[0], rshol[1],0);
			gl.glVertex3d(rmidarm[0], rmidarm[1],0);
		}
		if(rhand[0]> 0 && rmidarm[0] > 0){
			gl.glVertex3d(rhand[0], rhand[1],0);
			gl.glVertex3d(rmidarm[0], rmidarm[1],0);
		}
		
		/*Left Arm*/
		if(lshol[0]> 0 && lmidarm[0] > 0){
			gl.glVertex3d(lshol[0], lshol[1],0);
			gl.glVertex3d(lmidarm[0], lmidarm[1],0);
		}
		if(lhand[0]> 0 && lmidarm[0] > 0){
			gl.glVertex3d(lhand[0], lhand[1],0);
			gl.glVertex3d(lmidarm[0], lmidarm[1],0);
		}
		
		/*Right leg*/
		if(rhip[0] >0 && rknee[0] > 0){
			gl.glVertex3d(rhip[0], rhip[1],0);
			gl.glVertex3d(rknee[0], rknee[1],0);
		}
		if(rfoot[0] >0 && rknee[0] > 0){
			gl.glVertex3d(rfoot[0], rfoot[1],0);
			gl.glVertex3d(rknee[0], rknee[1],0);
		}
		
		/*Left leg*/
		if(lhip[0] >0 && lknee[0] > 0){
			gl.glVertex3d(lhip[0], lhip[1],0);
			gl.glVertex3d(lknee[0], lknee[1],0);
		}
		if(lfoot[0] >0 && lknee[0] > 0){
			gl.glVertex3d(lfoot[0], lfoot[1],0);
			gl.glVertex3d(lknee[0], lknee[1],0);
		}
		gl.glEnd();
		
		
		if(rshol[0] >0 && lshol[0]>0 && rhip[0]>0 && lhip[0]>0){
			gl.glBegin(GL.GL_LINE_LOOP);
			gl.glVertex3d(lshol[0], lshol[1],0);
			gl.glVertex3d(rshol[0], rshol[1],0);
			gl.glVertex3d(rhip[0], rhip[1],0);
			gl.glVertex3d(lhip[0], lhip[1],0);
			gl.glEnd();
		}
		


	}
	public void displayChanged(GLAutoDrawable arg0, boolean arg1, boolean arg2) {}

	public void init(GLAutoDrawable glDrawable) {}

	public void reshape(GLAutoDrawable arg0, int arg1, int arg2, int arg3,int arg4) {}

}
