import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.applet.MainFrame;
import java.util.*;

public class Prismatic extends Applet implements ActionListener, AdjustmentListener {

   String host;                    // Host from which this applet came from
   int width, height;              // Size of the graphics window in pixels
   Canvas3D canvas3D;              // 3D rendering canvas
   Panel b_container;              // Container to hold the buttons
   Panel c_container;              // Container to hold the canvas
   Panel z_container;              // Container to hold the zoom
   Button update_button;           // Update button
   static boolean appletFlag = true;      // Applet flag
   String textString;              // Storage area for introduction

    private SimpleUniverse universe = null;
    int zoom;
    TextField nNum, hNum, vNum, HNum, nInput, superText;
    BranchGroup scene3D;
    Scrollbar HSlider, ZoomSlider;
    int n, h, v;
    double H;
    
    Label zoomLabel, resultLabel, plusLabel, paraLabel, superLabel;

   /**
    * Initialization
    */
   public void init() {

      // Set the graphics window size.
      width  = 350;
      height = 350;          
      zoom = 50;
      n = 5;
      h = 1;
      v = 1;
      H = 1;

      // Create the "base" color for the AWT components.
      setBackground(new Color(200, 200, 200));

      // Create a 3D graphics canvas.
      canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
      canvas3D.setSize(width, height);
      canvas3D.setLocation(5, 5);

      // Create the branch group                 
      createScene3D();

      // Create a universe with the Java3D universe utility.
      universe = new SimpleUniverse(canvas3D);
      universe.addBranchGraph(scene3D);
  
      // Use parallel projection.
      View view = universe.getViewer().getView();
      view.setProjectionPolicy(View.PARALLEL_PROJECTION);

      // Set the universe Transform3D object.
      TransformGroup tg = 
         universe.getViewingPlatform().getViewPlatformTransform();
      Transform3D transform = new Transform3D();
      transform.set(65.f, new Vector3f(0.0f, 0.0f, 400.0f));
      tg.setTransform(transform);

      // Create the canvas container.
      c_container = new Panel();
      c_container.setSize(360, 360);
      c_container.setLocation(0, 0);
      c_container.setVisible(true);
      c_container.setLayout(null);
      add(c_container);

      // Add the 2D and 3D canvases to the container.
      c_container.add(canvas3D);

      // Turn off the layout manager, widgets will be sized 
      // and positioned explicitly.
      setLayout(null);

      b_container = new Panel();
      b_container.setSize(290, 360);
      b_container.setLocation(360, 0);
      b_container.setVisible(true);
      b_container.setLayout(null);
      
	  paraLabel = new Label(" Parameters:");
	  paraLabel.setSize(80,20);
	  paraLabel.setLocation(10,10);
	  paraLabel.setBackground(Color.red);
	  paraLabel.setVisible(true);
	  b_container.add(paraLabel);

      nNum = new TextField("5",20);
      nNum.setBackground(Color.white);
      Panel nPanel = new Panel();
      nPanel.setLayout(new BorderLayout(2,2));
      nPanel.setSize(70,20);
      nPanel.setLocation(20,50);
      nPanel.add( new Label(" n ="), BorderLayout.WEST );
      nPanel.add(nNum, BorderLayout.CENTER);
      nPanel.setVisible(true);
      b_container.add(nPanel);      
      
      hNum = new TextField("1",20);
      hNum.setBackground(Color.white);
      Panel hPanel = new Panel();
      hPanel.setLayout(new BorderLayout(2,2));
      hPanel.setSize(70,20);
      hPanel.setLocation(120,50);
      hPanel.add( new Label(" h ="), BorderLayout.WEST );
      hPanel.add(hNum, BorderLayout.CENTER);
      hPanel.setVisible(true);
      b_container.add(hPanel);     
      
      vNum = new TextField("1",20);
      vNum.setBackground(Color.white);
      Panel vPanel = new Panel();
      vPanel.setLayout(new BorderLayout(2,2));
      vPanel.setSize(70,20);
      vPanel.setLocation(220,50);
      vPanel.add( new Label(" v ="), BorderLayout.WEST );
      vPanel.add(vNum, BorderLayout.CENTER);
      vPanel.setVisible(true);
      b_container.add(vPanel);
	  
      HNum = new TextField("1",20);
      HNum.setBackground(Color.white);
      Panel HPanel = new Panel();
      HPanel.setLayout(new BorderLayout(2,2));
      HPanel.setSize(180,20);
      HPanel.setLocation(20,80);
      HPanel.add( new Label(" Height / Radius Ratio ="), BorderLayout.WEST );
      HPanel.add(HNum, BorderLayout.CENTER);
      HPanel.setVisible(true);
      b_container.add(HPanel);
	  	  
//public Scrollbar(int orientation, int value, int visible, int min, int max)
	  HSlider  = new Scrollbar(Scrollbar.HORIZONTAL, 10, 10, 0, 100);
	  HSlider.setUnitIncrement(2);	 
	  HSlider.setPageIncrement(10);	 
	  HSlider.addAdjustmentListener(this);
	  HSlider.setSize(200, 20);
	  HSlider.setLocation(20, 110);
	  b_container.add(HSlider);
	  
      update_button = new Button("Update");
      update_button.setSize(100, 20);
      update_button.setLocation(200, 140);
      update_button.setVisible(true);
      update_button.addActionListener(this);
      b_container.add(update_button);      
      
	  resultLabel = new Label(" Results:");
	  resultLabel.setSize(80,20);
	  resultLabel.setLocation(10,180);
	  resultLabel.setBackground(Color.red);
	  resultLabel.setVisible(true);
	  b_container.add(resultLabel);
	  
	  superLabel = new Label(" Super Stable?");
	  superLabel.setSize(100, 20);
	  superLabel.setLocation(20,210);
	  superLabel.setVisible(true);
	  b_container.add(superLabel);	  
	  
      superText = new TextField("Yes",20);
	  superText.setSize(50, 20);
	  superText.setLocation(150,210);
      superText.setBackground(Color.white);
      superText.setEditable(false);
      superText.setVisible(true);
      b_container.add(superText);
      
      add(b_container);      
      
      z_container = new Panel();
      z_container.setSize(360, 40);
      z_container.setLocation(0, 370);
      z_container.setVisible(true);
      z_container.setLayout(null);
      
      ZoomSlider  = new Scrollbar(Scrollbar.HORIZONTAL, 50, 10, 0, 100);
	  ZoomSlider.setUnitIncrement(2);	 
	  ZoomSlider.setPageIncrement(10);	 
	  ZoomSlider.addAdjustmentListener(this);
	  ZoomSlider.setSize(200, 20);
	  ZoomSlider.setLocation(80, 10);
	  ZoomSlider.setVisible(true);
	  z_container.add(ZoomSlider);
	  
	  zoomLabel = new Label(" Zoom Out");
	  zoomLabel.setSize(80, 20);
	  zoomLabel.setLocation(10,10);
	  zoomLabel.setVisible(true);
	  z_container.add(zoomLabel);
	  	  
	  	  
	  plusLabel = new Label(" Zoom In");
	  plusLabel.setSize(80, 20);
	  plusLabel.setLocation(280,10);
	  plusLabel.setVisible(true);
	  z_container.add(plusLabel);
	  	  
	  add(z_container);
      
   }

    public void destroy() {
	universe.cleanup();
    }

   /**
    *  Create the scenegraph for the 3D view.
    */
//   public BranchGroup createScene3D() {
   public void createScene3D() {

      // Define colors
      Color3f white = new Color3f(1.0f, 1.0f, 1.0f);
      Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
      Color3f red   = new Color3f(0.80f, 0.20f, 0.2f);
      Color3f ambient = new Color3f(0.25f, 0.25f, 0.25f);
      Color3f diffuse = new Color3f(0.7f, 0.7f, 0.7f);
      Color3f specular = new Color3f(0.9f, 0.9f, 0.9f);
      Color3f ambientRed = new Color3f(0.2f, 0.05f, 0.0f);
      Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);

      scene3D = new BranchGroup();
      scene3D.setCapability(BranchGroup.ALLOW_DETACH );
      // Create the bounding leaf node
      BoundingSphere bounds =
         new BoundingSphere(new Point3d(0.0,0.0,0.0), 1000.0);
      BoundingLeaf boundingLeaf = new BoundingLeaf(bounds);
      scene3D.addChild(boundingLeaf);

      // Create the background
      Background bg = new Background(bgColor);
      bg.setApplicationBounds(bounds);
      scene3D.addChild(bg);

      // Create the ambient light
      AmbientLight ambLight = new AmbientLight(white);
      ambLight.setInfluencingBounds(bounds);
      scene3D.addChild(ambLight);

      // Create the directional light
      Vector3f dir = new Vector3f(-1.0f, -1.0f, -1.0f);
      DirectionalLight dirLight = new DirectionalLight(white, dir);
      dirLight.setInfluencingBounds(bounds);
      scene3D.addChild(dirLight);

      // Create the transform group node
      TransformGroup transformGroup = new TransformGroup();
      transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
      transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
      scene3D.addChild(transformGroup);
      
      // Create the poles
      PrismaticPoles poles = new PrismaticPoles(zoom, n, h, v, H);
      transformGroup.addChild(poles.getChild());

      PickDragBehavior behavior = new PickDragBehavior(canvas3D, 
                                                       scene3D, transformGroup);
      behavior.setSchedulingBounds(bounds);
      transformGroup.addChild(behavior);

   }

  public void adjustmentValueChanged(AdjustmentEvent e){
     
    H = (double)HSlider.getValue()/10;
    zoom = (int)ZoomSlider.getValue();
    HNum.setText(String.valueOf(H));
    scene3D.detach();
    createScene3D();
    universe.addBranchGraph(scene3D);
    canvas3D.repaint();
    
  }
  
   public void actionPerformed (ActionEvent event) {

      Object target = event.getSource();

      // Process the button events.
      if (target == update_button) {
         n = (int)Double.valueOf(nNum.getText()).doubleValue();
         h = (int)Double.valueOf(hNum.getText()).doubleValue();
         v = (int)Double.valueOf(vNum.getText()).doubleValue();
         H = (double)Double.valueOf(HNum.getText()).doubleValue();
         HSlider.setValue((int)(H*10));
         scene3D.detach();
         createScene3D();
      	 universe.addBranchGraph(scene3D);
         canvas3D.repaint();
         
         if (h == 1){
         	superText.setText("Yes");
         }
         else {
         	superText.setText("No");
         }
      }

   }
   
      public void mousePressed(MouseEvent evt) {
          b_container.requestFocus();
       }
       

   public void start() {
      if (appletFlag) showStatus("Symmetric Prismatic Tensegrity Structures");
   }


   /**
    *  Inner class used to "kill" the window when running as
    *  an application.
    */
   static class killAdapter extends WindowAdapter {
      public void windowClosing(WindowEvent event) {
         System.exit(0);
      }
   }

  /**
   *  Main method, only used when running as an application.
   */
  public static void main(String[] args) {
    Prismatic.appletFlag = false;
    new MainFrame(new Prismatic(), 730, 600);
  }
  
}

