// This is a parent for the GLCanvas, and contains the rendering thread, the drawing
// code, etc.

package JoglTestApp;

import java.awt.*;
import java.awt.event.*;
import net.java.games.jogl.*;

public class JoglPanel extends Panel implements  MouseMotionListener {
    
    private JoglObj _joglObj;      // Interface to Jogl.
    RenderThread _renderThread;    // This thread will actually make OpenGL calls.
    
    private float _x, _y;
    
    public JoglPanel() {
        setLayout(new BorderLayout());
        _renderThread = new RenderThread();
        _renderThread.setName("RenderThread");
        _renderThread.start();        
    }
    
    
    public void mouseMoved(MouseEvent e) {}

    // Some interaction to cause rendering.
    public void mouseDragged(MouseEvent e) {
        _x = 2.0f * (float) e.getX() / (float) getWidth() - 1.0f;
        _y = -(2.0f * (float) e.getY() / (float) getHeight() - 1.0f);
        repaint();
    }

    public void repaint() {
        // Tell the GLCanvas to repaint.
        _joglObj.getCanvas().repaint();
    }

    public void setJoglObj(JoglObj joglObj) {
        _joglObj = joglObj;
        _joglObj.getCanvas().addMouseMotionListener(this);
    }
    
    public void startPicture() {
        // To render on the AWT thread, call joglCallback() instead of startRender().
        //_renderThread.joglCallback();
        _renderThread.startRender();
    }
    
    //  This thread does the rendering.
    public class RenderThread extends Thread implements JoglObj.JoglCallback {
        boolean _renderLatch = false;
        
        public RenderThread() {
        }
        
        // JoglObj will call this from AWT thread to tell the thread to get going.
        public synchronized void startRender() {
            _renderLatch = true;
            notifyAll();
        }
        
        // JoglObj will call this from this tread to render.
        public void joglCallback() {
            // Do OpenGL stuff.
            GL gl = _joglObj.getGL();
            
            gl.glClearColor(0.f,0.5f,1.f,1.f);
            gl.glClear(GL.GL_COLOR_BUFFER_BIT);
            
            gl.glPushMatrix();
            gl.glOrtho(-1.f,1.f,-1.f,1.f,-1.f,1.f);
            
            gl.glColor3f(1.0f, 1.0f, 0.0f);
            gl.glBegin(GL.GL_TRIANGLES);
            gl.glVertex3f(_x + -0.5f, _y + -0.5f, 0.0f);
            gl.glVertex3f(_x +  0.5f, _y + -0.5f, 0.0f);
            gl.glVertex3f(_x +  0.0f, _y +  0.5f, 0.0f);
            gl.glEnd();
            
            gl.glPopMatrix();
        }
        
        // Get it going.        
        public void run() {
            loop();
        }

        // The displatch loop, running in this thread.
        private synchronized void loop() {
            while (true) {
                if (_renderLatch) {
                    _renderLatch = false;

                    // Here's where we'll ask for a rendering in this thread.
                    _joglObj.renderJogl(this);
                }
                else {
                    notifyAll();
                    try {
                        wait();
                    }
                    catch (InterruptedException ex) {
                    }
                }
            }
        }
    }
}

