/** Questo applet mostra un cubo che ruota.
 */


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

//// <applet code="AppletSolido.class" height = 600 width = 500> 
//// </applet>

public class AppletSolido extends JApplet {

    private Parallelepipedo mattone;
    private SpazioToPiano mioPiano;
    private double[] orientazione; 
    private int scala = 30;
    private double[][] vertice;
    private int[][] lato;
    private int[][] faccia;
    private Color[] colFacce = new Color[6];
    private Disegno disegno;
    private Timer t;

   
    /**
       Qui di seguito si vede l'utilizzo della classe Parallelepipedo.
       Come si vede, bisogna definire un array 8x3 che contiene le 
       coordinate spaziali degli 8 punti vertici del parallepipedo, 
       successivamente si deve definire un array 12x2 (denominato lato)
       che va cosi' interpretato: lato[i][0]=p, lato[i][1]=q significa
       che l'i-imo lato del parallelepipedo e' quello ottenuto congiungendo
       i vertici p e q.
       Infine si deve definire un array 6x4 (denominato faccia) tale
       che faccia[i][0]=v1, faccia[i][1]=v2, faccia[i][2]=v3, 
       faccia[i][3]=v4 significa che l'i-ima faccia e' costituita 
       dai vertici v1, v2, v3 e v4. Si noti che l'ordine in cui sono dati
       i vertici e' importante: e' richiesto che il prodotto esterno del
       vettore v2-v1 e del vettore v3-v1 sia un vettore con verso esterno
       al parallelepipedo.
    */
    public void init() {
	vertice = new double[8][3];
	vertice[0][0] = 4;
	vertice[0][1] = 3;
	vertice[0][2] = 2;
	    
	vertice[1][0] = 4; 
	vertice[1][1] = 3; 
	vertice[1][2] = -2;

	vertice[2][0] = 4; 
	vertice[2][1] = -3; 
	vertice[2][2] = -2; 
	    
	vertice[3][0] = 4; 
	vertice[3][1] = -3; 
	vertice[3][2] = 2;

	vertice[4][0] = -4;
	vertice[4][1] = 3; 
	vertice[4][2] = 2; 
	    
	vertice[5][0] = -4; 
	vertice[5][1] = -3; 
	vertice[5][2] = 2; 
	    
	vertice[6][0] = -4; 
	vertice[6][1] = -3;
	vertice[6][2] = -2;
	    
	vertice[7][0] = -4; 
	vertice[7][1] = 3;
	vertice[7][2] = -2; 
	    
	lato = new int[12][2];
	lato[0][0] = 0;
	lato[0][1] = 1;
	lato[1][0] = 1;
	lato[1][1] = 2;
	lato[2][0] = 2;
	lato[2][1] = 3;
	lato[3][0] = 3;
	lato[3][1] = 0;
	lato[4][0] = 0;
	lato[4][1] = 4;
	lato[5][0] = 1;
	lato[5][1] = 7;
	lato[6][0] = 2;
	lato[6][1] = 6;
	lato[7][0] = 3;
	lato[7][1] = 5;
	lato[8][0] = 4;
	lato[8][1] = 7;
	lato[9][0] = 7;
	lato[9][1] = 6;
	lato[10][0] = 6;
	lato[10][1] = 5;
	lato[11][0] = 5;
	lato[11][1] = 4;

	faccia = new int[6][4];
	faccia[0][0] = 0;
	faccia[0][1] = 3;
	faccia[0][2] = 2; 
	faccia[0][3] = 1;
	faccia[1][0] = 0;
	faccia[1][1] = 1;
	faccia[1][2] = 7; 
	faccia[1][3] = 4;
	faccia[2][0] = 1;
	faccia[2][1] = 2;
	faccia[2][2] = 6; 
	faccia[2][3] = 7;
	faccia[3][0] = 2;
	faccia[3][1] = 3;
	faccia[3][2] = 5;
	faccia[3][3] = 6;
	faccia[4][0] = 0;
	faccia[4][1] = 4; 
	faccia[4][2] = 5;
	faccia[4][3] = 3;
	faccia[5][0] = 4;
	faccia[5][1] = 7;
	faccia[5][2] = 6;
	faccia[5][3] = 5;

	// il seguente vettore indica che stiamo guardando il parallelepipedo
	// con l'occhio posto sulla retta dello spazio passante per i punti
	// (0,0,0) e orientazione.
	orientazione = new double[] {1, 1, 1};

	mattone = new Parallelepipedo(vertice, lato, faccia);

	// Costruiamo un oggetto della classe SpazioToPiano che permette
	// di convertire un punto dello spazio in un punto del piano dello
	// schermo.
	mioPiano = new SpazioToPiano(300, 300);

	disegno = new Disegno();
	Container c = getContentPane();
	disegno.setBackground(Color.black);
	c.add(disegno);
	colFacce = new Color[] {Color.red, Color.blue, Color.green,
	                        Color.yellow, Color.magenta, Color.cyan};
	
	ActionListener ric = new ActionListener() {
		public void actionPerformed(ActionEvent e) {
		    // Il mattone viene ruotato di due centesimi di 
		    // angolo giro attorno alla retta passante per l'origine
		    // e il punto (1, -1, 2).
		    mattone.ruotaSolido(new double[] {1,- 1, 2}, Math.PI/100);
		    disegno.repaint();
		}
	    };
	
	t = new Timer(100, ric);
	t.start();
    }
    

    private class Disegno extends JPanel {

	public void paintComponent(Graphics g) {
	    super.paintComponent(g);
	    for (int i = 0; i < faccia.length; i++) {
		disegnaFaccia(i, g);
	    }
	}
    }

    private void disegnaFaccia(int i, Graphics g) {
	if (mattone.facciaVisibile(i, orientazione)) {
	    int[] j = mattone.getVerticiFaccia(i);
	    double[][] vt = mattone.getVertici();
	    int[] a1 = mioPiano.coordPiane(vt[j[0]], scala);
	    int[] a2 = mioPiano.coordPiane(vt[j[1]], scala);
	    int[] a3 = mioPiano.coordPiane(vt[j[2]], scala);
	    int[] a4 = mioPiano.coordPiane(vt[j[3]], scala);


	    int[] xPol = new int[] {a1[0], a2[0], a3[0], a4[0]};
	    int[] yPol = new int[] {a1[1], a2[1], a3[1], a4[1]};
	    g.setColor(colFacce[i]);
	    g.fillPolygon(xPol, yPol, 4);


	}

    }
    public void stop() {
	if (t != null) 
	    t.stop();
    }
    public void destroy() {
	if (t != null) 
	    t=null;
    }
}
