/**
 * @(#) scube.java
 * @(#) author: David G Yu/Mark J. Kilgard/Silicon Graphics (converted to Java by Ron Cemer)
 */

/* Copyright (c) Mark J. Kilgard, 1994. */

/**
 * (c) Copyright 1993, 1994, Silicon Graphics, Inc.
 * ALL RIGHTS RESERVED 
 * Permission to use, copy, modify, and distribute this software for 
 * any purpose and without fee is hereby granted, provided that the above
 * copyright notice appear in all copies and that both the copyright notice
 * and this permission notice appear in supporting documentation, and that 
 * the name of Silicon Graphics, Inc. not be used in advertising
 * or publicity pertaining to distribution of the software without specific,
 * written prior permission. 
 *
 * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
 * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
 * FITNESS FOR A PARTICULAR PURPOSE.  IN NO EVENT SHALL SILICON
 * GRAPHICS, INC.  BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
 * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
 * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
 * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
 * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC.  HAS BEEN
 * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
 * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
 * 
 * US Government Users Restricted Rights 
 * Use, duplication, or disclosure by the Government is subject to
 * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
 * (c)(1)(ii) of the Rights in Technical Data and Computer Software
 * clause at DFARS 252.227-7013 and/or in similar or successor
 * clauses in the FAR or the DOD or NASA FAR Supplement.
 * Unpublished-- rights reserved under the copyright laws of the
 * United States.  Contractor/manufacturer is Silicon Graphics,
 * Inc., 2011 N.  Shoreline Blvd., Mountain View, CA 94039-7311.
 *
 * OpenGL(TM) is a trademark of Silicon Graphics, Inc.
 */

/*
 * 1992 David G Yu -- Silicon Graphics Computer Systems
 */

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.*;
import java.util.*;
import java.io.*;
import java.util.*;
import gl4java.GLContext;
import gl4java.awt.GLAnimCanvas;
import gl4java.applet.SimpleGLAnimApplet1;

public class scube extends SimpleGLAnimApplet1 
{

        /* Initialize the applet */


	public void init()
	{
	super.init();
        Dimension d = getSize();
        canvas = new scubeCanvas(d.width, d.height);
        add("Center", canvas);
	}


        /* Local GLAnimCanvas extension class */


    private class scubeCanvas extends GLAnimCanvas
    	implements KeyListener, MouseListener
    {
        private static final int
            GREY=0,RED=1,GREEN=2,BLUE=3,CYAN=4,MAGENTA=5,YELLOW=6,BLACK=7;

        private float materialColor[][] =
        {
            {0.8f, 0.8f, 0.8f, 1.0f},
            {0.8f, 0.0f, 0.0f, 1.0f},
            {0.0f, 0.8f, 0.0f, 1.0f},
            {0.0f, 0.0f, 0.8f, 1.0f},
            {0.0f, 0.8f, 0.8f, 1.0f},
            {0.8f, 0.0f, 0.8f, 1.0f},
            {0.8f, 0.8f, 0.0f, 1.0f},
            {0.0f, 0.0f, 0.0f, 0.6f},
        };

        private float lightPos[] = {2.0f, 4.0f, 2.0f, 1.0f};
        private float lightAmb[] = {0.2f, 0.2f, 0.2f, 1.0f};
        private float lightDiff[] = {0.8f, 0.8f, 0.8f, 1.0f};
        private float lightSpec[] = {0.4f, 0.4f, 0.4f, 1.0f};

        private float groundPlane[] = {0.0f, 1.0f, 0.0f, 1.499f};
        private float backPlane[] = {0.0f, 0.0f, 1.0f, 0.899f};

        private float fogColor[] = {0.0f, 0.0f, 0.0f, 0.0f};
        private float fogIndex[] = {0.0f};

        private byte shadowPattern[] =
        {
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,  /* 50% Grey */
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55,
            (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0xaa, (byte)0x55, (byte)0x55, (byte)0x55, (byte)0x55
        };

        private byte sgiPattern[] =
        {
            (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff,  /* SGI Logo */
            (byte)0xff, (byte)0xbd, (byte)0xff, (byte)0x83, (byte)0xff, (byte)0x5a, (byte)0xff, (byte)0xef,
            (byte)0xfe, (byte)0xdb, (byte)0x7f, (byte)0xef, (byte)0xfd, (byte)0xdb, (byte)0xbf, (byte)0xef,
            (byte)0xfb, (byte)0xdb, (byte)0xdf, (byte)0xef, (byte)0xf7, (byte)0xdb, (byte)0xef, (byte)0xef,
            (byte)0xfb, (byte)0xdb, (byte)0xdf, (byte)0xef, (byte)0xfd, (byte)0xdb, (byte)0xbf, (byte)0x83,
            (byte)0xce, (byte)0xdb, (byte)0x73, (byte)0xff, (byte)0xb7, (byte)0x5a, (byte)0xed, (byte)0xff,
            (byte)0xbb, (byte)0xdb, (byte)0xdd, (byte)0xc7, (byte)0xbd, (byte)0xdb, (byte)0xbd, (byte)0xbb,
            (byte)0xbe, (byte)0xbd, (byte)0x7d, (byte)0xbb, (byte)0xbf, (byte)0x7e, (byte)0xfd, (byte)0xb3,
            (byte)0xbe, (byte)0xe7, (byte)0x7d, (byte)0xbf, (byte)0xbd, (byte)0xdb, (byte)0xbd, (byte)0xbf,
            (byte)0xbb, (byte)0xbd, (byte)0xdd, (byte)0xbb, (byte)0xb7, (byte)0x7e, (byte)0xed, (byte)0xc7,
            (byte)0xce, (byte)0xdb, (byte)0x73, (byte)0xff, (byte)0xfd, (byte)0xdb, (byte)0xbf, (byte)0xff,
            (byte)0xfb, (byte)0xdb, (byte)0xdf, (byte)0x87, (byte)0xf7, (byte)0xdb, (byte)0xef, (byte)0xfb,
            (byte)0xf7, (byte)0xdb, (byte)0xef, (byte)0xfb, (byte)0xfb, (byte)0xdb, (byte)0xdf, (byte)0xfb,
            (byte)0xfd, (byte)0xdb, (byte)0xbf, (byte)0xc7, (byte)0xfe, (byte)0xdb, (byte)0x7f, (byte)0xbf,
            (byte)0xff, (byte)0x5a, (byte)0xff, (byte)0xbf, (byte)0xff, (byte)0xbd, (byte)0xff, (byte)0xc3,
            (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff, (byte)0xff
        };

        private float cube_vertexes[][][] =
        {
            {
                {-1.0f, -1.0f, -1.0f, 1.0f},
                {-1.0f, -1.0f, 1.0f, 1.0f},
                {-1.0f, 1.0f, 1.0f, 1.0f},
                {-1.0f, 1.0f, -1.0f, 1.0f}
            },
            {
                {1.0f, 1.0f, 1.0f, 1.0f},
                {1.0f, -1.0f, 1.0f, 1.0f},
                {1.0f, -1.0f, -1.0f, 1.0f},
                {1.0f, 1.0f, -1.0f, 1.0f}
            },
            {
                {-1.0f, -1.0f, -1.0f, 1.0f},
                {1.0f, -1.0f, -1.0f, 1.0f},
                {1.0f, -1.0f, 1.0f, 1.0f},
                {-1.0f, -1.0f, 1.0f, 1.0f}
            },
            {
                {1.0f, 1.0f, 1.0f, 1.0f},
                {1.0f, 1.0f, -1.0f, 1.0f},
                {-1.0f, 1.0f, -1.0f, 1.0f},
                {-1.0f, 1.0f, 1.0f, 1.0f}
            },
            {
                {-1.0f, -1.0f, -1.0f, 1.0f},
                {-1.0f, 1.0f, -1.0f, 1.0f},
                {1.0f, 1.0f, -1.0f, 1.0f},
                {1.0f, -1.0f, -1.0f, 1.0f}
            },
            {
                {1.0f, 1.0f, 1.0f, 1.0f},
                {-1.0f, 1.0f, 1.0f, 1.0f},
                {-1.0f, -1.0f, 1.0f, 1.0f},
                {1.0f, -1.0f, 1.0f, 1.0f}
            }
        };

        private float cube_normals[][] =
        {
            {-1.0f, 0.0f, 0.0f, 0.0f},
            {1.0f, 0.0f, 0.0f, 0.0f},
            {0.0f, -1.0f, 0.0f, 0.0f},
            {0.0f, 1.0f, 0.0f, 0.0f},
            {0.0f, 0.0f, -1.0f, 0.0f},
            {0.0f, 0.0f, 1.0f, 0.0f}
        };

        private boolean useLighting = true;
        private boolean useFog = false;
        private boolean useLogo = false;
        private boolean useQuads = true;
        private int tick = -1;

        public scubeCanvas(int w, int h)
        {
            super(w, h);
            GLContext.gljNativeDebug = false;
            GLContext.gljClassDebug = false;
            setAnimateFps(30.0);
        }
    
        public void preInit()
        {
            doubleBuffer = true;
            stereoView = false;
        }
    
        public void init()
        {
            System.out.println("init(): " + this);
            reshape(getSize().width, getSize().height);

                /* setup context */
            gl.glMatrixMode(GL_PROJECTION);
            gl.glLoadIdentity();
            gl.glFrustum(-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 3.0f);

            gl.glMatrixMode(GL_MODELVIEW);
            gl.glLoadIdentity();
            gl.glTranslatef(0.0f, 0.0f, -2.0f);

            gl.glEnable(GL_DEPTH_TEST);

            if (useLighting) gl.glEnable(GL_LIGHTING);
            gl.glEnable(GL_LIGHT0);
            gl.glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
            gl.glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmb);
            gl.glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiff);
            gl.glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpec);

            gl.glEnable(GL_NORMALIZE);

            if (useFog) gl.glEnable(GL_FOG);
            gl.glFogfv(GL_FOG_COLOR, fogColor);
            gl.glFogfv(GL_FOG_INDEX, fogIndex);
            gl.glFogf(GL_FOG_MODE, GL_EXP);
            gl.glFogf(GL_FOG_DENSITY, 0.5f);
            gl.glFogf(GL_FOG_START, 1.0f);
            gl.glFogf(GL_FOG_END, 3.0f);

            gl.glEnable(GL_CULL_FACE);
            gl.glCullFace(GL_BACK);

            gl.glShadeModel(GL_SMOOTH);

            gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            if (useLogo)
                gl.glPolygonStipple(sgiPattern);
            else
                gl.glPolygonStipple(shadowPattern);

            gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
            gl.glClearIndex(0);
            gl.glClearDepth(1);
                
            glj.gljCheckGL();

            addKeyListener(this);
	    addMouseListener(this);    
        }
    
        public void doCleanup()
        {
            System.out.println("destroy(): " + this);
            removeKeyListener(this);
        }
    
        public void reshape(int width, int height)
        {
            gl.glViewport(0,0,width,height);

// Put any custom reshape code here.

        }

        public void display()
        {
            if (glj.gljMakeCurrent() == false) return;

            if (!isSuspended()) inctick();

            float cubeXform[] = new float[16];

            gl.glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

            gl.glPushMatrix();
            gl.glTranslatef(0.0f, -1.5f, 0.0f);
            gl.glRotatef(-90.0f, 1f, 0f, 0f);
            gl.glScalef(2.0f, 2.0f, 2.0f);

            drawCheck(6, 6, BLUE, YELLOW);  /* draw ground */
            gl.glPopMatrix();

            gl.glPushMatrix();
            gl.glTranslatef(0.0f, 0.0f, -0.9f);
            gl.glScalef(2.0f, 2.0f, 2.0f);

            drawCheck(6, 6, BLUE, YELLOW);  /* draw back */
            gl.glPopMatrix();

            gl.glPushMatrix();
            gl.glTranslatef(0.0f, 0.2f, 0.0f);
            gl.glScalef(0.3f, 0.3f, 0.3f);
            gl.glRotatef((360.0f / (30 * 1)) * tick, 1f, 0f, 0f);
            gl.glRotatef((360.0f / (30 * 2)) * tick, 0f, 1f, 0f);
            gl.glRotatef((360.0f / (30 * 4)) * tick, 0f, 0f, 1f);
            gl.glScalef(1.0f, 2.0f, 1.0f);
            gl.glGetFloatv(GL_MODELVIEW_MATRIX, cubeXform);

            drawCube(RED);        /* draw cube */
            gl.glPopMatrix();

            gl.glDepthMask(false);
            gl.glEnable(GL_POLYGON_STIPPLE);
            if (useFog) gl.glDisable(GL_FOG);
            gl.glPushMatrix();
            myShadowMatrix(groundPlane, lightPos);
            gl.glTranslatef(0.0f, 0.0f, 2.0f);
            gl.glMultMatrixf(cubeXform);

            drawCube(BLACK);      /* draw ground shadow */
            gl.glPopMatrix();

            gl.glPushMatrix();
            myShadowMatrix(backPlane, lightPos);
            gl.glTranslatef(0.0f, 0.0f, 2.0f);
            gl.glMultMatrixf(cubeXform);

            drawCube(BLACK);      /* draw back shadow */
            gl.glPopMatrix();

            gl.glDepthMask(true);
            gl.glDisable(GL_POLYGON_STIPPLE);
            if (useFog) gl.glEnable(GL_FOG);

            glj.gljSwap();
            glj.gljCheckGL();
            glj.gljFree();
    
            //if (!isSuspended()) repaint();  // Animate at full speed.
        }

        // Methods required for the implementation of KeyListener
        public void keyPressed(KeyEvent e)
        {
        }

        public void keyReleased(KeyEvent e)
        {
        }

        public void keyTyped(KeyEvent e)
        {
            if (glj.gljMakeCurrent() == false) return;
            boolean dorepaint = false;
            switch ((char)e.getKeyChar())
            {
            case 'L':
            case 'l':
                useLighting = !useLighting;
                if (useLighting)
                    gl.glEnable(GL_LIGHTING);
                else
                    gl.glDisable(GL_LIGHTING);
                dorepaint = isSuspended();
                break;
            case 'S':
            case 's':
                useLogo = !useLogo;
                if (useLogo)
                    gl.glPolygonStipple(sgiPattern);
                else
                    gl.glPolygonStipple(shadowPattern);
                dorepaint = isSuspended();
                break;
            case 'Q':
            case 'q':
                useQuads = !useQuads;
                dorepaint = isSuspended();
                break;
            case 'F':
            case 'f':
                useFog = !useFog;
                if (useFog)
                    gl.glEnable(GL_FOG);
                else
                    gl.glDisable(GL_FOG);
                dorepaint = isSuspended();
                break;
            case '1':
                gl.glFogf(GL_FOG_MODE, GL_LINEAR);
                dorepaint = isSuspended();
                break;
            case '2':
                gl.glFogf(GL_FOG_MODE, GL_EXP);
                dorepaint = isSuspended();
                break;
            case '3':
                gl.glFogf(GL_FOG_MODE, GL_EXP2);
                dorepaint = isSuspended();
                break;
            case 'P':
            case 'p':
                setSuspended(!isSuspended());
                break;
            case ' ':
                if (isSuspended())
                {
                    inctick();
                    dorepaint = true;
                }
                break;
            }
            glj.gljFree();
            if (dorepaint) repaint();
        }

        private void inctick()
        {
            tick++;
            if (tick >= 120) tick = 0;
        }

        private void setColor(int c)
        {
            if (useLighting)
                gl.glMaterialfv
                    (GL_FRONT_AND_BACK,
                     GL_AMBIENT_AND_DIFFUSE,
                     materialColor[c]);
            else
                gl.glColor4fv(materialColor[c]);
        }

        private void drawCube(int color)
        {
            setColor(color);

            for (int i = 0; i < 6; ++i)
            {
                gl.glNormal3fv(cube_normals[i]);
                gl.glBegin(GL_POLYGON);
                gl.glVertex4fv(cube_vertexes[i][0]);
                gl.glVertex4fv(cube_vertexes[i][1]);
                gl.glVertex4fv(cube_vertexes[i][2]);
                gl.glVertex4fv(cube_vertexes[i][3]);
                gl.glEnd();
            }
        }

        private boolean check_initialized = false;
        private boolean check_usedLighting = false;
        private boolean check_usedQuads = false;
        private int checklist = 0;

        private void drawCheck(int w, int h, int evenColor, int oddColor)
        {
            if (   (!check_initialized)
                || (check_usedLighting != useLighting)
                || (check_usedQuads != useQuads)  )
            {
                float square_normal[] = {0.0f, 0.0f, 1.0f, 0.0f};
                float square[][] = new float[4][4];
                int i, j;

                if (checklist == 0) checklist = gl.glGenLists(1);
                gl.glNewList(checklist, GL_COMPILE_AND_EXECUTE);
                if (useQuads)
                {
                    gl.glNormal3fv(square_normal);
                    gl.glBegin(GL_QUADS);
                }
                for (j = 0; j < h; ++j)
                {
                    for (i = 0; i < w; ++i)
                    {
                        square[0][0] = -1.0f + 2.0f / w * i;
                        square[0][1] = -1.0f + 2.0f / h * (j + 1);
                        square[0][2] = 0.0f;
                        square[0][3] = 1.0f;

                        square[1][0] = -1.0f + 2.0f / w * i;
                        square[1][1] = -1.0f + 2.0f / h * j;
                        square[1][2] = 0.0f;
                        square[1][3] = 1.0f;
                        
                        square[2][0] = -1.0f + 2.0f / w * (i + 1);
                        square[2][1] = -1.0f + 2.0f / h * j;
                        square[2][2] = 0.0f;
                        square[2][3] = 1.0f;
                        
                        square[3][0] = -1.0f + 2.0f / w * (i + 1);
                        square[3][1] = -1.0f + 2.0f / h * (j + 1);
                        square[3][2] = 0.0f;
                        square[3][3] = 1.0f;
                        
                        if ( ((i & 1) != 0) ^ ((j & 1) != 0) )
                            setColor(oddColor);
                        else
                            setColor(evenColor);

                        if (!useQuads)gl.glBegin(GL_POLYGON);
                        gl.glVertex4fv(square[0]);
                        gl.glVertex4fv(square[1]);
                        gl.glVertex4fv(square[2]);
                        gl.glVertex4fv(square[3]);
                        if (!useQuads) gl.glEnd();
                    }
                }

                if (useQuads) gl.glEnd();
                gl.glEndList();

                check_initialized = true;
                check_usedLighting = useLighting;
                check_usedQuads = useQuads;
            }
            else
                gl.glCallList(checklist);
        }

        private void myShadowMatrix(float ground[], float light[])
        {
            float dot;
            float shadowMat[] = new float[4*4];

            dot =
                ground[0] * light[0] +
                ground[1] * light[1] +
                ground[2] * light[2] +
                ground[3] * light[3];

            shadowMat[0] = dot - light[0] * ground[0];
            shadowMat[4] = -light[0] * ground[1];
            shadowMat[8] = -light[0] * ground[2];
            shadowMat[12] = -light[0] * ground[3];
            
            shadowMat[1] = -light[1] * ground[0];
            shadowMat[5] = dot - light[1] * ground[1];
            shadowMat[9] = -light[1] * ground[2];
            shadowMat[13] = -light[1] * ground[3];
            
            shadowMat[2] = -light[2] * ground[0];
            shadowMat[6] = -light[2] * ground[1];
            shadowMat[10] = dot - light[2] * ground[2];
            shadowMat[14] = -light[2] * ground[3];
            
            shadowMat[3] = -light[3] * ground[0];
            shadowMat[7] = -light[3] * ground[1];
            shadowMat[11] = -light[3] * ground[2];
            shadowMat[15] = dot - light[3] * ground[3];

            gl.glMultMatrixf(shadowMat);
        }

        // Methods required for the implementation of MouseListener
        public void mouseEntered( MouseEvent evt )
        {
            Component comp = evt.getComponent();
	    if( comp.equals(this ) )
	    {
		requestFocus();
	    }
        }

        public void mouseExited( MouseEvent evt )
        { }
        public void mousePressed( MouseEvent evt )
        { }
        public void mouseReleased( MouseEvent evt )                                     
	{ }
        public void mouseClicked( MouseEvent evt )
        { 
            Component comp = evt.getComponent();
	    if( comp.equals(this ) )
	    {
		requestFocus();
	    }
	}
    }
}
