import java.awt.*;
import java.awt.event.*;
import java.awt.Point;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.event.ListSelectionListener;
import java.awt.font.FontRenderContext;
import java.awt.font.LineBreakMeasurer;
import java.awt.font.TextLayout;
import java.awt.image.BufferedImage;
import java.text.AttributedCharacterIterator;
import java.util.Date;
import java.util.Random;
import java.awt.Robot;
import java.io.BufferedWriter;
import java.io.FileWriter;

/**
 * Fourchoice						                      		  <br>
 *																  <br>
 * Data are saved to fourchoice-X.txt
 */

public class fourchoice    extends JPanel
                         implements TestInterface, KeyListener {
     
	/**
	* Debugmode: false - no debug, true - debug
    */
    public static boolean debug              = true;
  
    // Layout defaults
	/**
	* Screen width
    */
    public static int SCREEN_W               = 800;
	/**
	* Screen height
    */
    public static int SCREEN_H               = 600;

	// Which key is what number?
	int fKeyCode							 = 0;	
	int vKeyCode							 = 1;
	int jKeyCode							 = 2;	
	int nKeyCode							 = 4;	
	
	/**
	* Codes for different keyboard selection. keyboard=0 for f,v,j,n and 
	* numpad=1 for  4,1,5,2 keypad numbers
	*/
	int KEYBOARD							 = 0;
	int NUMPAD 								 = 1;
	
	/**
	* This method indicates what keys the user chose keyboard or keypad?
	*/
	int chosenKeys							 = 0;
	
	/**
	* Symbol 1 location's x-coordinate
    */
    static int SYMBOL_1_LEFT              	 = SCREEN_W/2 - 100;
	/**
	* Symbol 1 location's y-coordinate
    */
    static int SYMBOL_1_TOP         	     = SCREEN_H/2;
	/**
	* Symbol 2 location's x-coordinate
    */
    static int SYMBOL_2_LEFT              	 = SCREEN_W/2 + 100;
	/**
	* Symbol 2 location's y-coordinate
    */
    static int SYMBOL_2_TOP         	     = SCREEN_H/2;

	
	/**
	* The X-coordinate of the trial number debug-text 
    */
    int TRIAL_INFO_X                         = 650;
    /**
	* The Y-coordinate of the trial number debug-text 
    */
	int TRIAL_INFO_Y                         = 50;
    
	
	/**
	* The boarder's width to help drawing boarder. 
    */
	public static int BOARDER_W              = 40;
    /**
	* The boarder's height to help drawing boarder. 
    */
	public static int BOARDER_H              = 40;
	
	/**
	* Sentence starting with PRINT_ tells what mode the test is currently doing.<br>
	* Print the key selection-mode first
	* @see #printMode
    */	
    public int PRINT_CHOOSE_KEYS             = 0;
	
	/**
	* Sentence starting with PRINT_ tells what mode the test is currently doing.<br>
	* Print greeting is the mode when test starts and the greeting text is printed.
	* @see #printMode
    */	
    public int PRINT_GREETING                = 1;
	
	/**
	* Sentence starting with PRINT_ tells what mode the test is currently doing.<br>
	* If printMode is set to this the trial is shown and we'r waiting for user keypress.
	* @see #printMode
    */	
    public int PRINT_TRIAL                 	 = 2;
		
	/**
	* The current trial number on going. ie. it can be from 0 to 180.
    */
    public int currentTrial                  = 0;
   
	/**
	* This variable tells the time when test was started.
    */	
    static long testStartTime;     
	/**
	* This variable tells the time when last printmode was changed ie. when the last trial started
    */	
    static long screenStartTime;
    
	/**
	* This variable is the printMode which tells what phase the test is going through at the moment.
	* @see #PRINT_TRIAL
	*/
    public int printMode                     = 0;
    
	/**
	* The JFrame which holds the graphical frameset and helps with the layout.
	* @see javax.swing.JFrame
    */		
    static JFrame frame;
	
	/*
	* JPanel to help catch the keyboard input
	*/
	static JPanel listenerPan = new JPanel();
	
	/**
	* JComponent to help with the layout system.
	* @see JComponent
    */		
    static JComponent newContentPane;
	
	/**
	* Transparent 16 x 16 pixel cursor image.
    */		
    static BufferedImage cursorImg           = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);    
	
	/**
	* Create a new blank cursor.
    */
    static Cursor blankCursor                = Toolkit.getDefaultToolkit().createCustomCursor(cursorImg, new Point(0, 0), "blank cursor");
       
	/**
	* For saving the results a bufferedwriter is neccessary.
	* @see java.io.BufferedWriter
    */		
    static BufferedWriter bw;
    
    
	// Design parameters  
    /**
	* Amount of repeats in the design	
    */
    public static int repeats                = 50; // Repeat every case x amount
    
	/**
	* Different quad-markings
    */
	public static int quads[] 			     = {1,2,3,4};
    
	/**
	* Holds the subject-number.
    */		
	public static String subjectGuy          = "James Bond";
	
	/**
	* design is the object of DesignContainer and holds the information and functions to do the actual test.
    */    
    public static DesignContainer design;
        
        
	/**
	* Contains the trials included in this design. It also does the shuffling of   
	* of trials and initializes the trial objects according the design setup.	   
	* user choises and responsetime are also captured through this to each trial.						   	
	* @see 		Trial															   
	*/	
    public static class DesignContainer {
        
        int amountOfTrials = quads.length*repeats;
        Trial trialsTmp[]  = new Trial[amountOfTrials];
        Trial trials[]     = new Trial[amountOfTrials];                
        
		/**
		* The constructor generates the trials according the design parameters which  
		* are defined earlier in the static variables. 
		*/	
        public DesignContainer() {           
            // Generate trials for not suffled array
            int index = 0;
            for (int angle=0;angle<quads.length;angle++) {
                for (int repeat=0;repeat<repeats;repeat++) {                                                                                              
                        trialsTmp[index] = new Trial(angle,angle,angle,angle); 
                        trials[index]    = new Trial();
                        index++;
                }
            }                     
			
            // Suffle the array: Loop and insert into new random places
            boolean trySuffle;
            for (int i=0;i<amountOfTrials;i++) { 
                trySuffle=true;
                while (trySuffle) { 
                    int randomIndex = getRandomNumber(amountOfTrials);
                    if ( trials[randomIndex].suffled == false ) {
                         trials[randomIndex] = trialsTmp[i]; // Copy the generated trial into this array
                         trials[randomIndex].suffled = true; // Merge to avoid inserting again..
                         trials[randomIndex].setTrialNumber(randomIndex+1);
                         trySuffle=false; // Okay ready to go next index!
                         if (debug) System.out.println("Suffled n shaked but not mixed: tmp[" + i + "] to trial[" + randomIndex + "]");
                    }
                }
            }
        }
		       
		/**
		* User pressed key. Forward to ask the trial if it was the right answer or even S or D..
		* @param 		keyCode		user's keyCode
		* @param 		trialNum	user's trialnumber
		* @return		true, if the user gave some answer by keyboard, or false if not
		* false.																	  
		*/		
        public boolean userPressedKey(int keyCode, int trialNum) {
            if (trials[trialNum].userPressedKey(keyCode))
                return true;
            else
                return false;
        }    
		
		/**
		* This function is called to record the time when user pressed the key	  		
		*/
        public void response(int trialNum) {
            trials[trialNum].trialResponse();
        }

    }

      
	  
	/**
	* This class resembles one trial of the study experiment. 					  
	* @see 		DesignContainer													  
	*/	
    public static class Trial {
	
        
        // Keeps track if the element is processed already to suffled list or just initialized
        public boolean suffled = false;                 
        	
        /**
		* response time that went for user to pick answer
		*/
		long responseTime     = 0;
        
		/**
		* The user's given answer. 
		*/
        int  answer            = 0;
		
		/**
		* The correctness of user's answer.
		*/
        int  correct           = 0;

		/**
		* The correct answer
		*/
        int  correctAnswer     = 0;
		
		/**
		* More to add.. Rotation of the two shapes
		*/
        
		
		/**
		* The index of this trial.
		*/
        int  thisTrialNumber   = 0;
        
        public Trial() {}
		
		/**
		* The constructor for trial. This takes care of calling the methods generating
		* shapes and gathering the trials information about what's right answer and what
		* is the quad etc.
		* @param v1		.       .
		* @param v2		..     ..
		* @param v3		...   ...
		* @param v4		.... ....
		*/
        public Trial(int v1, int v2, int v3, int v4) {
            // Copy the index values as well for further needs
                       
            if (debug) System.out.print("Added trial: "+v1+" "+v2+" "+v3+" "+v4);
            generateShapes();
            if (debug) System.out.println("");
        }
        
		/**
		* Set the trialNumber -variable of this trial which tells this trials index.  
		* @param	num 	The trial number.										  
		*/
        public void setTrialNumber(int num) {
            thisTrialNumber = num;
        }               
        
        /**
		* Log the results into debug or file according subject's number.			  
		* Filename is made from subjectnumber.										  
		* This is called after trial is done to make sure all informatin is complete.
		* Does io exception if something went horribly wrong.					  
		*/				
        public void printLog() {            
            /*String logLine = subjectGuy + " " + thisTrialNumber + " " + currentTestTime + " " + targetsReal+ " " + sizeReal + " "+ targCharReal + " " + targColorReal + " " + 
                     generatedCharStr + " " + answer + " " + correct + " " + responseTime1 + " " + responseTime2;
            if (debug) System.out.println(logLine);
            try {
                bw.write(logLine);
                bw.newLine();
                bw.flush();
            } catch(Exception e) { System.out.println("Problems saving results.."); }            */
        }
        
        /**
		* This captures the time user went choosing the answer. This should be called right after key press.
		* @see 		#getTestTimeMs()													  
		* @see 		#getScreenTimeMs()												  
		* @see		#trialResponse2()												  
		*/
		public void trialResponse() {
            responseTime   = getScreenTimeMs();
        }
        
				
		/**
		* This function checks the correctness of user's answer.					  
		* This should be called after user had pressed button.
		*/
        public void checkCorrectness() {                     
            if (answer==0) {
                correct = 0;
			}
        }

		/**
		* The user had pressed a key. Testing if it was f,v,j,n
		* @param 		keyCode 	the key code user pressed
		* @return		if he pressed s or d return true, otherwise return false to recognize he pressed wrong button
		* false.																	   
		*/
        public boolean userPressedKey(int keyCode) {
            
            boolean heTrulyHit=false;
            
				// Test if user hit S or D.. Return false if he didn't press those buttons.
            
            return heTrulyHit;
        }
        
		/**
		* Generates the shapes or something for the trial..
		* @see 	Trial.Trial(int v1, int v2, int v3, int v4)								  	
		*/
        private void generateShapes() {            
            
        }
				
		/**
		* Draws shapes of the trial. Ie two shapes in different angles.
		* @param 		g Graphics to draw the stuff.								  	 
		*/
        public void drawShapes(Graphics g) {

        }
		
    }
    
	
	/**
     * Generates a random number from given range.								  
	 * @param 		range which should be positive number ie. 100				  	 
	 * @return		Randomly generated number from range ie. 0-100  			  
	 */
    public static int getRandomNumber(int range) {
       Random randomGenerator = new Random();
       return randomGenerator.nextInt(range);
    }
    
    
	/**
	 * Nothing overwhelming..													   
     * Start function for the test. Subject number will be given also via this.   
	 * The test-file is started to write in this function as also the design      
	 * object which is DesignContainer's object will be set up here.			  
	 * This function should be called when starting the test and the subject's    
	 * number is known. This is called from the start menu.															  
	 * @param       subjectNumber subject's individual number 					  
	 * @see         java.lang.Thread														  
	 */
    public static void runTest(String subjectNumber) {
        
        subjectGuy = subjectNumber;
        design     = new DesignContainer();
        if (debug) System.out.println("subnum resptype isi trial sound resp quad leftright updown respquad  corr lapse rt");
        
		/* set up the logfile
        try {
            bw         = new BufferedWriter(new FileWriter("rotation-"+subjectGuy+".txt",true));           
            bw.write("subnum resptype isi trial sound resp quad leftright updown respquad  corr lapse rt");
            bw.newLine();
            bw.flush();
        } catch(Exception e) { System.out.println("Problems loading and setting up the filewriter or file.."); }        
        */
        
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {                               
               // Set up user GUI 
               createAndShowGUI();                                                  
            }
        });                
        
        // Set up test-updater              
        Thread upd = new testUpdater();
        upd.start();
        
    }
    
	/**
     * Test updater holds the main loop for the test. It takes care of updating   
	 * the graphical interface again and again and making the thread sleep in     
	 * each cycle for 50ms.											  			  
	 * It also extends the Thread-class and overrides the run()-method.			  
	 * @see         #paint()														  
	 * @see         java.lang.Thread														  
	 */
    static class testUpdater extends Thread {         
         public void run() {            
            while(true) { // Test MAIN LOOP
                
                // Graphical delay 
                try 
                {
                     Thread.sleep(50);
                }
                catch (Exception e) {}      

                newContentPane.repaint();            
            
            } // Test mainloop            
         }
    }
    
    
	/**
     * Resets screen time. Should be called	when the time taking starts.		  
	 * For example when trial starts each time.									   
	 * @see         #getScreenTimeMs()											  
	 * @see         #resetTestTime()   											  
	 * @see         #getTestTimeMs()												  
	 */	 
    public static void resetScreenTime() {
        screenStartTime = new Date().getTime(); 
    }
	
	/**
     * Returns the screentime which is the time past after resetScreenTime() was  
     * called. For example get the time of last trial.							  	 
	 * @see         #resetScreenTime()											  
	 * @see         #resetTestTime()    											  
	 * @see         #getTestTimeMs()												  
	 * @return      the time in milliseconds after resetScreenTime() was called.  
	 */
    public static long getScreenTimeMs() {
        return (new Date().getTime() - screenStartTime ); 
    }
	
	/**
     * Resets test time. Should be used right after the total test begins.		  
	 * @see         #getScreenTimeMs()											  
	 * @see         #resetScreenTime()   										  
	 * @see         #getTestTimeMs()												  
	 */
    public static void resetTestTime() {
        testStartTime = new Date().getTime(); 
    }
	
	/**
     * Returns the test time which is the time past after resetTestTime() was     
     * called. For example get the time when person started doing the test.		  	 
	 * @see         #resetScreenTime()											  
	 * @see         #resetTestTime()    											  
	 * @see         #getScreenTimeMs()											  
	 * @return      the time in milliseconds after resetTestTime() was called.    
	 */
	public static long getTestTimeMs() {
        return (new Date().getTime() - testStartTime ); 
    }
    
     
	/**
    * fourchoice class construcor.
    * 
	* Keypresses are captured wheeeere?
	*
	* @see        java.awt.event.MouseAdapter
	*/
    public fourchoice() {

		listenerPan.addKeyListener(this);

		listenerPan.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_F,0,true),"fKey");
		listenerPan.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_V,0,true),"vKey");
		listenerPan.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_J,0,true),"jKey");
		listenerPan.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_N,0,true),"nKey");

		listenerPan.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD4,0,true),"4Key");
		listenerPan.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD1,0,true),"1Key");
		listenerPan.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD5,0,true),"5Key");
		listenerPan.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_NUMPAD2,0,true),"2Key");
		
		listenerPan.getActionMap().put("fKey",fKey);
		listenerPan.getActionMap().put("vKey",vKey);
		listenerPan.getActionMap().put("jKey",jKey);
		listenerPan.getActionMap().put("nKey",nKey);
		
		listenerPan.getActionMap().put("4Key",fKey); // Same mapping for numbad-keys..!
		listenerPan.getActionMap().put("1Key",vKey);
		listenerPan.getActionMap().put("5Key",jKey);
		listenerPan.getActionMap().put("2Key",nKey);
        
    }

    /**
     * Create the GUI and show it.
	 * Nothing special. Just setting basic things like window-size and title.
	 * @see javax.swing.JFrame
	 */
    private static void createAndShowGUI() {
        //Create and set up the window.
        frame = new JFrame("Fourchoice Test");
        //frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        
        //Create and set up the content pane.
        newContentPane = new fourchoice();			
				
        newContentPane.setOpaque(true); //content panes must be opaque               
        newContentPane.setBackground(Color.black);
        newContentPane.setLayout(null); // Helps for absolute positioning which is neccessary here..       		
        
		newContentPane.add(listenerPan, null);
		listenerPan.requestFocus();
		frame.setContentPane(newContentPane);				
		                        
        //Display the window.
        frame.pack();
        frame.setVisible(true);
        frame.setSize(800, 600);
                
    }
    

	 /**
     * This function draws according the current situation of the test.		     
	 * The drawn window is managed with global printMode-attribute.				 
	 * printMode attribute is changed according the time and user input.		 
	 * Some draw functions are used from the current 
	 * All drawing is done here.												 
	 * @param g     The Graphics to draw.										 	
	 * @see         #printMode													 
	 */
    public void paint(Graphics g)
    {       
        
       g.setColor(Color.BLACK);            
       g.fillRect(0,0,SCREEN_W,SCREEN_H);
                   
	   // Print choose keys windows
       if (printMode == PRINT_CHOOSE_KEYS) {                                
            g.setColor(Color.WHITE);            
			g.setFont(new Font("Dialog", Font.PLAIN, 22));			
			g.drawString("Which keys do you want to use to respond?",BOARDER_W*4, BOARDER_H*2+15);              
            
			g.drawString("1.",BOARDER_W*6+15, BOARDER_H*2+65);              
			g.drawString("2.",BOARDER_W*13-15, BOARDER_H*2+65);    
			
			int boxSize = 100;
			int row     = 27;
            g.fillRect(BOARDER_W*5,BOARDER_H*4,boxSize,boxSize);
			g.setColor(Color.BLACK);            
			g.drawString("Keyboard",BOARDER_W*5, BOARDER_H*4+row*1);    		
			g.drawString("F       J",BOARDER_W*5, BOARDER_H*4+row*2);                      				
			g.drawString(" V   N",BOARDER_W*5, BOARDER_H*4+row*3);                      				
			
			g.setColor(Color.WHITE);            
            g.fillRect(BOARDER_W*11,BOARDER_H*4,boxSize,boxSize);			
			g.setColor(Color.BLACK);            
			g.drawString("Numpad",BOARDER_W*11, BOARDER_H*4+row*1);    		
			g.drawString("4    5",BOARDER_W*11, BOARDER_H*4+row*2);                      				
			g.drawString("1    2",BOARDER_W*11, BOARDER_H*4+row*3);                      				

			
       } else {

	   // Print Greeting windows
       if (printMode == PRINT_GREETING) {                    
            g.setColor(Color.white);
            g.fillRect(BOARDER_W*2,BOARDER_H*2,SCREEN_W-BOARDER_W*4,SCREEN_H-BOARDER_H*5);
        
            g.setColor(Color.black);            
			int gNumtrials  = 50; // ?????????
            ghostWriter("In this test, A 'plus sign' (+) will be presented in one of the four quadrants of the computer screen. The object of the four-choice serial reaction time task is to press the key on the keyboard that corresponds to the quadrant with the plus sign. The plus sign remains in a given quadrant until one of the four keys is pressed, and then randomly appears in any one of the four quadrants, at which time you again press the corresponding key on the keyboard. This process continues for " +gNumtrials + " trials. Respond as quickly and accurately as possible. If none of the four keys is pressed within 2.5 seconds of the onset of the plus sign, a beep sounds every .1 seconds until a response is made.  Reaction times of all responses, correct and incorrect, are recorded. Use these keys to respond:",BOARDER_W*2+15,BOARDER_H*2+15,600,500,g);                          
            
			int boxSize = 100;
			int row     = 15;
			g.setFont(new Font("Dialog", Font.BOLD, 16));	
			if (chosenKeys == KEYBOARD) {
				g.setColor(Color.BLACK);            
				g.drawString("Keyboard",BOARDER_W*2+15,SCREEN_H - BOARDER_H*5+15+row*1);    		
				g.drawString("F       J",BOARDER_W*2+15,SCREEN_H - BOARDER_H*5+15+row*2);                      				
				g.drawString(" V   N",BOARDER_W*2+15,SCREEN_H - BOARDER_H*5+15+row*3);                      				
			}			
			if (chosenKeys == NUMPAD) {
				g.setColor(Color.BLACK);            
				g.drawString("Keypad",BOARDER_W*2+15,SCREEN_H - BOARDER_H*5+15+row*1);    		
				g.drawString(" 4   5",BOARDER_W*2+15,SCREEN_H - BOARDER_H*5+15+row*2);                      				
				g.drawString(" 1   2",BOARDER_W*2+15,SCREEN_H - BOARDER_H*5+15+row*3);                      				
			}			
			g.drawString("Press any key to continue..",SCREEN_W/2,SCREEN_H - BOARDER_H*4);              
       }
	   
       // Draw trial number
       if (debug) {
			g.setColor(Color.white);                        
            g.setFont(new Font("Dialog", Font.PLAIN, 12));
            g.drawString("Trial ["+(currentTrial+1)+"] of [" + (design.amountOfTrials) + "]",TRIAL_INFO_X, TRIAL_INFO_Y); 
	   }
       
       // Set defaultFont
       g.setFont(new Font("Dialog", Font.PLAIN, 26));   
       
       // Wait for user's answer screen ...
       if (printMode == PRINT_TRIAL) {                   
            frame.getContentPane().setCursor(Cursor.getDefaultCursor());           
			
			// Shapes?
            design.trials[currentTrial].drawShapes(g);
			
            g.setColor(Color.black);
            g.drawString("Press 'S' for same and 'D' for different.",153, SCREEN_H-155);              
       }
       
       } // end of drawing screens..
       
    }
    
    
    /**
     * Draws a text to screen into specified x,y position and the paragraph size 
	 * For example "Thank you for taking part in the study" inthe middle.        
     * Text is printed in a reader friendly way and not cutted stupidly..        
	 * @param  str  String that contains the text to print.					     
	 * @param  x    The starting X-position of text to print.   				 
	 * @param  y    The starting Y-position of text to print.   				 
	 * @param  w    The width of the area for printing.			  				 
	 * @param  h    The heigth of the text-area.				   				 
	 * @param  g    This holds the graphic-class where text is drawn.			 	 
	 * @see         java.awt.Graphics													 
	 */
    public void ghostWriter(String str,  int x, int y, int w, int h, Graphics g) {                
    
        int paragraphStart;
        int paragraphEnd;
    
        Graphics2D graphics2D = (Graphics2D) g;
        peblUtils util;
        AttributedCharacterIterator paragraph = peblUtils.getText(str);    
    
    
        FontRenderContext frc = peblUtils.getDefaultFontRenderContext();

        paragraphStart = paragraph.getBeginIndex();
        paragraphEnd = paragraph.getEndIndex();

        // Create a new LineBreakMeasurer from the paragraph.
        LineBreakMeasurer lineMeasurer;
        lineMeasurer = new LineBreakMeasurer(paragraph, frc);
     
        Dimension size = new Dimension(w, h);
        float formatWidth = (float) size.width;
        float drawPosY = y;

        lineMeasurer.setPosition(paragraphStart);
        
        while (lineMeasurer.getPosition() < paragraphEnd) {

            TextLayout layout = lineMeasurer.nextLayout(formatWidth);
            drawPosY += layout.getAscent();
            float drawPosX;
            if (layout.isLeftToRight()) {
                drawPosX = x;
            }
            else {
                drawPosX = formatWidth - layout.getAdvance();
            }
       
            layout.draw(graphics2D, drawPosX, drawPosY);
            drawPosY += layout.getDescent() + layout.getLeading();
        }
     
    
    } // ghostwriter

	
	//Called when the key is pressed down.
	public void keyPressed(KeyEvent e){		
	}
	
	//Called when the key is released	
	public void keyReleased(KeyEvent e){
		// Anykey pressed.. where's the anykey?!
		if (printMode == PRINT_GREETING) {
            printMode = PRINT_TRIAL; // Start test if user pressed something
            resetScreenTime();
        }			
		if (printMode == PRINT_CHOOSE_KEYS) {
			int keyKode1 = 49; // Keycode for number 1 from keyboard
			int keyKode2 = 50; // Keycode for number 2 from keyboard
			
			if (e.getKeyCode() == keyKode1) {		
				chosenKeys = KEYBOARD;
				printMode = PRINT_GREETING; // After chosing keys it's time to tell more about this test
			}
			if (e.getKeyCode() == keyKode2) {		
				chosenKeys = NUMPAD;
				printMode = PRINT_GREETING; // After chosing keys it's time to tell more about this test
			}
        }			
	}
	
	//Called when a key is typed
	public void keyTyped(KeyEvent e){ }
	
	Action fKey = new AbstractAction() {
		public void actionPerformed(ActionEvent e) {
			if (debug) System.out.println("F pressed");
			
			design.userPressedKey(fKeyCode, currentTrial);
			currentTrial++;
			
		}
	};
	Action vKey = new AbstractAction() {
		public void actionPerformed(ActionEvent e) {
			if (debug) System.out.println("V pressed");
			
			design.userPressedKey(vKeyCode, currentTrial);
			currentTrial++;
			
		}
	};
	Action jKey = new AbstractAction() {
		public void actionPerformed(ActionEvent e) {
			if (debug) System.out.println("J pressed");
			
			design.userPressedKey(jKeyCode, currentTrial);
			currentTrial++;
			
		}
	};
	Action nKey = new AbstractAction() {
		public void actionPerformed(ActionEvent e) {
			if (debug) System.out.println("N pressed");
			
			design.userPressedKey(nKeyCode, currentTrial);
			currentTrial++;
			
		}
	};
	
} // end of this funky class

