import java.awt.*;
import java.applet.*;
import java.util.*;
import java.lang.*;


public class CG_hw_05 extends BufferedApplet
{
	double[][] matrix = new double[4][4];
	

	
	double theta = Math.PI/2;
	double theta2 = Math.PI/2;
	double theta3 = Math.PI/2;
	
	
	final int STACKSIZE = 50;
	
	double mStack[][][] = new double[STACKSIZE][4][4];
	
	int mTop = 49;
	
	int n=85;
	int p;
	
	double dx, dy, dz;
	
	double tempAngle;
	
	double theta10 = Math.PI;
	double theta11 = Math.PI;
	double theta12 = Math.PI;

	
	
	public void render(Graphics g) 
	{
		// WHENEVER THERE IS "DAMAGE", WE NEED TO REDRAW

		if (damage) 
		{	
   			g.setColor(Color.black);
         	g.fillRect(0, 0, bounds().width, bounds().height);
   			
   	
   			Color col = new Color(10,100,100);
   			
   			g.setColor(Color.lightGray);
   			
   			Matrix3D.identity(matrix);
   	     
	
   			
   			ParametricTorus torus = new ParametricTorus(0.1,.1);
   			ParametricSphere sphere = new ParametricSphere(0,0,0,1);


 
 
 			Matrix3D.identity(mStack[mTop]);
 

 			
 			Matrix3D.scale(mStack[mTop],.2,.05,.05);

 			
 			Matrix3D.identity(mStack[mTop]);
 			
 		
 
 
 			//Shoulder
 			
 			Matrix3D.translate(mStack[mTop],-.2,0,0);
 			Matrix3D.zRotate(mStack[mTop],Math.PI/2);
 			
 			push();	
 				Matrix3D.zRotate(mStack[mTop],-Math.PI/2);
 				Matrix3D.zRotate(mStack[mTop],theta);	
				push();
				
 					Matrix3D.translate(mStack[mTop],-.1,0,0);
 		 			Matrix3D.scale(mStack[mTop],.1,.025,.025);
 					sphere.draw(g,mStack[mTop]);
  	 				
 				pop();
 				
 			
 			
				Matrix3D.translate(mStack[mTop],-.2,0,0);
 				Matrix3D.zRotate(mStack[mTop],Math.PI/2);
  		
				push();
			
					Matrix3D.zRotate(mStack[mTop],-Math.PI/2);
					Matrix3D.zRotate(mStack[mTop],theta2);
 						
				
 					push();
 						Matrix3D.translate(mStack[mTop],-.075,0,0);
 		 				Matrix3D.scale(mStack[mTop],.075,.015,.015);
 						sphere.draw(g,mStack[mTop]);		
  					
  					pop();
  					
  					
  					Matrix3D.translate(mStack[mTop],-.145,0,0);
 					Matrix3D.zRotate(mStack[mTop],Math.PI/2);
  		
					push();
			
						Matrix3D.zRotate(mStack[mTop],-Math.PI/2);
						Matrix3D.zRotate(mStack[mTop],theta3);
 						
				
 						push();
 							
 							Matrix3D.translate(mStack[mTop],-.034,0,0);
 		 					Matrix3D.scale(mStack[mTop],.035,.02,.015);
 							sphere.draw(g,mStack[mTop]);		
  					
  						pop();

  					
 					pop();
  					
  					
 				pop();
 			
 				Matrix3D.translate(mStack[mTop],.2,0,0);

 			pop();		
 			 		
 	 		Matrix3D.zRotate(mStack[mTop],-Math.PI/2);			
 			Matrix3D.translate(mStack[mTop],.2,0,0);
 			
 			
 			
 			
 			
 			
 			
 			g.setColor(Color.lightGray);
 			
 			
 			Matrix3D.identity(mStack[mTop]);
 
 
 			//Shoulder
 			
 			Matrix3D.translate(mStack[mTop],-.3,0,0);
 			Matrix3D.zRotate(mStack[mTop],Math.PI/2);
 			
 			push();	
 				Matrix3D.zRotate(mStack[mTop],-Math.PI/2);
 				Matrix3D.zRotate(mStack[mTop],theta);	
				push();
				
 					Matrix3D.translate(mStack[mTop],-.1,0,0);
 		 			Matrix3D.scale(mStack[mTop],.1,.025,.025);
 					sphere.draw(g,mStack[mTop]);
  	 				
 				pop();
 				
 			
 			
				Matrix3D.translate(mStack[mTop],-.2,0,0);
 				Matrix3D.zRotate(mStack[mTop],Math.PI/2);
  		
				push();
			
					Matrix3D.zRotate(mStack[mTop],-Math.PI/2);
					Matrix3D.zRotate(mStack[mTop],theta2);
 						
				
 					push();
 						Matrix3D.translate(mStack[mTop],-.075,0,0);
 		 				Matrix3D.scale(mStack[mTop],.075,.015,.015);
 						sphere.draw(g,mStack[mTop]);		
  					
  					pop();
  					
  					
  					Matrix3D.translate(mStack[mTop],-.145,0,0);
 					Matrix3D.zRotate(mStack[mTop],Math.PI/2);
  		
					push();
			
						Matrix3D.zRotate(mStack[mTop],-Math.PI/2);
						Matrix3D.zRotate(mStack[mTop],theta3);
 						
				
 						push();
 							Matrix3D.translate(mStack[mTop],-.034,0,0);
 		 					Matrix3D.scale(mStack[mTop],.035,.02,.015);
 							sphere.draw(g,mStack[mTop]);		
  					
  						pop();
  						
  						
  						Matrix3D.translate(mStack[mTop],-.03,0,0);
 						Matrix3D.zRotate(mStack[mTop],Math.PI/2);
  	
						push();
				
							
							
							Matrix3D.zRotate(mStack[mTop],-Math.PI/2);
 							Matrix3D.zRotate(mStack[mTop],theta3);
 							
 							
 							push();
 								
 							
 								if(!(n > 120  && n <180))
 								{
 									g.setColor(Color.red);
 									Matrix3D.translate(mStack[mTop],0.06,0.005,0);
 		 							Matrix3D.scale(mStack[mTop],.06,.06,.06);
 									sphere.draw(g,mStack[mTop]);
 									
 															
 									
 								}
 								
  							pop();
  					
 						pop();

  					
 					pop();
  					
  					
 				pop();
 			
 				Matrix3D.translate(mStack[mTop],.2,0,0);

 			pop();		
 
 
 
 
 			 		
 	 		Matrix3D.zRotate(mStack[mTop],-Math.PI/2);			
 			Matrix3D.translate(mStack[mTop],.2,0,0);
 	
 	
 			Matrix3D.identity(mStack[mTop]);
 			
 			Matrix3D.zRotate(mStack[mTop],Math.PI/4);
 			
 			Matrix3D.translate(mStack[mTop],0.006,.29,0);
 
 			
 			Matrix3D.scale(mStack[mTop],.06,.06,.06);
 			
  			
 			g.setColor(Color.blue);
 			g.fillOval(600,80,120,30);
 			
 			int x[]={680,760,760,680};
 			int y[]={10,20,150,140};
 			g.drawPolygon(x,y,4);
 			
 			
 			
 			g.setColor(Color.red);
 			Matrix3D.translate(mStack[mTop],dx,dy,dz);
 				
 			
 			
 			if(n > 120  && n <190)
 			{
 				sphere.draw(g,mStack[mTop]);
 
 				if(n>120 && n<169)
 				{
					dx+= 0.2;
					dy-=.08;
				}
					
				if(n>=169 && n<177)
				{
					dy-=.25;
					dx+=.1;
				}
				
				if(n>=177 && n<190)
				{
					dx-=.1;
				}
				
 				if(n==189)
 				{
 					dx=0;
 					dy=0;
 				}		
 									
 			}
 			
 			
 			g.setColor(Color.lightGray);
 
 
 
 			Matrix3D.identity(mStack[mTop]);
   			Matrix3D.translate(mStack[mTop],-.25,.24,0);

  	
			push();
				
 				push();
 				
 					Matrix3D.zRotate(mStack[mTop],theta11/70);
 					Matrix3D.translate(mStack[mTop],-.015,-.12,0);
 						
 					Matrix3D.scale(mStack[mTop],.05,.06,.06);
   					sphere.draw(g,mStack[mTop]);
   						
   					push();
   						Matrix3D.zRotate(mStack[mTop],theta10/50);
   						Matrix3D.zRotate(mStack[mTop],-Math.PI/25);
   						Matrix3D.translate(mStack[mTop],0,-3.4,0);
   					   	Matrix3D.scale(mStack[mTop],1.7,2.5,.7);
   			
   						sphere.draw(g,mStack[mTop]);
   						
   					pop();
   					   						
      				push();
   						Matrix3D.zRotate(mStack[mTop],theta10/50);
   						Matrix3D.zRotate(mStack[mTop],-Math.PI/25);
   						Matrix3D.translate(mStack[mTop],0,-6.5,0);
   					   	Matrix3D.scale(mStack[mTop],.7,1,.7);
   			
   						sphere.draw(g,mStack[mTop]);
   							
   							
   						push();
   						Matrix3D.zRotate(mStack[mTop],theta12/50);
   						Matrix3D.zRotate(mStack[mTop],-Math.PI/25);
   						Matrix3D.translate(mStack[mTop],0.3,-1.5,0);
   						Matrix3D.scale(mStack[mTop],.7,1.4,.7);
   			
   						sphere.draw(g,mStack[mTop]);
   						
   						
   						pop();
   						
   						
   					pop();
   						
   						

   						
 								
 	
  				pop();
  					
 			pop();


   				
 			if(n<=115)
 			{
 				theta += .06;
 				theta2 += 0.015;
 				theta3 -= .025;
 				theta10+=.1;
 				theta11+=.2;
 				theta12-=.9;
 				n++;
 			}
 			
			
 			else
 			{			
 				if(n >= 150 && n<=180)
 				{
 		 			theta -= .06;
 					theta2 -= 0.015;
 					theta3 += 0.025;
 					theta10 -=.1;
 					theta11-=.2;
 					theta12+=.9;			
 					
 				}
 				
 				if(n>118 && n<=129)
 				{
 					theta3 -= .1;
 					
 				}
 				 
 				 
 				if(n>129 && n<=140)
 				{
 					theta3 += .1;
 					
 				}
 				
 								
 				
 				n++;
 			}
 			
 			if(n==190)
 					n=85;
 		
  
   			animating = true;
   		}
   		
   		
   		
   	}
   	
   	
   	public void push()
   	{
   		if(mTop < 0)
   			System.out.println("Stack is full");
   		else
   		{
   			Matrix3D.copy(mStack[mTop],mStack[mTop-1]);
   			mTop--;
   		}
   	}
   	
   	
    public void pop()
   	{
   		if(mTop > 49)
   			System.out.println("Stack is empty");
   		else
   		{
   			mTop++;
   		}
   	}	





}

