import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.lang.Math.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.GraphicsConfiguration;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.ColorCube;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.behaviors.vp.OrbitBehavior;

public class xct extends JApplet{
    Canvas3D canvas;
    AnimePanel canvas2;
    JCheckBox stopCB;
    JSlider speedBar;
    JButton restartButton;
    JPanel animePanel;
    javax.swing.Timer tm;
    SimpleUniverse u;

    BranchGroup scene;

    double t=0.0;
    double stepT=0.01;

    public void setStepTime(double a) {
	stepT=a;
    }
    public void destroy() {
        u.cleanup();
    }
    public void init(){
        Container cont=getContentPane();
        cont.setLayout(new BorderLayout());
        
        
        GraphicsConfiguration config =SimpleUniverse.getPreferredConfiguration();
        
        canvas = new Canvas3D(config);
        canvas2 = new AnimePanel();

        scene = new BranchGroup();


        u = new SimpleUniverse(canvas);
        u.getViewingPlatform().setNominalViewingTransform();

        scene.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
        scene.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);


        tm= new javax.swing.Timer(50,
                                  new ActionListener() {
                                      public void actionPerformed(ActionEvent e){
                                          t=t+stepT;
                                          repaint();
                                      }
                                  }
                                  );

        getRootPane().setDoubleBuffered(true);
        

        speedBar = new JSlider(0,50,10);
        speedBar.setMajorTickSpacing(10);
        speedBar.setMinorTickSpacing(1);
        speedBar.setPaintTicks(true);
        speedBar.setPaintLabels(true);

	speedBar.addChangeListener(new ChangeListener() {
		public void stateChanged(ChangeEvent e) {
		    int k=speedBar.getValue();
		    if( k==0 ) {
			tm.stop();
		    } else {
			tm.setDelay(1000/k);
			tm.restart();
		    }
		}
	    });
	

	stopCB=new JCheckBox("中断");
	restartButton=new JButton("もう一度最初から");

	stopCB.addItemListener(new ItemListener() {
		public void  itemStateChanged(ItemEvent evt) {
		    if( stopCB.isSelected() ) {
			tm.stop();
		    } else {
			tm.start();
		    }
		}
	    });
      

	cbS = new JCheckBox("太陽");
	cbE = new JCheckBox("地球");

	cbS.addItemListener(new ItemListener() {
		public void  itemStateChanged(ItemEvent evt) {
		    if( cbS.isSelected() ) {
			standing = new Standing((float)t);
			scene.addChild(standing);
		    } else {
			standing.detach();
		    }
		}
	    });

	cbE.addItemListener(new ItemListener() {
		public void  itemStateChanged(ItemEvent evt) {
		    if( cbE.isSelected() ) {
			earth = new Earth();
		    } else {
			earth.detach();
		    }
		}
	    });



	restartButton.addActionListener(new ActionListener() {
		public void actionPerformed(ActionEvent evt) {
		    t=0;
		    tm.start();
		    stopCB.setSelected(false);
		}
	    });     
	
	Label l=new Label("コマ数／秒");
	
	JPanel animePanelSub=new JPanel();
	animePanelSub.setLayout( new BorderLayout());
	animePanelSub.add(l,BorderLayout.WEST);
	animePanelSub.add(speedBar,BorderLayout.CENTER);
	

	animePanel = new JPanel();
	animePanel.setLayout( new BorderLayout());
	animePanel.add(stopCB,BorderLayout.WEST);
	animePanel.add(animePanelSub,BorderLayout.CENTER);
	animePanel.add(restartButton,BorderLayout.EAST);
	
	JPanel p1=new JPanel();
	p1.setLayout(new GridLayout(1,2));
	p1.add(canvas);
	p1.add(canvas2);
	JPanel p2=new JPanel();
	p2.setLayout(new GridLayout(2,1));
	p2.add(animePanel);
	JPanel p3=new JPanel();
	p3.add(cbS);
	p3.add(cbE);

	p2.add(p3);



	cont.add("Center",p1);
	cont.add("South",p2);
	lightcone = new LightCone(0f);
	//	standing = new Standing(0f);
	scene.addChild(lightcone);
	// scene.addChild(standing);

	
	QuadArray xyp= new QuadArray(4,QuadArray.COORDINATES|QuadArray.COLOR_3);
	xyp.setCoordinate(0,new Point3f(1f,-0.5f,1f));
	xyp.setCoordinate(1,new Point3f(-1f,-0.5f,1f));
	xyp.setCoordinate(2,new Point3f(-1f,-0.5f,-1f));
	xyp.setCoordinate(3,new Point3f(1f,-0.5f,-1f));
	for(int i=0; i<4; i++){xyp.setColor(i, new Color3f(1.0f,1.0f,1.0f));}
	
	PolygonAttributes attrib = new PolygonAttributes();
	attrib.setCullFace(PolygonAttributes.CULL_NONE);
	attrib.setPolygonMode(PolygonAttributes.POLYGON_FILL);
	
	TransparencyAttributes transAttrib;
	transAttrib = new TransparencyAttributes(TransparencyAttributes.NICEST,0.6f);
	
	Appearance appear = new Appearance();
	appear.setPolygonAttributes(attrib);
	appear.setTransparencyAttributes(transAttrib);
	appear.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_READ);
	appear.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE);
	
	xyPlane=new Shape3D();
	xyPlane.removeGeometry(0);
	xyPlane.addGeometry(xyp);
	xyPlane.setAppearance(appear);
	xyPlane.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
	xyPlane.setCapability(Shape3D.ALLOW_APPEARANCE_READ);


	tPlane=new Shape3D();
	tPlane.removeGeometry(0);
	tPlane.addGeometry(xyp);
	TransparencyAttributes transAttrib2;
	transAttrib2 = new TransparencyAttributes(TransparencyAttributes.NICEST,0.4f);
	
	Appearance appear2 = new Appearance();
	appear2.setPolygonAttributes(attrib);
	appear2.setTransparencyAttributes(transAttrib2);
	appear2.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_READ);
	appear2.setCapability(Appearance.ALLOW_TRANSPARENCY_ATTRIBUTES_WRITE);

	tPlane.setAppearance(appear2);
	tPlane.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
	tPlane.setCapability(Shape3D.ALLOW_APPEARANCE_READ);

	tPlaneTS=new Transform3D();
	tPlaneTS.setTranslation(new Vector3f(0f,0f,0f));

	tg= new TransformGroup();
 
	tg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
	tg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

	tg.setTransform(tPlaneTS);
	tg.addChild(tPlane);
 
        OrbitBehavior orbit = new OrbitBehavior(canvas, OrbitBehavior.REVERSE_ALL);
        orbit.setSchedulingBounds(new BoundingSphere(new Point3d(0, 0, 0), 100.0));
        u.getViewingPlatform().setViewPlatformBehavior(orbit);
        ViewingPlatform vP=u.getViewingPlatform();

	vP.setNominalViewingTransform();

	DirectionalLight light1 = new DirectionalLight( true,
							new Color3f(1.0f, 1.0f, 1.0f),
							new Vector3f(0.0f, -1.0f, -1.0f));
        
        AmbientLight light2= new AmbientLight(new Color3f(1f,1f,1f));
        light1.setInfluencingBounds(new BoundingSphere(new Point3d(), 100.0));
        light2.setInfluencingBounds(new BoundingSphere(new Point3d(), 100.0));

        scene.addChild(light1);
        scene.addChild(light2);
        scene.addChild(new Background(1.0f,1.0f,1.0f));

	scene.addChild(xyPlane);
	scene.addChild(tg);

	u.addBranchGraph(scene);
	tm.start();
    }

    class AnimePanel extends JPanel {
	public void paintComponent(Graphics g){
	    writeCanvas(g);
	}
    }

    class Standing extends BranchGroup {
	Cylinder c;
	Standing(float r) {
	    setCapability(BranchGroup.ALLOW_DETACH);
	    Appearance ap = new Appearance();
            Material apma = new Material();
            apma.setDiffuseColor(1.0f,0f,0f);
            apma.setAmbientColor(0.5f,0f,0f);
            ap.setMaterial(apma);

	    c=new Cylinder(0.05f,r+0.01f,ap);
	    TransformGroup tg=new TransformGroup();
	    Transform3D ts0=new Transform3D();
	    ts0.setTranslation(new Vector3f(0.5f,0.5f*r-0.5f,0.5f));
	    tg.setTransform(ts0);
	    tg.addChild(c);
	    addChild(tg);
	}
    }

    class LightCone extends BranchGroup {
	Cone c;
	LightCone(float r) {
	    setCapability(BranchGroup.ALLOW_DETACH);
	    TransparencyAttributes tr=new TransparencyAttributes(TransparencyAttributes.NICEST,0.6f);
	    Appearance ap = new Appearance();
            Material apma = new Material();
            apma.setDiffuseColor(1.0f,1.0f,0.0f);
            apma.setAmbientColor(0.5f,0.5f,0.0f);
            ap.setMaterial(apma);
	    ap.setTransparencyAttributes(tr);

	    c=new Cone(r,r,ap);
	    TransformGroup tg=new TransformGroup();
	    Transform3D ts0=new Transform3D();
	    ts0.rotZ(Math.PI);
	    ts0.setTranslation(new Vector3f(0f,0.5f*r-0.5f,0f));
	    tg.setTransform(ts0);
	    tg.addChild(c);
	    addChild(tg);
	}
	

    }


    class Earth extends BranchGroup {
	Earth() {
	    setCapability(BranchGroup.ALLOW_DETACH);
	    setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
	    setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);

	    scene.addChild(this);
	}
	void addOne(double y,double h)
	{ 
	    Appearance ap = new Appearance();
            Material apma = new Material();
            apma.setDiffuseColor(0f,1f,0f);
            apma.setAmbientColor(0f,0.5f,0f);
            ap.setMaterial(apma);

	    Cylinder c=new Cylinder(0.025f,(float)h,ap);
	    TransformGroup tg=new TransformGroup();
	    Transform3D ts0=new Transform3D();
	    ts0.setTranslation(new Vector3f(
					    0.5f+(float)(0.2*Math.cos(7.0*t)),
					    (float)y-0.5f,
					    0.5f+(float)(0.2*Math.sin(7.0*t))
					    ));
	    tg.setTransform(ts0);
	    tg.addChild(c);
	    BranchGroup bg=new BranchGroup();
	    bg.addChild(tg);
	    addChild(bg);
	}
    }

    LightCone lightcone;
    Standing standing;
    Earth earth;
    Shape3D xyPlane;
    Shape3D tPlane;
    Transform3D tPlaneTS;
    TransformGroup tg;

    JCheckBox cbS,cbE;

    void writeCanvas(Graphics g){
	lightcone.detach();
	lightcone = new LightCone((float)t);
	scene.addChild(lightcone);

	if( cbS.isSelected() ) {
	    standing.detach();
	    standing = new Standing((float)t);
	    scene.addChild(standing);
	}
	if( cbE.isSelected() ) {
	    earth.addOne(t,stepT);
	}



	tPlaneTS.setTranslation(new Vector3f(0,(float)t,0));
	tg.setTransform(tPlaneTS);
       	canvas.startRenderer();

	int w=canvas2.getWidth();
	int h=canvas2.getHeight();

	int r=(int)(t*w*0.5);
	g.setColor(Color.GRAY);
	g.fillRect(0,0,w,h);

	g.setColor(Color.YELLOW);
	g.drawOval(w/2-r,h/2-r,2*r,2*r);

	int rr=(int)(w*0.05);
	if( cbS.isSelected() ) {
	    g.setColor(Color.RED);
	    g.fillOval(3*w/4-rr,3*h/4-rr,2*rr,2*rr);
	}
	rr=(int)(w*0.025);
	int rrr=(int)(w*0.2);
	if( cbE.isSelected() ) {
	    g.setColor(Color.GREEN);
	    g.fillOval(3*w/4+(int)(rrr*Math.cos(7.0*t))-rr,3*h/4+(int)(rrr*Math.sin(7.0*t))-rr,2*rr,2*rr);
	}

	if(r > 3*w/5 ) {
	    t=0;
	    if( cbE.isSelected() ) {
		earth.detach();
		earth=new Earth();
	    }
	}
    }
}
	
   
