/* BasicOptionPaneUI.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.plaf.basic;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.Polygon;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.OptionPaneUI;

/**
 * This class is the UI delegate for JOptionPane in the Basic Look and Feel.
 */
public class BasicOptionPaneUI extends OptionPaneUI
{
  /**
   * This is a helper class that listens to the buttons located at the bottom
   * of the JOptionPane.
   */
  protected class ButtonActionListener implements ActionListener
  {
    /** The index of the option this button represents. */
    protected int buttonIndex;

    /**
     * Creates a new ButtonActionListener object with the given buttonIndex.
     *
     * @param buttonIndex The index of the option this button represents.
     */
    public ButtonActionListener(int buttonIndex)
    {
      this.buttonIndex = buttonIndex;
    }

    /**
     * This method is called when one of the option buttons are pressed.
     *
     * @param e The ActionEvent.
     */
    public void actionPerformed(ActionEvent e)
    {
      Object value = new Integer(JOptionPane.CLOSED_OPTION);
      Object[] options = optionPane.getOptions();
      if (options != null)
	value = new Integer(buttonIndex);
      else
        {
	  String text = ((JButton) e.getSource()).getText();
	  if (text.equals(OK_STRING))
	    value = new Integer(JOptionPane.OK_OPTION);
	  if (text.equals(CANCEL_STRING))
	    value = new Integer(JOptionPane.CANCEL_OPTION);
	  if (text.equals(YES_STRING))
	    value = new Integer(JOptionPane.YES_OPTION);
	  if (text.equals(NO_STRING))
	    value = new Integer(JOptionPane.NO_OPTION);
        }
      optionPane.setValue(value);
      resetInputValue();

      Window owner = SwingUtilities.windowForComponent(optionPane);

      if (owner instanceof JDialog)
	((JDialog) owner).dispose();

      //else we probably have some kind of internal frame.
      JInternalFrame inf = (JInternalFrame) SwingUtilities.getAncestorOfClass(JInternalFrame.class,
                                                                              optionPane);
      if (inf != null)
        {
	  try
	    {
	      inf.setClosed(true);
	    }
	  catch (PropertyVetoException pve)
	    {
	    }
        }
    }
  }

  /**
   * This helper layout manager is responsible for the layout of the button
   * area. The button area is the panel that holds the buttons which
   * represent the options.
   */
  protected class ButtonAreaLayout implements LayoutManager
  {
    /** Whether this layout will center the buttons. */
    protected boolean centersChildren = true;

    /** The space between the buttons. */
    protected int padding;

    /** Whether the buttons will share the same widths. */
    protected boolean syncAllWidths;

    /** The width of the widest button. */
    private transient int widthOfWidestButton;

    /** The height of the tallest button. */
    private transient int tallestButton;

    /**
     * Creates a new ButtonAreaLayout object with the given sync widths
     * property and padding.
     *
     * @param syncAllWidths Whether the buttons will share the same widths.
     * @param padding The padding between the buttons.
     */
    public ButtonAreaLayout(boolean syncAllWidths, int padding)
    {
      this.syncAllWidths = syncAllWidths;
      this.padding = padding;
    }

    /**
     * This method is called when a component is added to the container.
     *
     * @param string The constraints string.
     * @param comp The component added.
     */
    public void addLayoutComponent(String string, Component comp)
    {
      // Do nothing.
    }

    /**
     * This method returns whether the children will be centered.
     *
     * @return Whether the children will be centered.
     */
    public boolean getCentersChildren()
    {
      return centersChildren;
    }

    /**
     * This method returns the amount of space between components.
     *
     * @return The amount of space between components.
     */
    public int getPadding()
    {
      return padding;
    }

    /**
     * This method returns whether all components will share widths (set to
     * largest width).
     *
     * @return Whether all components will share widths.
     */
    public boolean getSyncAllWidths()
    {
      return syncAllWidths;
    }

    /**
     * This method lays out the given container.
     *
     * @param container The container to lay out.
     */
    public void layoutContainer(Container container)
    {
      Component[] buttonList = container.getComponents();
      int x = container.getInsets().left;
      if (getCentersChildren())
	x += (int) ((double) (container.getSize().width) / 2
	- (double) (buttonRowLength(container)) / 2);
      for (int i = 0; i < buttonList.length; i++)
        {
	  Dimension dims = buttonList[i].getPreferredSize();
	  if (getSizeButtonsToSameWidth())
	    {
	      buttonList[i].setBounds(x, 0, widthOfWidestButton, dims.height);
	      x += widthOfWidestButton + getPadding();
	    }
	  else
	    {
	      buttonList[i].setBounds(x, 0, dims.width, dims.height);
	      x += dims.width + getPadding();
	    }
        }
    }

    /**
     * This method returns the width of the given container taking into
     * consideration the padding and syncAllWidths.
     *
     * @param c The container to calculate width for.
     *
     * @return The width of the given container.
     */
    private int buttonRowLength(Container c)
    {
      Component[] buttonList = c.getComponents();

      int buttonLength = 0;
      int widest = 0;
      int tallest = 0;

      for (int i = 0; i < buttonList.length; i++)
        {
	  Dimension dims = buttonList[i].getPreferredSize();
	  buttonLength += dims.width + getPadding();
	  widest = Math.max(widest, dims.width);
	  tallest = Math.max(tallest, dims.height);
        }

      widthOfWidestButton = widest;
      tallestButton = tallest;

      int width;
      if (getSyncAllWidths())
	width = widest * buttonList.length
	        + getPadding() * (buttonList.length - 1);
      else
	width = buttonLength;

      Insets insets = c.getInsets();
      width += insets.left + insets.right;

      return width;
    }

    /**
     * This method returns the minimum layout size for the given container.
     *
     * @param c The container to measure.
     *
     * @return The minimum layout size.
     */
    public Dimension minimumLayoutSize(Container c)
    {
      return preferredLayoutSize(c);
    }

    /**
     * This method returns the preferred size of the given container.
     *
     * @param c The container to measure.
     *
     * @return The preferred size.
     */
    public Dimension preferredLayoutSize(Container c)
    {
      int w = buttonRowLength(c);

      return new Dimension(w, tallestButton);
    }

    /**
     * This method removes the given component from the layout manager's
     * knowledge.
     *
     * @param c The component to remove.
     */
    public void removeLayoutComponent(Component c)
    {
      // Do nothing.
    }

    /**
     * This method sets whether the children will be centered.
     *
     * @param newValue Whether the children will be centered.
     */
    public void setCentersChildren(boolean newValue)
    {
      centersChildren = newValue;
      optionPane.invalidate();
    }

    /**
     * This method sets the amount of space between each component.
     *
     * @param newPadding The padding between components.
     */
    public void setPadding(int newPadding)
    {
      padding = newPadding;
      optionPane.invalidate();
    }

    /**
     * This method sets whether the widths will be synced.
     *
     * @param newValue Whether the widths will be synced.
     */
    public void setSyncAllWidths(boolean newValue)
    {
      syncAllWidths = newValue;
      optionPane.invalidate();
    }
  }

  /**
   * This helper class handles property change events from the JOptionPane.
   */
  public class PropertyChangeHandler implements PropertyChangeListener
  {
    /**
     * This method is called when one of the properties of the JOptionPane
     * changes.
     *
     * @param e The PropertyChangeEvent.
     */
    public void propertyChange(PropertyChangeEvent e)
    {
      if (e.getPropertyName().equals(JOptionPane.ICON_PROPERTY)
          || e.getPropertyName().equals(JOptionPane.MESSAGE_TYPE_PROPERTY))
	addIcon(messageAreaContainer);
      else if (e.getPropertyName().equals(JOptionPane.INITIAL_SELECTION_VALUE_PROPERTY))
	resetSelectedValue();
      else if (e.getPropertyName().equals(JOptionPane.INITIAL_VALUE_PROPERTY)
               || e.getPropertyName().equals(JOptionPane.OPTIONS_PROPERTY)
               || e.getPropertyName().equals(JOptionPane.OPTION_TYPE_PROPERTY))
        {
	  Container newButtons = createButtonArea();
	  optionPane.remove(buttonContainer);
	  optionPane.add(newButtons);
	  buttonContainer = newButtons;
        }

      else if (e.getPropertyName().equals(JOptionPane.MESSAGE_PROPERTY)
               || e.getPropertyName().equals(JOptionPane.WANTS_INPUT_PROPERTY)
               || e.getPropertyName().equals(JOptionPane.SELECTION_VALUES_PROPERTY))
        {
	  optionPane.removeAll();
	  messageAreaContainer = createMessageArea();
	  optionPane.add(messageAreaContainer);
	  optionPane.add(buttonContainer);
        }
      optionPane.invalidate();
      optionPane.repaint();
    }
  }

  /** Whether the JOptionPane contains custom components. */
  protected boolean hasCustomComponents = false;

  // The initialFocusComponent seems to always be set to a button (even if 
  // I try to set initialSelectionValue). This is different from what the 
  // javadocs state (which should switch this reference to the input component 
  // if one is present since that is what's going to get focus). 

  /**
   * The button that will receive focus based on initialValue when no input
   * component is present. If an input component is present, then the input
   * component will receive focus instead.
   */
  protected Component initialFocusComponent;

  /** The component that receives input when the JOptionPane needs it. */
  protected JComponent inputComponent;

  /** The minimum height of the JOptionPane. */
  public static int minimumHeight;

  /** The minimum width of the JOptionPane. */
  public static int minimumWidth;

  /** The minimum dimensions of the JOptionPane. */
  protected Dimension minimumSize;

  /** The propertyChangeListener for the JOptionPane. */
  protected PropertyChangeListener propertyChangeListener;

  /** The JOptionPane this UI delegate is used for. */
  protected JOptionPane optionPane;

  /** The size of the icons. */
  private static int iconSize = 36;

  /** The foreground color for the message area. */
  private transient Color messageForeground;

  /** The border around the message area. */
  private transient Border messageBorder;

  /** The border around the button area. */
  private transient Border buttonBorder;

  /** The string used to describe OK buttons. */
  private static String OK_STRING = "OK";

  /** The string used to describe Yes buttons. */
  private static String YES_STRING = "Yes";

  /** The string used to describe No buttons. */
  private static String NO_STRING = "No";

  /** The string used to describe Cancel buttons. */
  private static String CANCEL_STRING = "Cancel";

  /** The container for the message area. */
  private transient Container messageAreaContainer;

  /** The container for the buttons. */
  private transient Container buttonContainer;

  /**
   * A helper class that implements Icon. This is used temporarily until
   * ImageIcons are fixed.
   */
  private static class MessageIcon implements Icon
  {
    /**
     * This method returns the width of the icon.
     *
     * @return The width of the icon.
     */
    public int getIconWidth()
    {
      return iconSize;
    }

    /**
     * This method returns the height of the icon.
     *
     * @return The height of the icon.
     */
    public int getIconHeight()
    {
      return iconSize;
    }

    /**
     * This method paints the icon as a part of the given component using the
     * given graphics and the given x and y position.
     *
     * @param c The component that owns this icon.
     * @param g The Graphics object to paint with.
     * @param x The x coordinate.
     * @param y The y coordinate.
     */
    public void paintIcon(Component c, Graphics g, int x, int y)
    {
    }
  }

  /** The icon displayed for ERROR_MESSAGE. */
  private static MessageIcon errorIcon = new MessageIcon()
    {
      public void paintIcon(Component c, Graphics g, int x, int y)
      {
	Polygon oct = new Polygon(new int[] { 0, 0, 9, 27, 36, 36, 27, 9 },
	                          new int[] { 9, 27, 36, 36, 27, 9, 0, 0 }, 8);
	g.translate(x, y);

	Color saved = g.getColor();
	g.setColor(Color.RED);

	g.fillPolygon(oct);

	g.setColor(Color.BLACK);
	g.drawRect(13, 16, 10, 4);

	g.setColor(saved);
	g.translate(-x, -y);
      }
    };

  /** The icon displayed for INFORMATION_MESSAGE. */
  private static MessageIcon infoIcon = new MessageIcon()
    {
      public void paintIcon(Component c, Graphics g, int x, int y)
      {
	g.translate(x, y);
	Color saved = g.getColor();

	// Should be purple.
	g.setColor(Color.RED);

	g.fillOval(0, 0, iconSize, iconSize);

	g.setColor(Color.BLACK);
	g.drawOval(16, 6, 4, 4);

	Polygon bottomI = new Polygon(new int[] { 15, 15, 13, 13, 23, 23, 21, 21 },
	                              new int[] { 12, 28, 28, 30, 30, 28, 28, 12 },
	                              8);
	g.drawPolygon(bottomI);

	g.setColor(saved);
	g.translate(-x, -y);
      }
    };

  /** The icon displayed for WARNING_MESSAGE. */
  private static MessageIcon warningIcon = new MessageIcon()
    {
      public void paintIcon(Component c, Graphics g, int x, int y)
      {
	g.translate(x, y);
	Color saved = g.getColor();
	g.setColor(Color.YELLOW);

	Polygon triangle = new Polygon(new int[] { 0, 18, 36 },
	                               new int[] { 36, 0, 36 }, 3);
	g.fillPolygon(triangle);

	g.setColor(Color.BLACK);

	Polygon excl = new Polygon(new int[] { 15, 16, 20, 21 },
	                           new int[] { 8, 26, 26, 8 }, 4);
	g.drawPolygon(excl);
	g.drawOval(16, 30, 4, 4);

	g.setColor(saved);
	g.translate(-x, -y);
      }
    };

  /** The icon displayed for MESSAGE_ICON. */
  private static MessageIcon questionIcon = new MessageIcon()
    {
      public void paintIcon(Component c, Graphics g, int x, int y)
      {
	g.translate(x, y);
	Color saved = g.getColor();
	g.setColor(Color.GREEN);

	g.fillRect(0, 0, iconSize, iconSize);

	g.setColor(Color.BLACK);

	g.drawOval(11, 2, 16, 16);
	g.drawOval(14, 5, 10, 10);

	g.setColor(Color.GREEN);
	g.fillRect(0, 10, iconSize, iconSize - 10);

	g.setColor(Color.BLACK);

	g.drawLine(11, 10, 14, 10);

	g.drawLine(24, 10, 17, 22);
	g.drawLine(27, 10, 20, 22);
	g.drawLine(17, 22, 20, 22);

	g.drawOval(17, 25, 3, 3);

	g.setColor(saved);
	g.translate(-x, -y);
      }
    };

  // FIXME: Uncomment when the ImageIcons are fixed.

  /*  IconUIResource warningIcon, questionIcon, infoIcon, errorIcon;*/

  /**
   * Creates a new BasicOptionPaneUI object.
   */
  public BasicOptionPaneUI()
  {
  }

  /**
   * This method is messaged to add the buttons to the given container.
   *
   * @param container The container to add components to.
   * @param buttons The buttons to add. (If it is an instance of component,
   *        the Object is added directly. If it is an instance of Icon, it is
   *        packed into a label and added. For all other cases, the string
   *        representation of the Object is retreived and packed into a
   *        label.)
   * @param initialIndex The index of the component that is the initialValue.
   */
  protected void addButtonComponents(Container container, Object[] buttons,
                                     int initialIndex)
  {
    if (buttons == null)
      return;
    for (int i = 0; i < buttons.length; i++)
      {
	if (buttons[i] != null)
	  {
	    Component toAdd;
	    if (buttons[i] instanceof Component)
	      toAdd = (Component) buttons[i];
	    else
	      {
		if (buttons[i] instanceof Icon)
		  toAdd = new JButton((Icon) buttons[i]);
		else
		  toAdd = new JButton(buttons[i].toString());
		hasCustomComponents = true;
	      }
	    if (toAdd instanceof JButton)
	      ((JButton) toAdd).addActionListener(createButtonActionListener(i));
	    if (i == initialIndex)
	      initialFocusComponent = toAdd;
	    container.add(toAdd);
	  }
      }
    selectInitialValue(optionPane);
  }

  /**
   * This method adds the appropriate icon the given container.
   *
   * @param top The container to add an icon to.
   */
  protected void addIcon(Container top)
  {
    JLabel iconLabel = null;
    Icon icon = getIcon();
    if (icon != null)
      {
	iconLabel = new JLabel(icon);
	top.add(iconLabel, BorderLayout.WEST);
      }
  }

  /**
   * A helper method that returns an instance of GridBagConstraints to be used
   * for creating the message area.
   *
   * @return An instance of GridBagConstraints.
   */
  private static GridBagConstraints createConstraints()
  {
    GridBagConstraints constraints = new GridBagConstraints();
    constraints.gridx = GridBagConstraints.REMAINDER;
    constraints.gridy = GridBagConstraints.REMAINDER;
    constraints.gridwidth = 0;
    constraints.anchor = GridBagConstraints.LINE_START;
    constraints.fill = GridBagConstraints.NONE;
    constraints.insets = new Insets(0, 0, 3, 0);

    return constraints;
  }

  /**
   * This method creates the proper object (if necessary) to represent msg.
   * (If msg is an instance of Component, it will add it directly. If it is
   * an icon, then it will pack it in a label and add it. Otherwise, it gets
   * treated as a string. If the string is longer than maxll, a box is
   * created and the burstStringInto is called with the box as the container.
   * The box is then added to the given container. Otherwise, the string is
   * packed in a label and placed in the given container.) This method is
   * also used for adding the inputComponent to the container.
   *
   * @param container The container to add to.
   * @param cons The constraints when adding.
   * @param msg The message to add.
   * @param maxll The max line length.
   * @param internallyCreated Whether the msg is internally created.
   */
  protected void addMessageComponents(Container container,
                                      GridBagConstraints cons, Object msg,
                                      int maxll, boolean internallyCreated)
  {
    if (msg == null)
      return;
    hasCustomComponents = internallyCreated;
    if (msg instanceof Object[])
      {
	Object[] arr = (Object[]) msg;
	for (int i = 0; i < arr.length; i++)
	  addMessageComponents(container, cons, arr[i], maxll,
	                       internallyCreated);
	return;
      }
    else if (msg instanceof Component)
      {
	container.add((Component) msg, cons);
	cons.gridy++;
      }
    else if (msg instanceof Icon)
      {
	container.add(new JLabel((Icon) msg), cons);
	cons.gridy++;
      }
    else
      {
	// Undocumented behaviour.
	// if msg.toString().length greater than maxll
	// it will create a box and burst the string.
	// otherwise, it will just create a label and re-call 
	// this method with the label o.O
	if (msg.toString().length() > maxll)
	  {
	    Box tmp = new Box(BoxLayout.Y_AXIS);
	    burstStringInto(tmp, msg.toString(), maxll);
	    addMessageComponents(container, cons, tmp, maxll, true);
	  }
	else
	  addMessageComponents(container, cons, new JLabel(msg.toString()),
	                       maxll, true);
      }
  }

  /**
   * This method creates instances of d (recursively if necessary based on
   * maxll) and adds to c.
   *
   * @param c The container to add to.
   * @param d The string to burst.
   * @param maxll The max line length.
   */
  protected void burstStringInto(Container c, String d, int maxll)
  {
    // FIXME: Verify that this is the correct behaviour.
    // One interpretation of the spec is that this method
    // should recursively call itself to create (and add) 
    // JLabels to the container if the length of the String d
    // is greater than maxll.
    // but in practice, even with a really long string, this is 
    // all that happens.
    if (d == null || c == null)
      return;
    JLabel label = new JLabel(d);
    c.add(label);
  }

  /**
   * This method returns true if the given JOptionPane contains custom
   * components.
   *
   * @param op The JOptionPane to check.
   *
   * @return True if the JOptionPane contains custom components.
   */
  public boolean containsCustomComponents(JOptionPane op)
  {
    return hasCustomComponents;
  }

  /**
   * This method creates a button action listener for the given button index.
   *
   * @param buttonIndex The index of the button in components.
   *
   * @return A new ButtonActionListener.
   */
  protected ActionListener createButtonActionListener(int buttonIndex)
  {
    return new ButtonActionListener(buttonIndex);
  }

  /**
   * This method creates the button area.
   *
   * @return A new Button Area.
   */
  protected Container createButtonArea()
  {
    JPanel buttonPanel = new JPanel();

    buttonPanel.setLayout(createLayoutManager());
    addButtonComponents(buttonPanel, getButtons(), getInitialValueIndex());

    return buttonPanel;
  }

  /**
   * This method creates a new LayoutManager for the button area.
   *
   * @return A new LayoutManager for the button area.
   */
  protected LayoutManager createLayoutManager()
  {
    return new ButtonAreaLayout(getSizeButtonsToSameWidth(), 6);
  }

  /**
   * This method creates the message area.
   *
   * @return A new message area.
   */
  protected Container createMessageArea()
  {
    JPanel messageArea = new JPanel();
    messageArea.setLayout(new BorderLayout());
    addIcon(messageArea);

    JPanel rightSide = new JPanel()
      {
	public Dimension getPreferredSize()
	{
	  int w = Math.max(optionPane.getSize().width, minimumWidth);
	  Insets i = optionPane.getInsets();
	  Dimension orig = super.getPreferredSize();
	  Dimension value = new Dimension(w - i.left - i.right - iconSize,
	                                  orig.height);
	  return value;
	}
      };
    rightSide.setLayout(new GridBagLayout());
    GridBagConstraints con = createConstraints();

    addMessageComponents(rightSide, con, getMessage(),
                         getMaxCharactersPerLineCount(), false);

    if (optionPane.getWantsInput())
      {
	Object[] selection = optionPane.getSelectionValues();

//	if (selection == null)
//	  inputComponent = new JTextField();
//	else if (selection.length < 20)
//	  inputComponent = new JComboBox(selection);
	// FIXME: Uncomment when the widgets are done.
	if (selection == null)
	  inputComponent = null;
	else
	  inputComponent = new JList(selection);
	if (inputComponent != null)
	  {
	    addMessageComponents(rightSide, con, inputComponent,
	                         getMaxCharactersPerLineCount(), true);
	    resetSelectedValue();
	    selectInitialValue(optionPane);
	  }
      }

    messageArea.add(rightSide, BorderLayout.EAST);

    return messageArea;
  }

  /**
   * This method creates a new PropertyChangeListener for listening to the
   * JOptionPane.
   *
   * @return A new PropertyChangeListener.
   */
  protected PropertyChangeListener createPropertyChangeListener()
  {
    return new PropertyChangeHandler();
  }

  /**
   * This method creates a Container that will separate the message and button
   * areas.
   *
   * @return A Container that will separate the message and button areas.
   */
  protected Container createSeparator()
  {
    return null;
  }

  /**
   * This method creates a new BasicOptionPaneUI for the given component.
   *
   * @param x The component to create a UI for.
   *
   * @return A new BasicOptionPaneUI.
   */
  public static ComponentUI createUI(JComponent x)
  {
    return new BasicOptionPaneUI();
  }

  /**
   * This method returns the buttons for the JOptionPane. If no options are
   * set, a set of options will be created based upon the optionType.
   *
   * @return The buttons that will be added.
   */
  protected Object[] getButtons()
  {
    if (optionPane.getOptions() != null)
      return optionPane.getOptions();
    switch (optionPane.getOptionType())
      {
      case JOptionPane.YES_NO_OPTION:
	return new Object[] { YES_STRING, NO_STRING };
      case JOptionPane.YES_NO_CANCEL_OPTION:
	return new Object[] { YES_STRING, NO_STRING, CANCEL_STRING };
      case JOptionPane.OK_CANCEL_OPTION:
      case JOptionPane.DEFAULT_OPTION:
	return new Object[] { OK_STRING, CANCEL_STRING };
      }
    return null;
  }

  /**
   * This method will return the icon the user has set or the icon that will
   * be used based on message type.
   *
   * @return The icon to use in the JOptionPane.
   */
  protected Icon getIcon()
  {
    if (optionPane.getIcon() != null)
      return optionPane.getIcon();
    else
      return getIconForType(optionPane.getMessageType());
  }

  /**
   * This method returns the icon for the given messageType.
   *
   * @param messageType The type of message.
   *
   * @return The icon for the given messageType.
   */
  protected Icon getIconForType(int messageType)
  {
    Icon tmp = null;
    switch (messageType)
      {
      case JOptionPane.ERROR_MESSAGE:
	tmp = errorIcon;
	break;
      case JOptionPane.INFORMATION_MESSAGE:
	tmp = infoIcon;
	break;
      case JOptionPane.WARNING_MESSAGE:
	tmp = warningIcon;
	break;
      case JOptionPane.QUESTION_MESSAGE:
	tmp = questionIcon;
	break;
      }
    return tmp;
    // FIXME: Don't cast till the default icons are in.
    // return new IconUIResource(tmp);
  }

  /**
   * This method returns the index of the initialValue in the options array.
   *
   * @return The index of the initalValue.
   */
  protected int getInitialValueIndex()
  {
    Object[] buttons = getButtons();

    if (buttons == null)
      return -1;

    Object select = optionPane.getInitialValue();

    for (int i = 0; i < buttons.length; i++)
      {
	if (select == buttons[i])
	  return i;
      }
    return 0;
  }

  /**
   * This method returns the maximum number of characters that should be
   * placed on a line.
   *
   * @return The maximum number of characteres that should be placed on a
   *         line.
   */
  protected int getMaxCharactersPerLineCount()
  {
    return optionPane.getMaxCharactersPerLineCount();
  }

  /**
   * This method returns the maximum size.
   *
   * @param c The JComponent to measure.
   *
   * @return The maximum size.
   */
  public Dimension getMaximumSize(JComponent c)
  {
    return getPreferredSize(c);
  }

  /**
   * This method returns the message of the JOptionPane.
   *
   * @return The message.
   */
  protected Object getMessage()
  {
    return optionPane.getMessage();
  }

  /**
   * This method returns the minimum size of the JOptionPane.
   *
   * @return The minimum size.
   */
  public Dimension getMinimumOptionPaneSize()
  {
    return minimumSize;
  }

  /**
   * This method returns the minimum size.
   *
   * @param c The JComponent to measure.
   *
   * @return The minimum size.
   */
  public Dimension getMinimumSize(JComponent c)
  {
    return getPreferredSize(c);
  }

  /**
   * This method returns the preferred size of the JOptionPane. The preferred
   * size is the maximum of the size desired by the layout and the minimum
   * size.
   *
   * @param c The JComponent to measure.
   *
   * @return The preferred size.
   */
  public Dimension getPreferredSize(JComponent c)
  {
    Dimension d = optionPane.getLayout().preferredLayoutSize(optionPane);
    Dimension d2 = getMinimumOptionPaneSize();

    int w = Math.max(d.width, d2.width);
    int h = Math.max(d.height, d2.height);
    return new Dimension(w, h);
  }

  /**
   * This method returns whether all buttons should have the same width.
   *
   * @return Whether all buttons should have the same width.
   */
  protected boolean getSizeButtonsToSameWidth()
  {
    return true;
  }

  /**
   * This method installs components for the JOptionPane.
   */
  protected void installComponents()
  {
    // reset it.
    hasCustomComponents = false;
    Container msg = createMessageArea();
    if (msg != null)
      {
	((JComponent) msg).setBorder(messageBorder);
	msg.setForeground(messageForeground);
	messageAreaContainer = msg;
	optionPane.add(msg);
      }

    Container sep = createSeparator();
    if (sep != null)
      optionPane.add(sep);

    Container button = createButtonArea();
    if (button != null)
      {
	((JComponent) button).setBorder(buttonBorder);
	buttonContainer = button;
	optionPane.add(button);
      }

    optionPane.invalidate();
  }

  /**
   * This method installs defaults for the JOptionPane.
   */
  protected void installDefaults()
  {
    UIDefaults defaults = UIManager.getLookAndFeelDefaults();

    optionPane.setFont(defaults.getFont("OptionPane.font"));
    optionPane.setBackground(defaults.getColor("OptionPane.background"));
    optionPane.setForeground(defaults.getColor("OptionPane.foreground"));
    optionPane.setBorder(defaults.getBorder("OptionPane.border"));

    messageBorder = defaults.getBorder("OptionPane.messageAreaBorder");
    messageForeground = defaults.getColor("OptionPane.messageForeground");
    buttonBorder = defaults.getBorder("OptionPane.buttonAreaBorder");

    minimumSize = defaults.getDimension("OptionPane.minimumSize");
    minimumWidth = minimumSize.width;
    minimumHeight = minimumSize.height;

    // FIXME: Image icons don't seem to work properly right now.
    // Once they do, replace the synthetic icons with these ones.

    /*
    warningIcon = (IconUIResource) defaults.getIcon("OptionPane.warningIcon");
    infoIcon = (IconUIResource) defaults.getIcon("OptionPane.informationIcon");
    errorIcon = (IconUIResource) defaults.getIcon("OptionPane.errorIcon");
    questionIcon = (IconUIResource) defaults.getIcon("OptionPane.questionIcon");
    */
  }

  /**
   * This method installs keyboard actions for the JOptionpane.
   */
  protected void installKeyboardActions()
  {
    // FIXME: implement.
  }

  /**
   * This method installs listeners for the JOptionPane.
   */
  protected void installListeners()
  {
    propertyChangeListener = createPropertyChangeListener();

    optionPane.addPropertyChangeListener(propertyChangeListener);
  }

  /**
   * This method installs the UI for the JOptionPane.
   *
   * @param c The JComponent to install the UI for.
   */
  public void installUI(JComponent c)
  {
    if (c instanceof JOptionPane)
      {
	optionPane = (JOptionPane) c;

	installDefaults();
	installComponents();
	installListeners();
	installKeyboardActions();
      }
  }

  /**
   * Changes the inputValue property in the JOptionPane based on the current
   * value of the inputComponent.
   */
  protected void resetInputValue()
  {
    if (optionPane.getWantsInput() && inputComponent != null)
      {
	Object output = null;
	if (inputComponent instanceof JTextField)
	  output = ((JTextField) inputComponent).getText();
	else if (inputComponent instanceof JComboBox)
	  output = ((JComboBox) inputComponent).getSelectedItem();
	else if (inputComponent instanceof JList)
	  output = ((JList) inputComponent).getSelectedValue();

	if (output != null)
	  optionPane.setInputValue(output);
      }
  }

  /**
   * This method requests focus to the inputComponent (if one is present) and
   * the initialFocusComponent otherwise.
   *
   * @param op The JOptionPane.
   */
  public void selectInitialValue(JOptionPane op)
  {
    if (inputComponent != null)
      {
	inputComponent.requestFocus();
	return;
      }
    if (initialFocusComponent != null)
      initialFocusComponent.requestFocus();
  }

  /**
   * This method resets the value in the inputComponent to the
   * initialSelectionValue property.
   */
  private void resetSelectedValue()
  {
    if (inputComponent != null)
      {
	Object init = optionPane.getInitialSelectionValue();
	if (init == null)
	  return;
	if (inputComponent instanceof JTextField)
	  ((JTextField) inputComponent).setText((String) init);
	else if (inputComponent instanceof JComboBox)
	  ((JComboBox) inputComponent).setSelectedItem(init);
	else if (inputComponent instanceof JList)
	  {
	    //  ((JList) inputComponent).setSelectedValue(init, true);
	  }
      }
  }

  /**
   * This method uninstalls all the components in the JOptionPane.
   */
  protected void uninstallComponents()
  {
    optionPane.removeAll();
    buttonContainer = null;
    messageAreaContainer = null;
  }

  /**
   * This method uninstalls the defaults for the JOptionPane.
   */
  protected void uninstallDefaults()
  {
    optionPane.setFont(null);
    optionPane.setForeground(null);
    optionPane.setBackground(null);

    minimumSize = null;

    messageBorder = null;
    buttonBorder = null;
    messageForeground = null;

    // FIXME: ImageIcons don't seem to work properly

    /*
    warningIcon = null;
    errorIcon = null;
    questionIcon = null;
    infoIcon = null;
    */
  }

  /**
   * This method uninstalls keyboard actions for the JOptionPane.
   */
  protected void uninstallKeyboardActions()
  {
    // FIXME: implement.
  }

  /**
   * This method uninstalls listeners for the JOptionPane.
   */
  protected void uninstallListeners()
  {
    optionPane.removePropertyChangeListener(propertyChangeListener);
    propertyChangeListener = null;
  }

  /**
   * This method uninstalls the UI for the given JComponent.
   *
   * @param c The JComponent to uninstall for.
   */
  public void uninstallUI(JComponent c)
  {
    uninstallKeyboardActions();
    uninstallListeners();
    uninstallComponents();
    uninstallDefaults();

    optionPane = null;
  }
}
