/* $Id$
 *
 * Copyright (c) 1999 Xenonsoft Limited. All Rights Reserved.
 *
 * This software is protected by copyright. You are hereby notified from
 * now by reading this message. This software is also the confidential 
 * and proprietary information of Xenonsoft Limited.  ("Confidential
 * Information"). 
 *
 * This software is distributed under the Xenonsoft Public end user 
 * License ("XPeL"), where the machine-readable source code is provided 
 * under the "Open Source" model.
 * For more information, please read the file "LICENSE-XPL.txt" 
 */

// File:`DefaultUserKeyControl.java'
//
//
// DESCRIPTION
//	Default User Defined Key tuple
// 
// Author
//
//	Peter Pilgrim
//	Thu Aug 05 19:38:34 BST 1999
// 
// RCS HEADER ``DefaultUserKeyTuple.java''
// 
//	$Author$
//	$Date$
//	$Revision$    $State$    $Locker$
//

package xenon.gamekit;

import java.awt.*;				// for Component, Panel
import java.awt.event.*;			// for KeyEvent, InputEvent
import java.io.Serializable;

import xenon.swing.*;				// for RowColumnLayout


/**
 * A default GUI control that allows game key to be user defined.
 * 
 * @author Peter Pilgrim, Thu Aug 05 19:38:52 BST 1999
 * @version $Id$
 */
public class DefaultUserKeyControl extends AbstractUserKeyControl
{
    /** the key change buttons */
    protected Button []		keyButtons;
    /** the panel container to hold the custom control */
    protected Panel		panel;

    /**
     * constructs a GUI control for user defined game keys
     * that does not allow duplicate user defined keys 
     *
     * @param userkeys the user defined key 
     */
    public DefaultUserKeyControl( UserKeyTuple [] userkeys )
    {
	this( userkeys, false );
    }
    
    /**
     * constructs a GUI control for user defined game keys
     * @param userkeys the user defined key 
     * @param duplicate if true then allow duplicate user defined keys
     */
    public DefaultUserKeyControl( 
	UserKeyTuple [] userkeys, boolean duplicates )
    {
	super( userkeys, duplicates );
	
	int rows = userkeys.length;
	
	panel = new Panel();
	RowColumnConstraints rcc = new RowColumnConstraints();
	RowColumnLayout rcl = new RowColumnLayout( 
	    RowColumnLayout.VERTICAL, 2, RowColumnLayout.PACK_COLUMN );
	rcl.setColumnResizeMode( RowColumnLayout.RESIZE_FIRST_COLUMN );
	panel.setLayout( rcl );
    	
	keyButtons = new Button[rows];

	Font labelFont = new Font( "Courier", Font.ITALIC, 12 );
	Font buttonFont = new Font( "Monospaced", Font.BOLD, 12 );
	for ( int r=0; r<rows; ++r ) {
	    Label label = new Label( userkeys[r].keyDescrip );
	    label.setFont( labelFont );
	    label.setForeground( Color.white );
	    label.setBackground( Color.blue );
	    Button button = new Button( 
		getKeyCodeToString( userkeys[r].keyCode ) );
	    button.setFont( buttonFont );
	    button.setForeground( Color.white );
	    button.setBackground( Color.red );
	    // button.addActionListener( new ButtonActionListener() );
	    button.addKeyListener( new UserKeyListener() );
	    keyButtons[r] = button;		/*!*/
	    panel.add( label, rcc );
	    panel.add( button, rcc );
	}
    }

    /** get the custom control for the user defined key GUI */
    public Component getControl()
    {
	return (panel);
    }

    /**
     * A convenience method for <b>subclassers</code>
     * sets the keycode for a new user defined keycode.
     * 
     * @param keycode the new keycode
     * @param idx the index of the user defined key array
     *
     * @return <code>boolean</code> true if key can be set,
     * or false if the key has been duplicated, and
     * if the allow duplicates property is set to false.
     */
    protected boolean setNewUserDefinedKeyCode( int keycode , int idx )
    {
	if ( !duplicates ) {
	    // Check for duplicates keycodes
	    for ( int r=0; r<userkeys.length; ++r ) {
		if ( r != idx && keycode == userkeys[r].keyCode ) {
		    // System.out.println("duplicate key!");
		    return (false);
		}
	    }
	}
	
	UserKeyTuple keytuple = userkeys[idx];
	keytuple.keyCode = keycode;
	keyButtons[idx].setLabel( getKeyCodeToString( keytuple.keyCode ) );
	if ( keycode != keytuple.defKeyCode ) {
	    keyButtons[idx].setForeground( Color.black );
	    keyButtons[idx].setBackground( Color.yellow );
	}
	else {
	    keyButtons[idx].setForeground( Color.white );
	    keyButtons[idx].setBackground( Color.red );
	}
	
	return (true);
    }
    
    // ======================================================================
    // I N N E R   C L A S S E S
    // ======================================================================

    /** a private key listener for the buttons */
    protected class UserKeyListener implements KeyListener
    {
	public UserKeyListener() 
	{
	    // System.out.println("UserKeyListener() .");
	}
	    
	// Handle Event Driven Input
	public void keyTyped( KeyEvent ke )
	{
	}
	
	public void keyPressed( KeyEvent ke )
	{
	    // report("KEY_PRESSED", ke);

	    Object src = ke.getSource();

	    int keycode = ke.getKeyCode();
	    int mods = ke.getModifiers();

	    if ( keycode != 0 ) {
		for ( int r=0; r<userkeys.length; ++r ) {
		    if ( src == keyButtons[r] ) {
			if ( ! setNewUserDefinedKeyCode( keycode , r ) ) 
			    Toolkit.getDefaultToolkit().beep();
			break;
		    }
		}
	    }
	    else 
		Toolkit.getDefaultToolkit().beep();
	}
	
	public void keyReleased( KeyEvent ke )
	{
	}

	public void report( String msg, KeyEvent ke )
	{
	    int keyCode  = ke.getKeyCode();
	    char keyChar = ke.getKeyChar();
	    String mods  = ke.getKeyModifiersText( keyCode );
	    String txt   = ke.getKeyText( keyCode );
	    
	    System.out.println( msg );
	    if ( keyCode != -1 /*KeyEvent.KEY_UNDEFINED*/ )
		System.out.println( "code:  "+keyCode );
	    if ( keyCode != KeyEvent.CHAR_UNDEFINED )
		System.out.println( "char:  "+keyChar );
	    System.out.println( "Modif: "+mods );
	    System.out.println( "Text:  "+txt );
	    if ( ke.isActionKey() ) System.out.println("ACTION");
	    System.out.println("----------");
	}
	
    }
		    

    public static void main( String [] args )
    {
	UserKeyTuple keys [] = {
	    new UserKeyTuple( "Move Left",    KeyEvent.VK_A ), 
	    new UserKeyTuple( "Move Right",   KeyEvent.VK_S ), 
	    new UserKeyTuple( "Fire Missile", KeyEvent.VK_ENTER ), 
	};
	
	
	Frame frame = new Frame("Test Default User Key Control");
	frame.setLayout( new BorderLayout() );
	DefaultUserKeyControl keyControl = new DefaultUserKeyControl( keys );
	frame.add( keyControl.getControl(), BorderLayout.CENTER );
	frame.pack();
	frame.setVisible( true );
    }
    
}

// fini
