package test;

import java.io.PrintStream;

import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.SwingUtilities;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;

import com.jogamp.newt.awt.NewtCanvasAWT;
import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
import com.jogamp.test.junit.jogl.demos.gl2.gears.Gears;

public class JDesktopDemo {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                JFrame frame = new JFrame("JDesktop Demo");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JDesktopPane desktop = new JDesktopPane();
                frame.setContentPane(desktop);

                Animator animator = new Animator();
                for (int i = 0; i < 2; ++i) {
                    JInternalFrame subFrame = new JInternalFrame(Integer
                            .toString(i));
                    subFrame.setResizable(true);
                    subFrame.setIconifiable(true);
                    subFrame.setClosable(true);
                    subFrame.setDefaultCloseOperation(JInternalFrame.DISPOSE_ON_CLOSE);
                    subFrame.setLocation(i * 90, i * 30);
                    desktop.add(subFrame);

                    GLCapabilities caps = new GLCapabilities(GLProfile.getDefault());
                    caps.setHardwareAccelerated(true);
                    caps.setDoubleBuffered(true);

                    final GLWindow glWindow = GLWindow.create(caps);
                    glWindow.addGLEventListener(new TraceGLEventListener(
                            "--- Canvas" + i, System.out));
                    glWindow.addGLEventListener(new Gears());
                    
                    // TODO Should this be necessary?
                    subFrame.addInternalFrameListener(new InternalFrameAdapter() {
                        
                        @Override
                        public void internalFrameClosing(InternalFrameEvent e) {
                            glWindow.destroy();
                        }
                        
                    });

                    NewtCanvasAWT canvas = new NewtCanvasAWT(glWindow);
                    canvas.setSize(640, 480);
                    subFrame.getContentPane().add(canvas);
                    subFrame.pack();
                    subFrame.setVisible(true);
                    
                    animator.add(glWindow);
                }
                animator.start();

                frame.pack();
                frame.setSize(800, 600);
                frame.setVisible(true);
            }

        });
    }

    public static class TraceGLEventListener implements GLEventListener {

        public final String name;

        public final PrintStream out;
        
        public final boolean debugDisplay;

        public TraceGLEventListener(final String name, PrintStream out) {
            this(name, out, false);
        }

        public TraceGLEventListener(final String name, PrintStream out, boolean debugDisplay) {
            this.name = name;
            this.out = out;
            this.debugDisplay = debugDisplay;
        }

        @Override
        public void init(GLAutoDrawable drawable) {
            out.println(name + ".init ");
        }

        @Override
        public void reshape(GLAutoDrawable drawable, int x, int y, int width,
                int height) {
            out.println(name + ".reshape " + x + ", " + y + ", "
                    + width + " x " + height);
        }

        @Override
        public void display(GLAutoDrawable drawable) {
            if (debugDisplay)
                out.println(name + ".display on "
                        + Thread.currentThread());
        }

        @Override
        public void dispose(GLAutoDrawable drawable) {
            out.println(name + ".dispose");
        }

    }

}
