/*
 * Created on Nov 3, 2005
 *
 * TODO To change the template for this generated file go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
package de.tuberlin.polymake.common;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.io.IOException;
import java.util.Properties;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import de.jreality.scene.SceneGraphComponent;
import de.jreality.scene.SceneGraphNode;
import de.jreality.scene.Viewer;
import de.jreality.ui.viewerapp.ViewerApp;
import de.jreality.vr.AppearancePluginVR;
import de.jreality.vr.ToolPluginVR;
import de.jreality.vr.ViewerVR;

/**
 * @author wotzlaw
 *
 * TODO To change the template for this generated type comment go to
 * Window - Preferences - Java - Code Style - Code Templates
 */
public class JRealityFrame extends JFrame implements ChangeListener, WindowListener{
	
	/** Help frame explaining jreality controls **/
	protected static JRealityHelpFrame helpFrame = null;
	
	protected JButton helpButton;
	
	/** Contains parameters for display */
	protected Properties parameters;
	
	/** Contains interactive parameters for display */
	protected Properties iparameters;
	
	/** The complete scenegraph used for display **/ 
	protected JRealityScene scene;
	
	/** The viewer of the scenegraph **/
	protected Viewer viewer;
	
	protected ViewerVR viewerVR; 
	
	/** Panel for geometry explosion **/
	protected JRealitySpinner explode;
	
	//TODO: transparency does not work on hardware renderer
	///** Panel for geometry transparency **/
	//protected JRealitySpinner transparency;
	
	protected JRealityControl parent;
	
	protected Box box = new Box(BoxLayout.Y_AXIS);
	protected Box northBox = new Box(BoxLayout.X_AXIS);
	protected Box southBox = new Box(BoxLayout.X_AXIS);
	protected boolean isFullScreen = false;
	
	protected String title;

	protected SceneGraphNode geom;
	
	public JRealityFrame(SceneGraphComponent geom, 
						String title,
						Properties params, 
						Properties iparams, 
						final JRealityControl parent) {
		
		this.parent = parent;
		this.title = title;
		this.geom = geom;
		scene = new JRealityScene(geom);
		
			try {
				viewerVR = new ViewerVR();
				viewerVR.addAlignTab();
				viewerVR.addTerrainTab();
				viewerVR.addEnvTab();
				viewerVR.setGeneratePickTrees(true);
				
				// configure the viewerVR
				AppearancePluginVR appPlugin = new AppearancePluginVR();
				ToolPluginVR toolPlugin = new ToolPluginVR();
				
				viewerVR.registerPlugin(appPlugin);
				viewerVR.registerPlugin(toolPlugin);
								
				ViewerApp va = viewerVR.initialize();
				
				// overwrite restored preferences:
				appPlugin.setShowLines(true);
				appPlugin.setPointRadius(0.8);
				appPlugin.setShowPoints(true);
				appPlugin.setTubeRadius(0.6);
				appPlugin.setFaceReflection(0.2);
				toolPlugin.setRotationEnabled(true);
				toolPlugin.setDragEnabled(true);
				
				viewerVR.setContent(scene);
				viewerVR.setContentSize(10);
				viewerVR.setContentOffset(1);

				viewer = va.getViewer();
				if(System.getProperty("polymake.debug") != null) {
					va.setAttachNavigator(true);
					va.setAttachBeanShell(true);	
				}
				
				
				va.update();
				Component viewingComponent = va.getComponent();
				this.getContentPane().add(viewingComponent,BorderLayout.CENTER);
				
				box.add(southBox);
				
				this.setJMenuBar(va.getMenu().getMenuBar());
				super.setName(geom.getName());
				this.setTitle(title);
				this.setSize(800, 600);

				this.addWindowListener(this);

				helpButton = new JButton("Help");
				helpButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						if (helpFrame == null)
							helpFrame = new JRealityHelpFrame();
						if (!helpFrame.isVisible()
								|| helpFrame.getState() == Frame.ICONIFIED)
							helpFrame.setLocation(getX() + 20, getY() + 20);
						helpFrame.setState(Frame.NORMAL);
						helpFrame.setVisible(true);
					}
				});

				southBox.setPreferredSize(new Dimension(1000,20));

				
				explode = new JRealitySpinner("explode",0.0, 0.0, 10.0, 0.1);
				explode.setPreferredSize(new Dimension(150,20));
				explode.addChangeListener(this);	
						
				//TODO: explodable as property of poly object
				if(geom.getChildComponentCount() <= 1) {
					explode.setVisible(false);
				}
				southBox.add(explode.getComponent());
				southBox.add(Box.createHorizontalGlue());
				southBox.add(helpButton);

				helpButton.setAlignmentY(Component.CENTER_ALIGNMENT);
				helpButton.setMinimumSize(new Dimension(20, 20));
				helpButton.setPreferredSize(new Dimension(70, 20));

				this.getContentPane().add(box,BorderLayout.SOUTH);
				this.validate();
				this.setVisible(true);
			} catch (Exception e) {
				// TODO: handle exception
			}
	}
	
	void toggleFullScreen() {
		isFullScreen = !isFullScreen;
		if(isFullScreen) {
			this.dispose();
			this.setUndecorated(true);
		}
		if (isFullScreen) {
			box.remove(northBox);
			box.remove(southBox);
			this.setJMenuBar(null);
		} else {
			box.add(northBox, 0);
			box.add(southBox);
		}
		
		this.getGraphicsConfiguration().getDevice().setFullScreenWindow
		(isFullScreen ? this : null);
		if(!isFullScreen) {
			this.dispose();
			this.setUndecorated(false);
		}
		this.validate();
		//try { Thread.sleep(500); } catch (Exception e) { }
		this.setVisible(true);
	}
	
	public void stateChanged(ChangeEvent e) {
		Object source = e.getSource();	
		if(source == explode) {
			double val = ((Double)explode.getValue()).doubleValue();
			scene.explodeGeometry(val);
		}
		
//		if(source == transparency) {
//			double val = ((Double)transparency.getValue()).doubleValue();
//			parent.setTransparency(getName(), val);
//		}
		
	}

	public void windowActivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowClosing(WindowEvent e) {
		e.getWindow().dispose();
	}

	public void windowClosed(WindowEvent e) {
		try {
			parent.removeFrame(title);
			parent.putMessage(SimpleGeometryParser.write(geom.getName(),"close",1.),false);
			parent.removeFrame(getName());
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}

	public void windowDeactivated(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowDeiconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowIconified(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}

	public void windowOpened(WindowEvent arg0) {
		// TODO Auto-generated method stub
		
	}
}


syntax highlighted by Code2HTML, v. 0.9.1