import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/**
 * A Component that can be used to enter secret combinations
 * using the keyboard. A combination can consist of any number
 * of characters. The combination is never displayed.
 * Users indicates that they are done by pressing [Enter].
 *   
 * @author  Prof. David Bernstein, James Madison University
 * @version 1.0
 */
public class CombinationField extends JPanel implements KeyListener
{
  private static final long serialVersionUID = 1L;

  private ActionListener actionListener = null;
  Color   background;
  private int            id = ActionEvent.ACTION_FIRST;
  private JLabel         label;
  private String         combination;
  
  /**
   * Default Constructor.
   */
  public CombinationField()
  {
    super();

    setLayout(new BorderLayout());
    label = new JLabel("", SwingConstants.CENTER);
    add(label, BorderLayout.CENTER);
    background = getBackground();

    reset();
    
    setFocusable(true);
    requestFocusInWindow();
 }

  /**
   * Add an ActionListener to this Component. The ActionListener
   * will be informed when the user presses [Enter].
   * 
   * @param l  The ActionListener to add
   */
  public synchronized void addActionListener(ActionListener l) 
  {
    actionListener = AWTEventMulticaster.add(actionListener, l);
  }

  /**
   * Fire an ActionEvent to all listeners.
   */
  private void fireEvent()
  {
    ActionEvent ae = new ActionEvent(this, id, "CombinationEntered");
    id++;
    actionListener.actionPerformed(ae);
  }
  
  /**
   * Get the most recent combination that was entered
   * since the last call to reset().
   * 
   * @return  The combination
   */
  public String getCombination()
  {
    String result = combination;
    combination = "";
    return result;
  }

  /**
   * Handle keyTyped messages.
   * 
   * @param e The event that generated the message
   */
  public void keyTyped(KeyEvent e)
  {
  }

  /**
   * Handle keyPressed messages.
   * 
   * @param e The event that generated the message
   */
  public void keyPressed(KeyEvent e)
  {
    setBackground(Color.YELLOW);
    repaint();
    Toolkit.getDefaultToolkit().beep();
  }

  /**
   * Handle keyReleased messages.
   * 
   * @param e The event that generated the message
   */
  public void keyReleased(KeyEvent e)
  {
    setBackground(background);
    int code = e.getKeyCode();

    if (code == KeyEvent.VK_ENTER)
    {
      removeKeyListener(this);
      setText("Disabled");
      if (actionListener != null) fireEvent();
    }
    else
    {
      combination += e.getKeyChar();
    }
  }

  /**
   * Remove an ActionListener from this Component.
   * 
   * @param l  The ActionListener to remove
   */
  public synchronized void removeActionListener(ActionListener l) 
  {
    actionListener = AWTEventMulticaster.remove(actionListener, l);
  }

  /**
   * Reset the state of this Component.
   */
  public void reset()
  {
    combination = "";
    addKeyListener(this);
    label.setText("Enter A Combination");
  }
  
  /**
   * Set the text on this Component.
   * 
   * @param text  The text
   */
  public void setText(String text)
  {
    label.setText(text);
  }
}
