/* JOptionPane.java
   Copyright (C) 2004, 2005 Free Software Foundation, Inc.

This file is part of GNU Classpath.

GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.

GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301 USA.

Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */


package javax.swing;

import java.awt.Component;
import java.awt.Frame;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import javax.swing.plaf.OptionPaneUI;

/**
 * This class creates different types of JDialogs and JInternalFrames that can
 * ask users for input or pass on information. JOptionPane can be used by
 * calling one of the show static methods or  by creating an instance of
 * JOptionPane and calling createDialog or createInternalFrame.
 */
public class JOptionPane extends JComponent implements Accessible
{
  /**
   * DOCUMENT ME!
   */
  // FIXME: This inner class is a complete stub and needs to be implemented
  // properly.
  protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent
  {
    /** DOCUMENT ME! */
    private static final long serialVersionUID = 686071432213084821L;
    
    /**
     * Creates a new AccessibleJOptionPane object.
     */
    protected AccessibleJOptionPane()
    {
      // Nothing to do here.
    }

    /**
     * DOCUMENT ME!
     *
     * @return DOCUMENT ME!
     */
    public AccessibleRole getAccessibleRole()
    {
      return null;
    }
  }

  /** DOCUMENT ME! */
  private static final long serialVersionUID = 5231143276678566796L;

  /** The value returned when cancel option is selected. */
  public static final int CANCEL_OPTION = 2;

  /** The value returned when the dialog is closed without a selection. */
  public static final int CLOSED_OPTION = -1;

  /** An option used in confirmation dialog methods. */
  public static final int DEFAULT_OPTION = -1;

  /** The value returned when the no option is selected. */
  public static final int NO_OPTION = 1;

  /** An option used in confirmation dialog methods. */
  public static final int OK_CANCEL_OPTION = 2;

  /** The value returned when the ok option is selected. */
  public static final int OK_OPTION = 0;

  /** An option used in confirmation dialog methods. */
  public static final int YES_NO_CANCEL_OPTION = 1;

  /** An option used in confirmation dialog methods. */
  public static final int YES_NO_OPTION = 0;

  /** The value returned when the yes option is selected. */
  public static final int YES_OPTION = 0;

  /** Identifier for the error message type. */
  public static final int ERROR_MESSAGE = 0;

  /** Identifier for the information message type. */
  public static final int INFORMATION_MESSAGE = 1;

  /** Identifier for the plain message type. */
  public static final int PLAIN_MESSAGE = -1;

  /** Identifier for the question message type. */
  public static final int QUESTION_MESSAGE = 3;

  /** Identifier for the warning message type. */
  public static final int WARNING_MESSAGE = 2;

  /**
   * The identifier for the propertyChangeEvent when the icon property
   * changes.
   */
  public static final String ICON_PROPERTY = "icon";

  /**
   * The identifier for the propertyChangeEvent when the initialSelectionValue
   * property changes.
   */
  public static final String INITIAL_SELECTION_VALUE_PROPERTY = "initialSelectionValue";

  /**
   * The identifier for the propertyChangeEvent when the initialValue property
   * changes.
   */
  public static final String INITIAL_VALUE_PROPERTY = "initialValue";

  /**
   * The identifier for the propertyChangeEvent when the inputValue property
   * changes.
   */
  public static final String INPUT_VALUE_PROPERTY = "inputValue";

  /**
   * The identifier for the propertyChangeEvent when the message property
   * changes.
   */
  public static final String MESSAGE_PROPERTY = "message";

  /**
   * The identifier for the propertyChangeEvent when the messageType property
   * changes.
   */
  public static final String MESSAGE_TYPE_PROPERTY = "messageType";

  /**
   * The identifier for the propertyChangeEvent when the optionType property
   * changes.
   */
  public static final String OPTION_TYPE_PROPERTY = "optionType";

  /**
   * The identifier for the propertyChangeEvent when the options property
   * changes.
   */
  public static final String OPTIONS_PROPERTY = "options";

  /**
   * The identifier for the propertyChangeEvent when the selectionValues
   * property changes.
   */
  public static final String SELECTION_VALUES_PROPERTY = "selectionValues";

  /**
   * The identifier for the propertyChangeEvent when the value property
   * changes.
   */
  public static final String VALUE_PROPERTY = "value";

  /**
   * The identifier for the propertyChangeEvent when the wantsInput property
   * changes.
   */
  public static final String WANTS_INPUT_PROPERTY = "wantsInput";

  /** The value returned when the inputValue is uninitialized. */
  public static Object UNINITIALIZED_VALUE = "uninitializedValue";

  /** The icon displayed in the dialog/internal frame. */
  protected Icon icon;

  /** The initial selected value in the input component. */
  protected Object initialSelectionValue;

  /** The object that is initially selected for options. */
  protected Object initialValue;

  /** The value the user inputs. */
  protected Object inputValue = UNINITIALIZED_VALUE;

  /** The message displayed in the dialog/internal frame. */
  protected Object message;

  /** The type of message displayed. */
  protected int messageType = PLAIN_MESSAGE;

  /**
   * The options (usually buttons) aligned at the bottom for the user to
   * select.
   */
  protected Object[] options;

  /** The type of options to display. */
  protected int optionType = DEFAULT_OPTION;

  /** The input values the user can select. */
  protected Object[] selectionValues;

  /** The value returned by selecting an option. */
  protected Object value = UNINITIALIZED_VALUE;

  /** Whether the Dialog/InternalFrame needs input. */
  protected boolean wantsInput;

  /** The common frame used when no parent is provided. */
  private static Frame privFrame = SwingUtilities.getOwnerFrame();

  /**
   * Creates a new JOptionPane object using a message of "JOptionPane
   * message", using the PLAIN_MESSAGE type and DEFAULT_OPTION.
   */
  public JOptionPane()
  {
    this("JOptionPane message", PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
  }

  /**
   * Creates a new JOptionPane object using the given message using the
   * PLAIN_MESSAGE type and DEFAULT_OPTION.
   *
   * @param message The message to display.
   */
  public JOptionPane(Object message)
  {
    this(message, PLAIN_MESSAGE, DEFAULT_OPTION, null, null, null);
  }

  /**
   * Creates a new JOptionPane object using the given message and messageType
   * and DEFAULT_OPTION.
   *
   * @param message The message to display.
   * @param messageType The type of message.
   */
  public JOptionPane(Object message, int messageType)
  {
    this(message, messageType, DEFAULT_OPTION, null, null, null);
  }

  /**
   * Creates a new JOptionPane object using the given message, messageType and
   * optionType.
   *
   * @param message The message to display.
   * @param messageType The type of message.
   * @param optionType The type of options.
   */
  public JOptionPane(Object message, int messageType, int optionType)
  {
    this(message, messageType, optionType, null, null, null);
  }

  /**
   * Creates a new JOptionPane object using the given message, messageType,
   * optionType and icon.
   *
   * @param message The message to display.
   * @param messageType The type of message.
   * @param optionType The type of options.
   * @param icon The icon to display.
   */
  public JOptionPane(Object message, int messageType, int optionType, Icon icon)
  {
    this(message, messageType, optionType, icon, null, null);
  }

  /**
   * Creates a new JOptionPane object using the given message, messageType,
   * optionType, icon and options.
   *
   * @param message The message to display.
   * @param messageType The type of message.
   * @param optionType The type of options.
   * @param icon The icon to display.
   * @param options The options given.
   */
  public JOptionPane(Object message, int messageType, int optionType,
                     Icon icon, Object[] options)
  {
    this(message, messageType, optionType, icon, options, null);
  }

  /**
   * Creates a new JOptionPane object using the given message, messageType,
   * optionType, icon, options and initialValue. The initialValue will be
   * focused initially.
   *
   * @param message The message to display.
   * @param messageType The type of message.
   * @param optionType The type of options.
   * @param icon The icon to display.
   * @param options The options given.
   * @param initialValue The component to focus on initially.
   *
   * @throws IllegalArgumentException If the messageType or optionType are not
   *         legal values.
   */
  public JOptionPane(Object message, int messageType, int optionType,
                     Icon icon, Object[] options, Object initialValue)
  {
    this.message = message;
    if (! validMessageType(messageType))
      throw new IllegalArgumentException("Message Type not legal value.");
    this.messageType = messageType;
    if (! validOptionType(optionType))
      throw new IllegalArgumentException("Option Type not legal value.");
    this.optionType = optionType;
    this.icon = icon;
    this.options = options;
    this.initialValue = initialValue;

    setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

    updateUI();
  }

  /**
   * This method creates a new JDialog that is either centered around the
   * parent's frame or centered on the screen (if the parent is null). The
   * JDialog will not be resizable and will be modal. Once the JDialog is
   * disposed, the inputValue and value properties will  be set by the
   * optionPane.
   *
   * @param parentComponent The parent of the Dialog.
   * @param title The title in the bar of the JDialog.
   *
   * @return A new JDialog based on the JOptionPane configuration.
   */
  public JDialog createDialog(Component parentComponent, String title)
  {
    Frame toUse = getFrameForComponent(parentComponent);
    if (toUse == null)
      toUse = getRootFrame();

    JDialog dialog = new JDialog(toUse, title);
    inputValue = UNINITIALIZED_VALUE;
    value = UNINITIALIZED_VALUE;

    dialog.getContentPane().add(this);
    dialog.setModal(true);
    dialog.setResizable(false);
    dialog.pack();
    dialog.setLocationRelativeTo(parentComponent);
    
    return dialog;
  }

  /**
   * This method creates a new JInternalFrame that is in the JLayeredPane
   * which contains the parentComponent given. If no suitable JLayeredPane
   * can be found from the parentComponent given, a RuntimeException will be
   * thrown.
   *
   * @param parentComponent The parent to find a JDesktopPane from.
   * @param title The title of the JInternalFrame.
   *
   * @return A new JInternalFrame based on the JOptionPane configuration.
   *
   * @throws RuntimeException If no suitable JDesktopPane is found.
   *
   * @specnote The specification says that the internal frame is placed
   *           in the nearest <code>JDesktopPane</code> that is found in
   *           <code>parent</code>'s ancestors. The behaviour of the JDK
   *           is that it actually looks up the nearest
   *           <code>JLayeredPane</code> in <code>parent</code>'s ancestors.
   *           So do we.
   */
  public JInternalFrame createInternalFrame(Component parentComponent,
                                            String title)
                                     throws RuntimeException
  {
    // Try to find a JDesktopPane.
    JLayeredPane toUse = getDesktopPaneForComponent(parentComponent);
    // If we don't have a JDesktopPane, we try to find a JLayeredPane.
    if (toUse == null)
      toUse = JLayeredPane.getLayeredPaneAbove(parentComponent);
    // If this still fails, we throw a RuntimeException.
    if (toUse == null)
      throw new RuntimeException
        ("parentComponent does not have a valid parent");

    JInternalFrame frame = new JInternalFrame(title);

    inputValue = UNINITIALIZED_VALUE;
    value = UNINITIALIZED_VALUE;

    frame.setContentPane(this);
    frame.setClosable(true);

    toUse.add(frame);
    frame.setLayer(JLayeredPane.MODAL_LAYER);

    frame.pack();
    frame.setVisible(true);

    return frame;
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJOptionPane();
    return accessibleContext;
  }

  /**
   * This method returns the JDesktopPane for the given parentComponent or
   * null if none can be found.
   *
   * @param parentComponent The component to look in.
   *
   * @return The JDesktopPane for the given component or null if none can be
   *         found.
   */
  public static JDesktopPane getDesktopPaneForComponent(Component parentComponent)
  {
    return (JDesktopPane) SwingUtilities.getAncestorOfClass(JDesktopPane.class,
                                                            parentComponent);
  }

  /**
   * This method returns the Frame for the given parentComponent or null if
   * none can be found.
   *
   * @param parentComponent The component to look in.
   *
   * @return The Frame for the given component or null if none can be found.
   */
  public static Frame getFrameForComponent(Component parentComponent)
  {
    return (Frame) SwingUtilities.getAncestorOfClass(Frame.class,
                                                     parentComponent);
  }

  /**
   * This method returns the icon displayed.
   *
   * @return The icon displayed.
   */
  public Icon getIcon()
  {
    return icon;
  }

  /**
   * This method returns the value initially selected from the list of values
   * the user can input.
   *
   * @return The initial selection value.
   */
  public Object getInitialSelectionValue()
  {
    return initialSelectionValue;
  }

  /**
   * This method returns the value that is focused from the list of options.
   *
   * @return The initial value from options.
   */
  public Object getInitialValue()
  {
    return initialValue;
  }

  /**
   * This method returns the value that the user input.
   *
   * @return The user's input value.
   */
  public Object getInputValue()
  {
    if (getValue().equals(new Integer(CANCEL_OPTION)))
      setInputValue(null);
    return inputValue;
  }

  /**
   * This method returns the maximum characters per line. By default, this is
   * Integer.MAX_VALUE.
   *
   * @return The maximum characters per line.
   */
  public int getMaxCharactersPerLineCount()
  {
    return Integer.MAX_VALUE;
  }

  /**
   * This method returns the message displayed.
   *
   * @return The message displayed.
   */
  public Object getMessage()
  {
    return message;
  }

  /**
   * This method returns the message type.
   *
   * @return The message type.
   */
  public int getMessageType()
  {
    return messageType;
  }

  /**
   * This method returns the options.
   *
   * @return The options.
   */
  public Object[] getOptions()
  {
    return options;
  }

  /**
   * This method returns the option type.
   *
   * @return The option type.
   */
  public int getOptionType()
  {
    return optionType;
  }

  /**
   * This method returns the Frame used by JOptionPane dialog's that have no
   * parent.
   *
   * @return The Frame used by dialogs that have no parent.
   */
  public static Frame getRootFrame()
  {
    return privFrame;
  }

  /**
   * This method returns the selection values.
   *
   * @return The selection values.
   */
  public Object[] getSelectionValues()
  {
    return selectionValues;
  }

  /**
   * This method returns the UI used by the JOptionPane.
   *
   * @return The UI used by the JOptionPane.
   */
  public OptionPaneUI getUI()
  {
    return (OptionPaneUI) ui;
  }

  /**
   * This method returns an identifier to determine which UI class will act as
   * the UI.
   *
   * @return The UI identifier.
   */
  public String getUIClassID()
  {
    return "OptionPaneUI";
  }

  /**
   * This method returns the value that the user selected out of options.
   *
   * @return The value that the user selected out of options.
   */
  public Object getValue()
  {
    return value;
  }

  /**
   * This method returns whether this JOptionPane wants input.
   *
   * @return Whether this JOptionPane wants input.
   */
  public boolean getWantsInput()
  {
    return wantsInput;
  }

  /**
   * This method returns a String that describes this JOptionPane.
   *
   * @return A String that describes this JOptionPane.
   */
  protected String paramString()
  {
    return "JOptionPane";
  }

  /**
   * This method requests focus for the initial value.
   */
  public void selectInitialValue()
  {
    if (ui != null)
      ((OptionPaneUI) ui).selectInitialValue(this);
  }

  /**
   * This method changes the icon property.
   *
   * @param newIcon The new icon to use.
   */
  public void setIcon(Icon newIcon)
  {
    if (icon != newIcon)
      {
	Icon old = icon;
	icon = newIcon;
	firePropertyChange(ICON_PROPERTY, old, icon);
      }
  }

  /**
   * This method changes the initial selection property.
   *
   * @param newValue The new initial selection.
   */
  public void setInitialSelectionValue(Object newValue)
  {
    if (initialSelectionValue != newValue)
      {
	Object old = initialSelectionValue;
	initialSelectionValue = newValue;
	firePropertyChange(INITIAL_SELECTION_VALUE_PROPERTY, old,
	                   initialSelectionValue);
      }
  }

  /**
   * This method changes the initial value property.
   *
   * @param newValue The new initial value.
   */
  public void setInitialValue(Object newValue)
  {
    if (initialValue != newValue)
      {
	Object old = initialValue;
	initialValue = newValue;
	firePropertyChange(INITIAL_VALUE_PROPERTY, old, initialValue);
      }
  }

  /**
   * This method changes the inputValue property.
   *
   * @param newValue The new inputValue.
   */
  public void setInputValue(Object newValue)
  {
    if (inputValue != newValue)
      {
	Object old = inputValue;
	inputValue = newValue;
	firePropertyChange(INPUT_VALUE_PROPERTY, old, inputValue);
      }
  }

  /**
   * This method changes the message property.
   *
   * @param newMessage The new message.
   */
  public void setMessage(Object newMessage)
  {
    if (message != newMessage)
      {
	Object old = message;
	message = newMessage;
	firePropertyChange(MESSAGE_PROPERTY, old, message);
      }
  }

  /**
   * This method changes the messageType property.
   *
   * @param newType The new messageType.
   *
   * @throws IllegalArgumentException If the messageType is not valid.
   */
  public void setMessageType(int newType)
  {
    if (! validMessageType(newType))
      throw new IllegalArgumentException("Message Type not legal value.");
    if (newType != messageType)
      {
	int old = messageType;
	messageType = newType;
	firePropertyChange(MESSAGE_TYPE_PROPERTY, old, messageType);
      }
  }

  /**
   * This method changes the options property.
   *
   * @param newOptions The new options.
   */
  public void setOptions(Object[] newOptions)
  {
    if (options != newOptions)
      {
	Object[] old = options;
	options = newOptions;
	firePropertyChange(OPTIONS_PROPERTY, old, options);
      }
  }

  /**
   * This method changes the optionType property.
   *
   * @param newType The new optionType.
   *
   * @throws IllegalArgumentException If the optionType is not valid.
   */
  public void setOptionType(int newType)
  {
    if (! validOptionType(newType))
      throw new IllegalArgumentException("Option Type not legal value.");
    if (newType != optionType)
      {
	int old = optionType;
	optionType = newType;
	firePropertyChange(OPTION_TYPE_PROPERTY, old, optionType);
      }
  }

  /**
   * This method changes the Frame used for JOptionPane dialogs that have no
   * parent.
   *
   * @param newRootFrame The Frame to use for dialogs that have no parent.
   */
  public static void setRootFrame(Frame newRootFrame)
  {
    privFrame = newRootFrame;
  }

  /**
   * This method changes the selectionValues property.
   *
   * @param newValues The new selectionValues.
   */
  public void setSelectionValues(Object[] newValues)
  {
    if (newValues != selectionValues)
      {
	if (newValues != null)
	  wantsInput = true;
	Object[] old = selectionValues;
	selectionValues = newValues;
	firePropertyChange(SELECTION_VALUES_PROPERTY, old, selectionValues);
      }
  }

  /**
   * This method sets the UI used with the JOptionPane.
   *
   * @param ui The UI used with the JOptionPane.
   */
  public void setUI(OptionPaneUI ui)
  {
    super.setUI(ui);
  }

  /**
   * This method sets the value has been selected out of options.
   *
   * @param newValue The value that has been selected out of options.
   */
  public void setValue(Object newValue)
  {
    if (value != newValue)
      {
	Object old = value;
	value = newValue;
	firePropertyChange(VALUE_PROPERTY, old, value);
      }
  }

  /**
   * This method changes the wantsInput property.
   *
   * @param newValue Whether this JOptionPane requires input.
   */
  public void setWantsInput(boolean newValue)
  {
    if (wantsInput != newValue)
      {
	boolean old = wantsInput;
	wantsInput = newValue;
	firePropertyChange(WANTS_INPUT_PROPERTY, old, wantsInput);
      }
  }

  /**
   * This method shows a confirmation dialog with the title "Select an Option"
   * and displays the given message. The parent frame will be the same as the
   * parent frame of the given parentComponent. This method returns the
   * option chosen by the user.
   *
   * @param parentComponent The parentComponent to find a frame in.
   * @param message The message to display.
   *
   * @return The option that was selected.
   */
  public static int showConfirmDialog(Component parentComponent, Object message)
  {
    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
    JDialog dialog = pane.createDialog(parentComponent, "Select an Option");
    dialog.show();
    
    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method shows a confirmation dialog with the given message,
   * optionType and title. The frame that owns the dialog will be the same
   * frame that holds the given parentComponent. This method returns the
   * option that was chosen.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   * @param title The title of the dialog.
   * @param optionType The optionType.
   *
   * @return The option that was chosen.
   */
  public static int showConfirmDialog(Component parentComponent,
                                      Object message, String title,
                                      int optionType)
  {
    JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
    JDialog dialog = pane.createDialog(parentComponent, title);
    dialog.show();

    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method shows a confirmation dialog with the given message, title,
   * messageType and optionType. The frame owner will be the same frame as
   * the one that holds the given parentComponent. This method returns the
   * option selected by the user.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   * @param title The title of the dialog.
   * @param optionType The optionType.
   * @param messageType The messageType.
   *
   * @return The selected option.
   */
  public static int showConfirmDialog(Component parentComponent,
                                      Object message, String title,
                                      int optionType, int messageType)
  {
    JOptionPane pane = new JOptionPane(message, messageType, optionType);
    JDialog dialog = pane.createDialog(parentComponent, title);
    dialog.show();

    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method shows a confirmation dialog with the given message, title,
   * optionType, messageType and icon. The frame owner will be the same as
   * the one that holds the given parentComponent. This method returns the
   * option selected by the user.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   * @param title The title of the dialog.
   * @param optionType The optionType.
   * @param messageType The messsageType.
   * @param icon The icon displayed.
   *
   * @return The selected option.
   */
  public static int showConfirmDialog(Component parentComponent,
                                      Object message, String title,
                                      int optionType, int messageType,
                                      Icon icon)
  {
    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
    JDialog dialog = pane.createDialog(parentComponent, title);
    dialog.show();

    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method will show a QUESTION_MESSAGE input dialog with the given
   * message. No selectionValues is set so the Look and Feel will usually
   * give the user a TextField to fill out. The frame owner will be the same
   * frame that holds the given parentComponent. This method will return the
   * value entered by the user.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   *
   * @return The value entered by the user.
   */
  public static String showInputDialog(Component parentComponent,
                                       Object message)
  {
    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
    pane.setWantsInput(true);
    JDialog dialog = pane.createDialog(parentComponent, null);
    dialog.show();
    
    return (String) pane.getInputValue();
  }

  /**
   * This method will show a QUESTION_MESSAGE type input dialog with the given
   * message and initialSelectionValue. Since there is no selectionValues
   * set, the Look and Feel will usually give a TextField to fill out. The
   * frame owner will be the same as the one that holds the given
   * parentComponent. This method will return the value entered by the user.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message to display.
   * @param initialSelectionValue The initially selected value.
   *
   * @return The value the user input.
   */
  public static String showInputDialog(Component parentComponent,
                                       Object message,
                                       Object initialSelectionValue)
  {
    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
    pane.setInitialSelectionValue(initialSelectionValue);
    pane.setWantsInput(true);
    JDialog dialog = pane.createDialog(parentComponent, null);
    dialog.show();
    
    return (String) pane.getInputValue();
  }

  /**
   * This method displays a new input dialog with the given message, title and
   * messageType. Since no selectionValues value is given, the Look and Feel
   * will usually give the user a TextField to input data to. This method
   * returns the value the user inputs.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message to display.
   * @param title The title of the dialog.
   * @param messageType The messageType.
   *
   * @return The value the user input.
   */
  public static String showInputDialog(Component parentComponent,
                                       Object message, String title,
                                       int messageType)
  {
    JOptionPane pane = new JOptionPane(message, messageType);
    pane.setWantsInput(true);
    JDialog dialog = pane.createDialog(parentComponent, title);
    dialog.show();
    
    return (String) pane.getInputValue();
  }

  /**
   * This method shows an input dialog with the given message, title,
   * messageType, icon, selectionValues, and initialSelectionValue. This
   * method returns the value that the user selects.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   * @param title The title of the dialog.
   * @param messageType The messageType.
   * @param icon The icon displayed.
   * @param selectionValues The list of values to select from.
   * @param initialSelectionValue The initially selected value.
   *
   * @return The user selected value.
   */
  public static Object showInputDialog(Component parentComponent,
                                       Object message, String title,
                                       int messageType, Icon icon,
                                       Object[] selectionValues,
                                       Object initialSelectionValue)
  {
    JOptionPane pane = new JOptionPane(message, messageType);
    pane.setWantsInput(true);
    pane.setIcon(icon);
    pane.setSelectionValues(selectionValues);
    pane.setInitialSelectionValue(initialSelectionValue);
    JDialog dialog = pane.createDialog(parentComponent, title);
    dialog.show();
    
    return pane.getInputValue();
  }

  /**
   * This method shows a QUESTION_MESSAGE type input dialog. Since no
   * selectionValues is set, the Look and Feel will usually give the user a
   * TextField to input data to. This method returns the value the user
   * inputs.
   *
   * @param message The message to display.
   *
   * @return The user selected value.
   */
  public static String showInputDialog(Object message)
  {
    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
    pane.setWantsInput(true);
    JDialog dialog = pane.createDialog(null, null);
    dialog.show();
    
    return (String) pane.getInputValue();
  }

  /**
   * This method shows a QUESTION_MESSAGE type input dialog. Since no
   * selectionValues is set, the Look and Feel will usually give the user a
   * TextField to input data to. The input component will be initialized with
   * the initialSelectionValue. This method returns the value the user
   * inputs.
   *
   * @param message The message to display.
   * @param initialSelectionValue The initialSelectionValue.
   *
   * @return The user selected value.
   */
  public static String showInputDialog(Object message,
                                       Object initialSelectionValue)
  {
    JOptionPane pane = new JOptionPane(message, QUESTION_MESSAGE);
    pane.setWantsInput(true);
    pane.setInitialSelectionValue(initialSelectionValue);
    JDialog dialog = pane.createDialog(null, null);
    dialog.show();
    
    return (String) pane.getInputValue();
  }

  /**
   * This method shows an internal confirmation dialog with the given message.
   * The internal frame dialog will be placed in the first JDesktopPane
   * ancestor of the given parentComponent. This method will return the value
   * selected.
   *
   * @param parentComponent The parent to find a JDesktopPane in.
   * @param message The message to display.
   *
   * @return The value selected.
   */
  public static int showInternalConfirmDialog(Component parentComponent,
                                              Object message)
  {
    JOptionPane pane = new JOptionPane(message);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);

    startModal(frame);
    
    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method shows an internal confirmation dialog with the given message,
   * optionType and title. The internal frame dialog will be placed in the
   * first JDesktopPane ancestor of the given parentComponent.  This method
   * will return the selected value.
   *
   * @param parentComponent The parent to find a JDesktopPane in.
   * @param message The message to display.
   * @param title The title to display.
   * @param optionType The option type.
   *
   * @return The selected value.
   */
  public static int showInternalConfirmDialog(Component parentComponent,
                                              Object message, String title,
                                              int optionType)
  {
    JOptionPane pane = new JOptionPane(message, PLAIN_MESSAGE, optionType);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);

    startModal(frame);

    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method shows an internal confirmation dialog with the given message,
   * title, optionTypes and icon for the given message type. The internal
   * confirmation dialog will be placed in the first  instance of
   * JDesktopPane ancestor of the given parentComponent.
   *
   * @param parentComponent The component to find a JDesktopPane in.
   * @param message The message to display.
   * @param title The title of the dialog.
   * @param optionType The option type.
   * @param messageType The message type.
   *
   * @return The selected value.
   */
  public static int showInternalConfirmDialog(Component parentComponent,
                                              Object message, String title,
                                              int optionType, int messageType)
  {
    JOptionPane pane = new JOptionPane(message, messageType, optionType);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);

    startModal(frame);

    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method shows an internal confirmation dialog with the given message,
   * title, option type, message type, and icon. The internal frame dialog
   * will be placed in the first JDesktopPane ancestor  that is found in the
   * given parentComponent. This method returns  the selected value.
   *
   * @param parentComponent The parent to find a JDesktopPane in.
   * @param message The message to display.
   * @param title The title to display.
   * @param optionType The option type.
   * @param messageType The message type.
   * @param icon The icon to display.
   *
   * @return The selected value.
   */
  public static int showInternalConfirmDialog(Component parentComponent,
                                              Object message, String title,
                                              int optionType, int messageType,
                                              Icon icon)
  {
    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);

    startModal(frame);

    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method shows an internal input dialog with the given message. The
   * internal frame dialog will be placed in the first JDesktopPane ancestor
   * of the given parent component. This method returns the value input by
   * the user.
   *
   * @param parentComponent The parent to find a JDesktopPane in.
   * @param message The message to display.
   *
   * @return The user selected value.
   */
  public static String showInternalInputDialog(Component parentComponent,
                                               Object message)
  {
    JOptionPane pane = new JOptionPane(message);
    pane.setWantsInput(true);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);

    startModal(frame);
    
    return (String) pane.getInputValue();
  }

  /**
   * This method shows an internal input dialog with the given message,  title
   * and message type. The internal input dialog will be placed in the first
   * JDesktopPane ancestor found in the given parent component. This method
   * will return the input value given by the user.
   *
   * @param parentComponent The component to find a JDesktopPane in.
   * @param message The message to display.
   * @param title The title to display.
   * @param messageType The message type.
   *
   * @return The user input value.
   */
  public static String showInternalInputDialog(Component parentComponent,
                                               Object message, String title,
                                               int messageType)
  {
    JOptionPane pane = new JOptionPane(message, messageType);
    pane.setWantsInput(true);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);

    startModal(frame);
    
    return (String) pane.getInputValue();
  }

  /**
   * This method shows an internal input dialog with the given message, title
   * message type, icon, selection value list and initial selection value.
   * The internal frame dialog will be placed in the first JDesktopPane
   * ancestor found in the given parent component. This method returns the
   * input value from the user.
   *
   * @param parentComponent The parent to find a JDesktopPane in.
   * @param message The message to display.
   * @param title The title to display.
   * @param messageType The message type.
   * @param icon The icon to display.
   * @param selectionValues The selection value list.
   * @param initialSelectionValue The initial selection value.
   *
   * @return The user input value.
   */
  public static Object showInternalInputDialog(Component parentComponent,
                                               Object message, String title,
                                               int messageType, Icon icon,
                                               Object[] selectionValues,
                                               Object initialSelectionValue)
  {
    JOptionPane pane = new JOptionPane(message, messageType);
    pane.setWantsInput(true);
    pane.setIcon(icon);
    pane.setSelectionValues(selectionValues);
    pane.setInitialSelectionValue(initialSelectionValue);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);

    startModal(frame);
    
    return pane.getInputValue();
  }

  /**
   * This method shows an internal message dialog with the given message. The
   * internal frame dialog will be placed in the first JDesktopPane ancestor
   * found in the given parent component.
   *
   * @param parentComponent The component to find a JDesktopPane in.
   * @param message The message to display.
   */
  public static void showInternalMessageDialog(Component parentComponent,
                                               Object message)
  {
    JOptionPane pane = new JOptionPane(message);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, null);

    startModal(frame);
  }

  /**
   * This method shows an internal message dialog with the given message,
   * title and message type. The internal message dialog is placed in the
   * first JDesktopPane ancestor found in the given parent component.
   *
   * @param parentComponent The parent component to find a JDesktopPane in.
   * @param message The message to display.
   * @param title The title to display.
   * @param messageType The message type.
   */
  public static void showInternalMessageDialog(Component parentComponent,
                                               Object message, String title,
                                               int messageType)
  {
    JOptionPane pane = new JOptionPane(message, messageType);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);

    startModal(frame);
  }

  /**
   * This method shows an internal message dialog with the given message,
   * title, message type and icon. The internal message dialog is placed in
   * the first JDesktopPane ancestor found in the given parent component.
   *
   * @param parentComponent The component to find a JDesktopPane in.
   * @param message The message to display.
   * @param title The title to display.
   * @param messageType The message type.
   * @param icon The icon to display.
   */
  public static void showInternalMessageDialog(Component parentComponent,
                                               Object message, String title,
                                               int messageType, Icon icon)
  {
    JOptionPane pane = new JOptionPane(message, messageType);
    pane.setIcon(icon);
    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);

    startModal(frame);
  }

  /**
   * This method displays an internal option dialog with the given message,
   * title, option type, message type, icon, option list, and initial option
   * value. The internal option dialog is placed in the first JDesktopPane
   * ancestor found in the parent component. This method returns the option
   * selected.
   *
   * @param parentComponent The parent to find a JDesktopPane in.
   * @param message The message displayed.
   * @param title The title displayed.
   * @param optionType The option type.
   * @param messageType The message type.
   * @param icon The icon to display.
   * @param options The array of options.
   * @param initialValue The initial value selected.
   *
   * @return The option that was selected.
   */
  public static int showInternalOptionDialog(Component parentComponent,
                                             Object message, String title,
                                             int optionType, int messageType,
                                             Icon icon, Object[] options,
                                             Object initialValue)
  {
    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon,
                                       options, initialValue);

    JInternalFrame frame = pane.createInternalFrame(parentComponent, title);

    startModal(frame);
 
    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method shows an INFORMATION_MESSAGE type message dialog.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   */
  public static void showMessageDialog(Component parentComponent,
                                       Object message)
  {
    JOptionPane pane = new JOptionPane(message, INFORMATION_MESSAGE);
    JDialog dialog = pane.createDialog(parentComponent, null);
    dialog.show();   
  }

  /**
   * This method shows a message dialog with the given message, title and
   * messageType.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   * @param title The title of the dialog.
   * @param messageType The messageType.
   */
  public static void showMessageDialog(Component parentComponent,
                                       Object message, String title,
                                       int messageType)
  {
    JOptionPane pane = new JOptionPane(message, messageType);
    JDialog dialog = pane.createDialog(parentComponent, title);
    dialog.show();
  }

  /**
   * This method shows a message dialog with the given message, title,
   * messageType and icon.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   * @param title The title of the dialog.
   * @param messageType The messageType.
   * @param icon The icon displayed.
   */
  public static void showMessageDialog(Component parentComponent,
                                       Object message, String title,
                                       int messageType, Icon icon)
  {
    JOptionPane pane = new JOptionPane(message, messageType);
    pane.setIcon(icon);
    JDialog dialog = pane.createDialog(parentComponent, title);
    dialog.show();
  }

  /**
   * This method shows an option dialog with the given message, title,
   * optionType, messageType, icon, options and initialValue. This method
   * returns the option that was selected.
   *
   * @param parentComponent The component to find a frame in.
   * @param message The message displayed.
   * @param title The title of the dialog.
   * @param optionType The optionType.
   * @param messageType The messageType.
   * @param icon The icon displayed.
   * @param options The options to choose from.
   * @param initialValue The initial value.
   *
   * @return The selected option.
   */
  public static int showOptionDialog(Component parentComponent,
                                     Object message, String title,
                                     int optionType, int messageType,
                                     Icon icon, Object[] options,
                                     Object initialValue)
  {
    JOptionPane pane = new JOptionPane(message, messageType, optionType, icon,
                                       options, initialValue);

    JDialog dialog = pane.createDialog(parentComponent, title);
    dialog.show();

    if (pane.getValue() instanceof Integer)
      return ((Integer) pane.getValue()).intValue();
    return -1;
  }

  /**
   * This method resets the UI to the Look and Feel default.
   */
  public void updateUI()
  {
    setUI((OptionPaneUI) UIManager.getUI(this));
    invalidate();
  }

  /**
   * This method returns true if the key is a valid messageType.
   *
   * @param key The key to check.
   *
   * @return True if key is valid.
   */
  private boolean validMessageType(int key)
  {
    switch (key)
      {
      case ERROR_MESSAGE:
      case INFORMATION_MESSAGE:
      case PLAIN_MESSAGE:
      case QUESTION_MESSAGE:
      case WARNING_MESSAGE:
	return true;
      }
    return false;
  }

  /**
   * This method returns true if the key is a valid optionType.
   *
   * @param key The key to check.
   *
   * @return True if key is valid.
   */
  private boolean validOptionType(int key)
  {
    switch (key)
      {
      case DEFAULT_OPTION:
      case OK_CANCEL_OPTION:
      case YES_NO_CANCEL_OPTION:
      case YES_NO_OPTION:
	return true;
      }
    return false;
  }

  /**
   * This helper method makes the JInternalFrame wait until it is notified by
   * an InternalFrameClosing event. This method also adds the given
   * JOptionPane to the JInternalFrame and sizes it according to the
   * JInternalFrame's preferred size.
   *
   * @param f The JInternalFrame to make modal.
   */
  private static void startModal(JInternalFrame f)
  {
    synchronized (f)
    {
      final JInternalFrame tmp = f;
      tmp.toFront();

      f.addInternalFrameListener(new InternalFrameAdapter()
                                 {
                                   public void internalFrameClosed(InternalFrameEvent e)
                                   {
                                     synchronized (tmp)
                                     {
                                       tmp.removeInternalFrameListener(this);
                                       tmp.notifyAll();
                                     }
                                   }
                                 });
      try
        {
          while (! f.isClosed())
            f.wait();
        }
      catch (InterruptedException ignored)
        {
          // Ignore this Exception.
        }
    }
  }
}
