/*
 * Figure.java
 *
 * Created on September 24, 2006, 9:08 PM
 *
 * To change this template, choose Tools | Options and locate the template under
 * the Source Creation and Management node. Right-click the template and choose
 * Open. You can then make changes to the template in the Source Editor.
 */

/**
 *
 * @author Alex
 */
//<pre>
// Draw a simple house

import java.awt.*;

public class Figure extends BufferedApplet
{ 
    
    double original_points[][][] = {
        //left boot
        {{0, 0, 0}, {0.21, 0, 0}, {0.21, -.14, 0}, {.14, -.21, 0}, {0.07, -.21, 0},{0, -.14, 0}},
        {{0, 0.1, 0}, {0, .45, 0}, {.07, .52, 0}, {.14, .52, 0}, {.21, .45, 0}, {.21, .1, 0}},
        //right boot 
        {{-.1, 0, 0}, {-.1, -.14, 0}, {-.17, -.21, 0}, {-.24, -.21, 0}, {-.31, -.14, 0}, {-.31, 0, 0}},
        {{-.1, .1, 0}, {-.31, .1, 0}, {-.31, .45, 0}, {-.24, .52, 0}, {-.17, .52, 0}, {-.1, .45, 0}},                        
    };       
    
    // ATTEMPT HERE IS TO DRAW FOOTPRINTS
    double points[][][] = {
        //left boot
        {{0, 0, 0}, {0.21, 0, 0}, {0.21, -.14, 0}, {.14, -.21, 0}, {0.07, -.21, 0},{0, -.14, 0}},
        {{0, 0.1, 0}, {0, .45, 0}, {.07, .52, 0}, {.14, .52, 0}, {.21, .45, 0}, {.21, .1, 0}},
        //right boot 
        {{-.1, 0, 0}, {-.1, -.14, 0}, {-.17, -.21, 0}, {-.24, -.21, 0}, {-.31, -.14, 0}, {-.31, 0, 0}},
        {{-.1, .1, 0}, {-.31, .1, 0}, {-.31, .45, 0}, {-.24, .52, 0}, {-.17, .52, 0}, {-.1, .45, 0}},                        
    };       
   
    double temp_points[][][] = {
        //left boot
        {{0, 0, 0}, {0.21, 0, 0}, {0.21, -.14, 0}, {.14, -.21, 0}, {0.07, -.21, 0},{0, -.14, 0}},
        {{0, 0.1, 0}, {0, .45, 0}, {.07, .52, 0}, {.14, .52, 0}, {.21, .45, 0}, {.21, .1, 0}},
        //right boot 
        {{-.1, 0, 0}, {-.1, -.14, 0}, {-.17, -.21, 0}, {-.24, -.21, 0}, {-.31, -.14, 0}, {-.31, 0, 0}},
        {{-.1, .1, 0}, {-.31, .1, 0}, {-.31, .45, 0}, {-.24, .52, 0}, {-.17, .52, 0}, {-.1, .45, 0}},                        
    };     
    
    double a[] = {0,0,0}, b[] = {0,0,0};
    int w, h, count = 0;
    double t = 1; //scaling factor
    double move_x = 0;
    double move_y = 0;
    double move_z = 0;
    double theta = 0; // rotation angle
    Matrix3D M;
    int last_action;
    boolean initial_paint = true;
    boolean is_left = false;  //start walking right foot fwd
    boolean started_walking = false;
    boolean did_first_step = false;
   
    public void init() {
	super.init();

	// YOU MIGHT WANT TO CREATE YOUR MATRIX OBJECTS HERE
	M = new Matrix3D();
    }

    public void render(Graphics g) {
 
	w = bounds().width;                         // FIND OUT HOW BIG THE APPLET WINDOW IS
	h = bounds().height;

	g.setColor(Color.white);                    // MAKE A CLEAR WHITE BACKGROUND
	g.fillRect(0,0,w,h);

	g.setColor(Color.black);                    // SET THE DRAWING COLOR TO BLACK

	if(last_action == 'w') { //simulate walking
            walk(g);
	}
	else {
	    animate();                                  // DO ANIMATION CALCULATIONS
	    for (int i = 0 ; i < points.length ; i++) {   // LOOP THROUGH ALL THE SHAPES
		Polygon P = new Polygon();
		for (int j = 0 ; j < points[i].length ; j++) { // LOOP THROUGH ALL THE POINTS IN THE SHAPE
		    transform(points[i][j], a);                // TRANSFORM EACH POINT
		    P.addPoint(x(a[0]), y(a[1]));
		    temp_points[i][j][0] = a[0];                    // store the new location for continuability
		    temp_points[i][j][1] = a[1];
		} 
		g.fillPolygon(P);
	    }
	}
    }

    void animate() {
	switch(last_action) {
	case 's': case 'S':
            M.identityMatrix();
            M.scale(t, t, 1);
	    break;
 
	case 'r': case 'R':
            M.identityMatrix();
            M.rotateZ(theta);
	    break;
      
	case 1004:  // UP -- could not find thouse defines
            M.identityMatrix();
            M.translate(0, move_y, 0); 
	    break;
	case 1005:  // down -- could not find thouse defines
            M.identityMatrix();
            M.translate(0, move_y, 0);    
	    break;    
	case 1006:  // left
            M.identityMatrix();
            M.translate(move_x, 0, 0); 
	    break;   
	case 1007:  // right
            M.identityMatrix();
            M.translate(move_x, 0, 0);    
	    break;     
     
	default:break;
	}
    }
   
    int x(double c) { return w/2 + (int)(c*w/4); } // CONVERT X COORDINATE TO SCREEN PIXELS
    int y(double c) { return h/2 - (int)(c*w/4); } // CONVERT Y COORDINATE TO SCREEN PIXELS

    void transform(double src[], double dst[]) {
	if(last_action == 'z') {
	    dst[0] = src[0];
	    dst[1] = src[1];
	    dst[2] = src[2];
	}
	else
	    M.transform(src, dst);
    }
 
    public void fillMyPolygon(Graphics g, Polygon P) {
	g.fillPolygon(P);
    }
   
   
    public boolean keyDown(Event e, int key) {

	//start over
	if(key == 'z') {
	    for (int i = 0; i<points.length; i++)
		for(int j = 0; j<points[i].length; j++) {
                    points[i][j][0] = original_points[i][j][0];
                    points[i][j][1] = original_points[i][j][1];
                    points[i][j][2] = 0;
		}
	    damage = true;
	    last_action = key;
	    move_x = 0;
	    move_y = 0;
	    t = 1;
	    theta = 0;  
	    count = 0;
	    move_z = 0;
	    M.identityMatrix();
	    last_action = 0;
	    initial_paint = true;
	    is_left = false;  //start walking right foot fwd
	    started_walking = false;
	    return true;
	}
       
	if(last_action != key) { // user does something new.. remember continuity
	    // we continue from this point (as original) on
	    for (int i = 0; i<points.length; i++)
		for(int j = 0; j<points[i].length; j++) {
                    points[i][j][0] = temp_points[i][j][0];
                    points[i][j][1] = temp_points[i][j][1];
		}
           
	    last_action = key; // memorize key event
	}
       
	// do this here and not in animate so that I can control the applet from keyboard
	// key press and nothing and key press and nothing and etc...
	switch(last_action) {
	case 's': case 'S':
            //calc x,y scaling factor based on sin function     
            t = .7 + .3 * Math.sin(.1 * count++);       
	    break;
 
	case 'r': case 'R':
            //calc turning angle     
            theta = Math.PI/6  * ((count++));       
	    break;
      
	case 1004:  // UP -- could not find thouse defines
            move_y += 0.05;     
	    break;
	case 1005:  // down -- could not find thouse defines
            move_y -= 0.05;     
	    break;    
	case 1006:  // left
            move_x -= 0.05;     
	    break;   
	case 1007:  // right
            move_x += 0.05;            
	    break;     
          
	default:break;
	}
       
	return true;
    }
   
    public void walk(Graphics g) {
       
	Polygon P = new Polygon();       
	if(!started_walking) {
	    start_position(g);
	}
	else if(!did_first_step) {
	    // do 1st step (which is 1/2 step
	    do_first_step(g);
	}
	else {//keep on walking
            if(is_left && ++count%20 == 0) {
                // move left foot
                M.identityMatrix();
                M.translate(.3, .3, 0);
                for (int i = 2; i<points.length; i++){  // start with original
                    P.reset();
		    for(int j = 0; j<points[i].length; j++) {
			transform(points[i][j], a);                // TRANSFORM EACH POINT
			P.addPoint(x(a[0]), y(a[1]));
			points[i][j][0] = a[0];                    // store the new location for continuability
			points[i][j][1] = a[1];
		    }
                    g.drawPolygon(P);
                }
                // still draw the other print , else it's a monopod
                M.identityMatrix();
                for (int i = 0; i<points.length/2; i++){  // start with original
                    P.reset();
		    for(int j = 0; j<points[i].length; j++) {
			transform(points[i][j], a);                // TRANSFORM EACH POINT
			P.addPoint(x(a[0]), y(a[1]));
			points[i][j][0] = a[0];                    // store the new location for continuability
			points[i][j][1] = a[1];
		    }
                    g.drawPolygon(P);
		}
                is_left = false;
            }
            else if(!is_left && ++count%20 == 0){
                // move right foot
                M.identityMatrix();
                M.translate(.3, .3, 0);
                for (int i = 0; i<points.length/2; i++) { // start with original
                    P.reset();
		    for(int j = 0; j<points[i].length; j++) {
			transform(points[i][j], a);                // TRANSFORM EACH POINT
			P.addPoint(x(a[0]), y(a[1]));
			points[i][j][0] = a[0];                    // store the new location for continuability
			points[i][j][1] = a[1];
		    }
                    g.drawPolygon(P);
                }
                M.identityMatrix();
                for (int i = 2; i<points.length; i++){  // start with original
                    P.reset();
		    for(int j = 0; j<points[i].length; j++) {
			transform(points[i][j], a);                // TRANSFORM EACH POINT
			P.addPoint(x(a[0]), y(a[1]));
			points[i][j][0] = a[0];                    // store the new location for continuability
			points[i][j][1] = a[1];
		    }
                    g.drawPolygon(P);
                }
		is_left = true;
            }
            else { // paint the status quo {
                M.identityMatrix();
		for (int i = 0 ; i < points.length ; i++) {   // LOOP THROUGH ALL THE SHAPES
		    P.reset();
		    for (int j = 0 ; j < points[i].length ; j++) { // LOOP THROUGH ALL THE POINTS IN THE SHAPE
			transform(points[i][j], a);                // TRANSFORM EACH POINT
			P.addPoint(x(a[0]), y(a[1]));
			temp_points[i][j][0] = a[0];                    // store the new location for continuability
			temp_points[i][j][1] = a[1];
		    } 
		    g.drawPolygon(P);
		}    
            }
	}
	/// WALKING IS HARD WORK.....
    }

    public void start_position(Graphics g) {
	Polygon P  = new Polygon();
	// i can walk only in one direction... 
	for (int i = 0; i<points.length; i++)  // start with original
	    for(int j = 0; j<points[i].length; j++) {
		points[i][j][0] = original_points[i][j][0];
		points[i][j][1] = original_points[i][j][1];
		points[i][j][2] = 0;
	    }
	M.identityMatrix();
	M.rotateZ(7*Math.PI/4);
	M.scale(0.3, 0.3, 0);
	//M.translate(-3, 0, 0);
	M.translate(0, -4, 0);
	started_walking = true; 
	for (int i = 0 ; i < points.length ; i++) {   // LOOP THROUGH ALL THE SHAPES
            P.reset();  //empty the polygon 
	    for (int j = 0 ; j < points[i].length ; j++) { // LOOP THROUGH ALL THE POINTS IN THE SHAPE
		transform(points[i][j], a);                // TRANSFORM EACH POINT
		P.addPoint(x(a[0]), y(a[1]));
		points[i][j][0] = a[0];                    // store the new location for continuability
		points[i][j][1] = a[1];
	    }
            g.drawPolygon(P);
	}
    }
    
    public void do_first_step(Graphics g) {
	Polygon P = new Polygon();
	// move right foot
	M.identityMatrix();
	M.translate(.15, .15, 0);
	for (int i = 0; i<points.length/2; i++) { // start with original
	    P.reset();
	    for(int j = 0; j<points[i].length; j++) {
		transform(points[i][j], a);                // TRANSFORM EACH POINT
		P.addPoint(x(a[0]), y(a[1]));
		points[i][j][0] = a[0];                    // store the new location for continuability
		points[i][j][1] = a[1];
	    }
	    g.drawPolygon(P);
	}
	M.identityMatrix();
	for (int i = 2; i<points.length; i++){  // start with original
	    P.reset();
	    for(int j = 0; j<points[i].length; j++) {
		transform(points[i][j], a);                // TRANSFORM EACH POINT
		P.addPoint(x(a[0]), y(a[1]));
		points[i][j][0] = a[0];                    // store the new location for continuability
		points[i][j][1] = a[1];
	    }
	    g.drawPolygon(P);
	}
	is_left = true;
	did_first_step = true;
    }

}


