/**
 * 
 */

import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;

import java.awt.Color;
import java.io.IOException;

import javax.media.nativewindow.AbstractGraphicsDevice;
import javax.media.nativewindow.NativeWindow;
import javax.media.opengl.GL;
import javax.media.opengl.GL2;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLCapabilities;
import javax.media.opengl.GLCapabilitiesImmutable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.GLProfile;

import com.jogamp.newt.opengl.GLWindow;
import com.jogamp.opengl.util.Animator;
import com.jogamp.opengl.test.junit.util.UITestCase;

/**
 * @author Michael
 *
 */
public class JOGLWindowParentingTest extends UITestCase {
	static GLProfile glp;
    static int width, height;
    static boolean opaque;

    @BeforeClass
    public static void initClass() {
        width  = 300;
        height = 300;
        glp = GLProfile.getDefault();
        opaque = false;
    }
    
    static GLWindow createParentWindow(GLCapabilitiesImmutable caps)
            throws InterruptedException
        {
            Assert.assertNotNull(caps);
            //
            // Create native windowing resources .. X11/Win/OSX
            // 
            GLWindow glWindow;
            glWindow = GLWindow.create(caps);
            Assert.assertNotNull(glWindow);
            
            glWindow.setTitle("NEWT Parenting Window Test");
            
            glWindow.addGLEventListener(new JOGLRectListener(75,75,125,125,Color.RED));

            glWindow.setSize(width, height);
            glWindow.setVisible(true);
            Assert.assertEquals(true,glWindow.isVisible());
            Assert.assertEquals(true,glWindow.isNativeValid());
            
            Animator animator = new Animator(glWindow);
            animator.start();

            return glWindow;
        }
    
    static GLWindow createNestedWindow(NativeWindow nativeParentWindow, GLCapabilitiesImmutable caps)
    		throws InterruptedException {
    	 
    	Assert.assertNotNull(nativeParentWindow);
    	Assert.assertNotNull(caps);
         //
         // Create native windowing resources .. X11/Win/OSX
         // 
         GLWindow glWindow;
         glWindow = GLWindow.create(nativeParentWindow, caps);
         Assert.assertNotNull(glWindow);
         
         glWindow.setTitle("NEWT Parenting Window Test");
         
         glWindow.addGLEventListener(new JOGLRectListener(25,25,125,125,Color.BLUE));

         glWindow.setSize(width, height);
         glWindow.setVisible(true);
         Assert.assertEquals(true,glWindow.isVisible());
         Assert.assertEquals(true,glWindow.isNativeValid());
         
         Animator animator = new Animator(glWindow);
         animator.start();

         return glWindow;
    }
    
    static void destroyWindow(GLWindow glWindow) {
        if(null!=glWindow) {
            glWindow.destroy();
            Assert.assertEquals(false,glWindow.isNativeValid());
        }
    }
    
    @Test
    public void testWindow00() throws InterruptedException {
        GLCapabilities caps = new GLCapabilities(glp);
        Assert.assertNotNull(caps);
        caps.setBackgroundOpaque(opaque);
        GLWindow window1 = createParentWindow(caps);
        Assert.assertEquals(true,window1.isNativeValid());
        Assert.assertEquals(true,window1.isVisible());
        
        GLWindow window2 = createNestedWindow(window1, caps);
        Assert.assertEquals(true,window2.isNativeValid());
        Assert.assertEquals(true,window2.isVisible());
        
        AbstractGraphicsDevice device1 = window1.getScreen().getDisplay().getGraphicsDevice();

        System.err.println("GLProfiles window1: "+device1.getConnection()+": "+GLProfile.glAvailabilityToString(device1));

        Thread.sleep(3000);
        
        //Show resize/transparency bug
        //
        
        window1.setSize(width*2, height*2);
        
        Thread.sleep(5000);
        
        destroyWindow(window2);
        destroyWindow(window1);
    }
    
	public static void main(String[] args) throws IOException {
		String testName = JOGLWindowParentingTest.class.getName();
        org.junit.runner.JUnitCore.main(testName);
	}

	
    private static class JOGLRectListener implements GLEventListener {
    	
    	private int x, y, width, height;
    	private int[] colorArray;
    	
    	public JOGLRectListener(int x, int y, int width, int height, Color c){
    		this.x = x;
    		this.y = y;
    		this.width = width;
    		this.height = height;
    		if(c.equals(Color.RED)){
    			colorArray = new int[] {1, 0, 0, 1};
    		} else if(c.equals(Color.BLUE)){
    			colorArray = new int[] {0, 0, 1, 1};
    		} else{
    			colorArray = new int[] {0, 0, 0, 1};
    		}
    	}
    	
		@Override
		public void init(GLAutoDrawable drawable) {
			GL2 gl = drawable.getGL().getGL2();
			gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			gl.glClearDepth(1.0f);
		}

		@Override
		public void dispose(GLAutoDrawable drawable) {
			
		}

		@Override
		public void display(GLAutoDrawable drawable) {
			GL2 gl = drawable.getGL().getGL2();
			
			gl.glMatrixMode(GL2.GL_PROJECTION);
			
			gl.glLoadIdentity();
			gl.glOrtho(0, 200, 200, 0, 0, 1);
			
			gl.glMatrixMode(GL2.GL_MODELVIEW);
			
			gl.glDisable(GL.GL_DEPTH_TEST);
			gl.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
			gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
			gl.glColor4f(colorArray[0], colorArray[1], colorArray[2], colorArray[3]);
			gl.glRectd(x, y, width+x, height+y);

			gl.glFlush();
		}

		@Override
		public void reshape(GLAutoDrawable drawable, int x, int y, int width,
				int height) {
			
		}
    	
    }
}
