/*
 * CapturingPicture.java
 *
 * Created on 8 januari 2001, 9:25
 */
import java.net.URL;
import javax.swing.*;
import javax.media.j3d.*;
import com.sun.j3d.loaders.vrml97.*;
import java.awt.*;
import java.applet.*;
import com.sun.j3d.utils.geometry.ColorCube;
import javax.vecmath.*;
/** This class is a subclass of JFrame and holds a CapturingCanvas3D.  It
 * is used to save PART vrml files to a JPEG format so that they can be shown in
 * sets.  Each VRMl File is rotated 45 degrees around the X and Y axiss
 */
public class CapturingPicture extends JFrame{
    /** This URL holds the location of the VRML file
     */
    private URL url;
    /** VrmlScene is used by the VRMLLoader and holds the entire VRML file
     */
    private VrmlScene vrmlScene;
    /** This BranchGroup holds a Java3d tree representing the VRML file
     */
    private BranchGroup sceneGroup;
    /** This BranchGroup holds the content of the VRML file
     */
    private BranchGroup scene;
    /** This is a AWT component that captures the VRML file into a JPEG
     */
    private CapturingCanvas3D cCanvas;
    /** This is the universe where the part we be loaded.  It holds all
     * Java3D dependend objects
     */
    private VirtualUniverse universe;
    /** The Locale is attached to the Virtual universe and holds only BranchGroups
     */
    private Locale locale;
    /** vpRoot holds all vieuwing dependend objects
     */
    private BranchGroup vpRoot;
    /** this TransformGroup is responsible for the location of the View
     */
    private TransformGroup viewTransformGroup;
    /** The view holds information on how the object is seen
     */
    private View view;
    /** The viewplatform is a representation of the Camera.  This object is usually
     * transformed by a TransformGroup
     */
    private ViewPlatform viewPlatform;
    /** This object holds information on the Viewing Output
     */
    private PhysicalBody body;
    /** This object holds information on the Viewing Output
     */
    private PhysicalEnvironment environment;
    /** This transform3d is responsible for the rotation, location and size of the
     * of the viewplatform
     */
    private Transform3D viewTransform;
    /** These BranchGroup holds all content dependend objects
     */
    private BranchGroup sceneRoot;
    /** This is an AmbientLight usesd to light up the scene
     */
    private AmbientLight ambLight;
    /** This is a light, attached to the viewTransformGroup in order to give the visible
     * objects extra light
     */
    private DirectionalLight headLight;
    
    /** This method does the actual capturing of the scene.
     * @param URL This URL holds the location of the VRML Scene
     * @param file This String holds the name of the destination file
     * @param directory This String holds the destination directory
     */
    public CapturingPicture(String URL, String file, String directory){
            
       this.getContentPane().setLayout(new BorderLayout());
        	
        // Create a Canvas3D object
        cCanvas = new CapturingCanvas3D(null,file,directory);
        cCanvas.writeJPEG_ = true;
        cCanvas.repaint();
        this.getContentPane().add(cCanvas);
        
        // Create a Virtual Universe object
        universe = new VirtualUniverse();

        // Create a Locale object and connect it to the universe object
        locale = new Locale(universe);

        //=================================================================
        // Create a view branch graph
        // Create a BranchGroup note for the view platform
        vpRoot = new BranchGroup();
        SetCapability.settingCap(this.vpRoot, SetCapability.CAPTPICTURE_vpROOT_CAPABILITY);        
        
        BranchGroup temp = new BranchGroup();
        SetCapability.settingCap(temp, SetCapability.CAPTPICTURE_TEMP_CAPABILITY);        

        temp = this.createSceneGraph(URL);
        
        Transform3D tempRotate = new Transform3D();
        Transform3D rotate = new Transform3D();

        rotate.rotX(Math.PI/4.0d);
        tempRotate.rotY(Math.PI/4.0d);
        rotate.mul(tempRotate);
        TransformGroup objRotate = new TransformGroup(rotate);
        objRotate.addChild(temp);
        vpRoot.addChild(objRotate);
        view = new View();
                
        // Create a TransformGroup object.
        viewTransform = new Transform3D();
        BoundingSphere bound= new BoundingSphere(temp.getBounds());
        double radius = bound.getRadius();
        double eyeDist = (1.3999999999999999D * radius )/ Math.tan(view.getFieldOfView() / 2D);
        viewTransform.set(new Vector3f(0.0f , 0.0f, (float) eyeDist ));
        view.setBackClipDistance(eyeDist + 3 * radius);
        //viewTransform.set(new Vector3f(0.0f, 0.0f, 3.0f));
        viewTransformGroup = new TransformGroup(viewTransform);
        SetCapability.settingCap(this.viewTransformGroup, SetCapability.CAPTPICTURE_VIEWTG_CAPABILITY);
        
        // Create a View object        

        // Create a ViewPlatform object
        viewPlatform = new ViewPlatform();        

        // Create a PhysicalBody object
        body = new PhysicalBody();

        // Create a PhysicalEnvironment object
        environment = new PhysicalEnvironment();

        // Attach the ViewPlatform, PhysicalBody, PhysicalEnvironment,
        // and Canvas3D objects to the View object
        view.setPhysicalBody(body);
        view.setPhysicalEnvironment(environment);
        view.attachViewPlatform(viewPlatform);
        view.addCanvas3D(cCanvas);

        // Attach the ViewPlatform object to the TransformGroup object
        viewTransformGroup.addChild(viewPlatform);

        // Attach the viewTransformGroup to the BranchGroup vpRoot
        vpRoot.addChild(viewTransformGroup);
       
        sceneRoot = new BranchGroup();
        SetCapability.settingCap(this.sceneRoot, SetCapability.CAPTPICTURE_SCENEROOT_CAPABILITY);
        
        // maken van een ambientLight
        BoundingSphere lightBounds = new BoundingSphere(new Point3d(), Double.MAX_VALUE);
        ambLight = new AmbientLight(true, new Color3f(1.0f, 1.0f, 1.0f));
        ambLight.setInfluencingBounds(lightBounds);
        SetCapability.settingCap(this.ambLight, SetCapability.CAPTPICTURE_AMBLIGHT_CAPABILITY);        
        sceneRoot.addChild(ambLight);

        // maken van een DirectionalLight
        headLight = new DirectionalLight();
        SetCapability.settingCap(this.headLight, SetCapability.CAPTPICTURE_HEADLIGHT_CAPABILITY);
        
        headLight.setInfluencingBounds(lightBounds);
        sceneRoot.addChild(headLight);
        sceneRoot.addChild(this.scene);

        locale.addBranchGraph(vpRoot);  
        locale.addBranchGraph(sceneRoot);

        this.setSize(200,200);
        this.show();
    }
    
    
    /** This method loads the VRML file and returns its BranchGroup
     * @param URL The location of the VRML file
     * @return The VRML BranchGroup (rudementary)
     */
    public BranchGroup createSceneGraph(String URL){
        try{
            url = new URL( URL );
            VrmlLoader loader = new VrmlLoader();
            vrmlScene = ( VrmlScene ) loader.load( url );
            sceneGroup = vrmlScene.getSceneGroup();
        }catch( java.io.IOException e )
        {
            System.err.println( "IO exception reading URL" );
        }catch( vrml.InvalidVRMLSyntaxException e )
        {
            System.err.println( "VRML parse error" );
            e.printStackTrace( System.err );
        }catch(Exception e)
        {
            e.printStackTrace(System.err);
        }
        return sceneGroup;
    }    
    
    /** Used to make this class operate stand-alone
     * @param args not used
     */
    public static void main (String args[]) {
        String test = new String("http://w2000-jurgenv/sets/kegel.wrl");
        CapturingPicture cPicture = new CapturingPicture(test,"kegel","c:\\Inetpub\\wwwroot\\sets\\");
        cPicture.setSize(200,200);
        cPicture.show();
    }
}