/* JOptionPane.java
   Copyright (C) 2004 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., 59 Temple Place, Suite 330, Boston, MA
02111-1307 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.Dimension;
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!
   */
  protected class AccessibleJOptionPane extends JComponent.AccessibleJComponent
  {
    /** DOCUMENT ME! */
    private static final long serialVersionUID = 686071432213084821L;

    /**
     * Creates a new AccessibleJOptionPane object.
     */
    protected AccessibleJOptionPane()
    {
    }

    /**
     * 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();
    invalidate();
    repaint();
  }

  /**
   * 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;

    // FIXME: This dialog should be centered on the parent
    // or at the center of the screen (if the parent is null)
    // Need getGraphicsConfiguration to return non-null in
    // order for that to work so we know how large the 
    // screen is.
    dialog.getContentPane().add(this);
    dialog.setModal(true);
    dialog.setResizable(false);
    dialog.invalidate();
    dialog.repaint();

    return dialog;
  }

  /**
   * This method creates a new JInternalFrame that is in the JDesktopPane
   * which contains the parentComponent given. If no suitable JDesktopPane
   * 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.
   */
  public JInternalFrame createInternalFrame(Component parentComponent,
                                            String title)
                                     throws RuntimeException
  {
    JDesktopPane toUse = getDesktopPaneForComponent(parentComponent);
    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.setClosable(true);
    toUse.add(frame);

    // FIXME: JLayeredPane broken? See bug # 16576
    // frame.setLayer(JLayeredPane.MODAL_LAYER);
    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()
  {
    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);
    JDialog dialog = pane.createDialog(parentComponent, "Select an Option");

    dialog.pack();
    dialog.show();

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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.pack();
    dialog.show();

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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.pack();
    dialog.show();

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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.pack();
    dialog.show();

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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.pack();
    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.pack();
    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.pack();
    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.pack();
    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. 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.pack();
    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.pack();
    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, pane);

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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, pane);

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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, pane);

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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, pane);

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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, pane);

    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, pane);

    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, pane);

    return (String) 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, pane);
  }

  /**
   * 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, pane);
  }

  /**
   * 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, pane);
  }

  /**
   * 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, pane);

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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.pack();
    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.pack();
    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.pack();
    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.pack();
    dialog.show();

    return ((Integer) pane.getValue()).intValue();
  }

  /**
   * 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.
   * @param pane The JOptionPane to add to the JInternalFrame.
   */
  private static void startModal(JInternalFrame f, JOptionPane pane)
  {
    f.getContentPane().add(pane);
    f.pack();
    f.show();

    Dimension pref = f.getPreferredSize();
    f.setBounds(0, 0, pref.width, pref.height);

    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)
	  {
	  }
      }
  }
}
