/* BasicMenuItemUI.java --
   Copyright (C) 2002, 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.plaf.basic;

import gnu.classpath.SystemProperties;

import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;

import javax.swing.AbstractAction;
import javax.swing.AbstractButton;
import javax.swing.ActionMap;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIDefaults;
import javax.swing.UIManager;
import javax.swing.event.MenuDragMouseEvent;
import javax.swing.event.MenuDragMouseListener;
import javax.swing.event.MenuKeyEvent;
import javax.swing.event.MenuKeyListener;
import javax.swing.event.MouseInputListener;
import javax.swing.plaf.ActionMapUIResource;
import javax.swing.plaf.ComponentInputMapUIResource;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.MenuItemUI;
import javax.swing.text.View;

/**
 * UI Delegate for JMenuItem.
 */
public class BasicMenuItemUI extends MenuItemUI
{
  /**
   * Font to be used when displaying menu item's accelerator.
   */
  protected Font acceleratorFont;

  /**
   * Color to be used when displaying menu item's accelerator.
   */
  protected Color acceleratorForeground;

  /**
   * Color to be used when displaying menu item's accelerator when menu item is
   * selected.
   */
  protected Color acceleratorSelectionForeground;

  /**
   * Icon that is displayed after the text to indicated that this menu contains
   * submenu.
   */
  protected Icon arrowIcon;

  /**
   * Icon that is displayed before the text. This icon is only used in
   * JCheckBoxMenuItem or JRadioBoxMenuItem.
   */
  protected Icon checkIcon;

  /**
   * Number of spaces between icon and text.
   */
  protected int defaultTextIconGap = 4;
  
  /**
   * Color of the text when menu item is disabled
   */
  protected Color disabledForeground;

  /**
   * The menu Drag mouse listener listening to the menu item.
   */
  protected MenuDragMouseListener menuDragMouseListener;

  /**
   * The menu item itself
   */
  protected JMenuItem menuItem;

  /**
   * Menu Key listener listening to the menu item.
   */
  protected MenuKeyListener menuKeyListener;

  /**
   * mouse input listener listening to menu item.
   */
  protected MouseInputListener mouseInputListener;

  /**
   * Indicates if border should be painted
   */
  protected boolean oldBorderPainted;

  /**
   * Color of text that is used when menu item is selected
   */
  protected Color selectionBackground;

  /**
   * Color of the text that is used when menu item is selected.
   */
  protected Color selectionForeground;

  /**
   * String that separates description of the modifiers and the key
   */
  private String acceleratorDelimiter;

  /**
   * ItemListener to listen for item changes in the menu item
   */
  private ItemListener itemListener;

  /**
   * Number of spaces between accelerator and menu item's label.
   */
  private int defaultAcceleratorLabelGap = 10;

  /**
   * The gap between different menus on the MenuBar.
   */
  private int MenuGap = 10;
  
  /** A PropertyChangeListener to make UI updates after property changes **/
  PropertyChangeHandler propertyChangeListener;

  /**
   * The view rectangle used for layout of the menu item.
   */
  private Rectangle viewRect;

  /**
   * The rectangle that holds the area of the label.
   */
  private Rectangle textRect;

  /**
   * The rectangle that holds the area of the accelerator.
   */
  private Rectangle accelRect;

  /**
   * The rectangle that holds the area of the icon.
   */
  private Rectangle iconRect;

  /**
   * The rectangle that holds the area of the icon.
   */
  private Rectangle arrowIconRect;

  /**
   * The rectangle that holds the area of the check icon.
   */
  private Rectangle checkIconRect;

  /**
   * A rectangle used for temporary storage to avoid creation of new
   * rectangles.
   */
  private Rectangle cachedRect;

  /**
   * A class to handle PropertChangeEvents for the JMenuItem
   * @author Anthony Balkissoon abalkiss at redhat dot com.   
   */
  class PropertyChangeHandler implements PropertyChangeListener
  {
    /**
     * This method is called when a property of the menuItem is changed.
     * Currently it is only used to update the accelerator key bindings.
     * 
     * @param e
     *          the PropertyChangeEvent
     */
    public void propertyChange(PropertyChangeEvent e)
    {
      String property = e.getPropertyName();
      if (property.equals("accelerator"))
        {
          InputMap map = SwingUtilities.getUIInputMap(menuItem, 
              JComponent.WHEN_IN_FOCUSED_WINDOW);
          if (map != null)
            map.remove((KeyStroke) e.getOldValue());
          else
            map = new ComponentInputMapUIResource(menuItem);

          KeyStroke accelerator = (KeyStroke) e.getNewValue();
          if (accelerator != null)
            map.put(accelerator, "doClick");
        }
      // TextLayout caching for speed-up drawing of text.
      else if ((property.equals(AbstractButton.TEXT_CHANGED_PROPERTY)
                || property.equals("font"))
               && SystemProperties.getProperty("gnu.javax.swing.noGraphics2D")
               == null)
               
        {
          AbstractButton b = (AbstractButton) e.getSource();
          String text = b.getText();
          if (text == null)
            text = "";
          FontRenderContext frc = new FontRenderContext(new AffineTransform(),
                                                        false, false);
          TextLayout layout = new TextLayout(text, b.getFont(), frc);
          b.putClientProperty(BasicGraphicsUtils.CACHED_TEXT_LAYOUT, layout);
        }
    }
  }
  
  /**
   * A class to handle accelerator keys.  This is the Action we will
   * perform when the accelerator key for this JMenuItem is pressed.
   * @author Anthony Balkissoon abalkiss at redhat dot com
   *
   */
  class ClickAction extends AbstractAction
  {
    /**
     * This is what is done when the accelerator key for the JMenuItem is
     * pressed.
     */
    public void actionPerformed(ActionEvent event)
    {
      doClick(MenuSelectionManager.defaultManager());
    }    
  }
  
  /**
   * Creates a new BasicMenuItemUI object.
   */
  public BasicMenuItemUI()
  {
    mouseInputListener = createMouseInputListener(menuItem);
    menuDragMouseListener = createMenuDragMouseListener(menuItem);
    menuKeyListener = createMenuKeyListener(menuItem);
    itemListener = new ItemHandler();
    propertyChangeListener = new PropertyChangeHandler();

    // Initialize rectangles for layout.
    viewRect = new Rectangle();
    textRect = new Rectangle();
    iconRect = new Rectangle();
    arrowIconRect = new Rectangle();
    checkIconRect = new Rectangle();
    accelRect = new Rectangle();
    cachedRect = new Rectangle();
  }

  /**
   * Create MenuDragMouseListener to listen for mouse dragged events.
   * 
   * @param c
   *          menu item to listen to
   * @return The MenuDragMouseListener
   */
  protected MenuDragMouseListener createMenuDragMouseListener(JComponent c)
  {
    return new MenuDragMouseHandler();
  }

  /**
   * Creates MenuKeyListener to listen to key events occuring when menu item is
   * visible on the screen.
   * 
   * @param c
   *          menu item to listen to
   * @return The MenuKeyListener
   */
  protected MenuKeyListener createMenuKeyListener(JComponent c)
  {
    return new MenuKeyHandler();
  }

  /**
   * Handles mouse input events occuring for this menu item
   * 
   * @param c
   *          menu item to listen to
   * @return The MouseInputListener
   */
  protected MouseInputListener createMouseInputListener(JComponent c)
  {
    return new MouseInputHandler();
  }

  /**
   * Factory method to create a BasicMenuItemUI for the given {@link
   * JComponent}, which should be a {@link JMenuItem}.
   * 
   * @param c
   *          The {@link JComponent} a UI is being created for.
   * @return A BasicMenuItemUI for the {@link JComponent}.
   */
  public static ComponentUI createUI(JComponent c)
  {
    return new BasicMenuItemUI();
  }

  /**
   * Programatically clicks menu item.
   * 
   * @param msm
   *          MenuSelectionManager for the menu hierarchy
   */
  protected void doClick(MenuSelectionManager msm)
  {
    menuItem.doClick();
    msm.clearSelectedPath();
  }

  /**
   * Returns maximum size for the specified menu item
   * 
   * @param c
   *          component for which to get maximum size
   * @return Maximum size for the specified menu item.
   */
  public Dimension getMaximumSize(JComponent c)
  {
    return null;
  }

  /**
   * Returns minimum size for the specified menu item
   * 
   * @param c
   *          component for which to get minimum size
   * @return Minimum size for the specified menu item.
   */
  public Dimension getMinimumSize(JComponent c)
  {
    return null;
  }

  /**
   * Returns path to this menu item.
   * 
   * @return $MenuElement[]$ Returns array of menu elements that constitute a
   *         path to this menu item.
   */
  public MenuElement[] getPath()
  {
    ArrayList path = new ArrayList();

    // Path to menu should also include its popup menu.
    if (menuItem instanceof JMenu)
      path.add(((JMenu) menuItem).getPopupMenu());

    Component c = menuItem;
    while (c instanceof MenuElement)
      {
        path.add(0, (MenuElement) c);

        if (c instanceof JPopupMenu)
          c = ((JPopupMenu) c).getInvoker();
        else
          c = c.getParent();
      }

    MenuElement[] pathArray = new MenuElement[path.size()];
    path.toArray(pathArray);
    return pathArray;
  }

  /**
   * Returns preferred size for the given menu item.
   * 
   * @param c
   *          menu item for which to get preferred size
   * @param checkIcon
   *          check icon displayed in the given menu item
   * @param arrowIcon
   *          arrow icon displayed in the given menu item
   * @param defaultTextIconGap
   *          space between icon and text in the given menuItem
   * @return $Dimension$ preferred size for the given menu item
   */
  protected Dimension getPreferredMenuItemSize(JComponent c, Icon checkIcon,
                                               Icon arrowIcon,
                                               int defaultTextIconGap)
  {
    JMenuItem m = (JMenuItem) c;
    String accelText = getAcceleratorString(m);

    // Layout the menu item. The result gets stored in the rectangle
    // fields of this class.
    layoutMenuItem(m, accelText);

    // The union of the text and icon areas is the label area.
    cachedRect.setBounds(textRect);
    Rectangle pref = SwingUtilities.computeUnion(iconRect.x, iconRect.y,
                                                 iconRect.width,
                                                 iconRect.height,
                                                 cachedRect);

    // Find the widest menu item text and accelerator and store it in
    // client properties of the parent, so that we can align the accelerators
    // properly. Of course, we only need can do this, if the parent is
    // a JComponent and this menu item is not a toplevel menu.
    Container parent = m.getParent();
    if (parent != null && parent instanceof JComponent
        && !(m instanceof JMenu && ((JMenu) m).isTopLevelMenu()))
      {
        JComponent p = (JComponent) parent;

        // The widest text so far.
        Integer maxTextWidth = (Integer) p.getClientProperty("maxTextWidth");
        int maxTextValue = maxTextWidth == null ? 0 : maxTextWidth.intValue();
        if (pref.width < maxTextValue)
          pref.width = maxTextValue;
        else
          p.putClientProperty("maxTextWidth", new Integer(pref.width));

        // The widest accelerator so far.
        Integer maxAccelWidth = (Integer) p.getClientProperty("maxAccelWidth");
        int maxAccelValue = maxAccelWidth == null ? 0
                                                  : maxAccelWidth.intValue();
        if (accelRect.width > maxAccelValue)
          {
            maxAccelValue = accelRect.width;
            p.putClientProperty("maxAccelWidth", new Integer(accelRect.width));
          }
        pref.width += maxAccelValue;
        pref.width += defaultTextIconGap;
      }

    // Add arrow and check size if appropriate.
    if (! (m instanceof JMenu && ((JMenu) m).isTopLevelMenu()))
      {
        pref.width += checkIconRect.width;
        pref.width += defaultTextIconGap;
        pref.width += arrowIconRect.width;
        pref.width += defaultTextIconGap;
      }

    // Add a gap ~2 times as wide as the defaultTextIconGap.
    pref.width += 2 * defaultTextIconGap;

    // Respect the insets of the menu item.
    Insets i = m.getInsets();
    pref.width += i.left + i.right;
    pref.height += i.top + i.bottom;

    // Return a copy, so that nobody messes with our textRect.
    return pref.getSize();
  }

  /**
   * Returns preferred size of the given component
   * 
   * @param c
   *          component for which to return preferred size
   * @return $Dimension$ preferred size for the given component
   */
  public Dimension getPreferredSize(JComponent c)
  {
    return getPreferredMenuItemSize(c, checkIcon, arrowIcon, 
                                    defaultTextIconGap);
  }

  /**
   * Returns the prefix for entries in the {@link UIDefaults} table.
   * 
   * @return "MenuItem"
   */
  protected String getPropertyPrefix()
  {
    return "MenuItem";
  }

  /**
   * This method installs the components for this {@link JMenuItem}.
   * 
   * @param menuItem
   *          The {@link JMenuItem} to install components for.
   */
  protected void installComponents(JMenuItem menuItem)
  {
    // FIXME: Need to implement
  }

  /**
   * This method installs the defaults that are defined in the Basic look and
   * feel for this {@link JMenuItem}.
   */
  protected void installDefaults()
  {
    String prefix = getPropertyPrefix();
    LookAndFeel.installBorder(menuItem, prefix + ".border");
    LookAndFeel.installColorsAndFont(menuItem, prefix + ".background",
                                     prefix + ".foreground", prefix + ".font");
    menuItem.setMargin(UIManager.getInsets(prefix + ".margin"));
    acceleratorFont = UIManager.getFont(prefix + ".acceleratorFont");
    acceleratorForeground = UIManager.getColor(prefix 
        + ".acceleratorForeground");
    acceleratorSelectionForeground = UIManager.getColor(prefix 
        + ".acceleratorSelectionForeground");
    selectionBackground = UIManager.getColor(prefix + ".selectionBackground");
    selectionForeground = UIManager.getColor(prefix + ".selectionForeground");
    acceleratorDelimiter = UIManager.getString(prefix + ".acceleratorDelimiter");
    checkIcon = UIManager.getIcon(prefix + ".checkIcon");
    
    menuItem.setHorizontalTextPosition(SwingConstants.TRAILING);
    menuItem.setHorizontalAlignment(SwingConstants.LEADING);
  }

  /**
   * This method installs the keyboard actions for this {@link JMenuItem}.
   */
  protected void installKeyboardActions()
  {
    InputMap focusedWindowMap = SwingUtilities.getUIInputMap(menuItem, 
        JComponent.WHEN_IN_FOCUSED_WINDOW);
    if (focusedWindowMap == null)
      focusedWindowMap = new ComponentInputMapUIResource(menuItem);
    KeyStroke accelerator = menuItem.getAccelerator();
    if (accelerator != null)
      focusedWindowMap.put(accelerator, "doClick");
    SwingUtilities.replaceUIInputMap(menuItem, 
        JComponent.WHEN_IN_FOCUSED_WINDOW, focusedWindowMap);
    
    ActionMap UIActionMap = SwingUtilities.getUIActionMap(menuItem);
    if (UIActionMap == null)
      UIActionMap = new ActionMapUIResource();
    UIActionMap.put("doClick", new ClickAction());
    SwingUtilities.replaceUIActionMap(menuItem, UIActionMap);
  }

  /**
   * This method installs the listeners for the {@link JMenuItem}.
   */
  protected void installListeners()
  {
    menuItem.addMouseListener(mouseInputListener);
    menuItem.addMouseMotionListener(mouseInputListener);
    menuItem.addMenuDragMouseListener(menuDragMouseListener);
    menuItem.addMenuKeyListener(menuKeyListener);
    menuItem.addItemListener(itemListener);
    menuItem.addPropertyChangeListener(propertyChangeListener);
  }

  /**
   * Installs and initializes all fields for this UI delegate. Any properties of
   * the UI that need to be initialized and/or set to defaults will be done now.
   * It will also install any listeners necessary.
   * 
   * @param c
   *          The {@link JComponent} that is having this UI installed.
   */
  public void installUI(JComponent c)
  {
    super.installUI(c);
    menuItem = (JMenuItem) c;
    installDefaults();
    installComponents(menuItem);
    installListeners();
    installKeyboardActions();
  }

  /**
   * Paints given menu item using specified graphics context
   * 
   * @param g
   *          The graphics context used to paint this menu item
   * @param c
   *          Menu Item to paint
   */
  public void paint(Graphics g, JComponent c)
  {
    paintMenuItem(g, c, checkIcon, arrowIcon, selectionBackground,
                  c.getForeground(), defaultTextIconGap);
  }

  /**
   * Paints background of the menu item
   * 
   * @param g
   *          The graphics context used to paint this menu item
   * @param menuItem
   *          menu item to paint
   * @param bgColor
   *          Background color to use when painting menu item
   */
  protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor)
  {
    // Menu item is considered to be highlighted when it is selected.
    // But we don't want to paint the background of JCheckBoxMenuItems
    ButtonModel mod = menuItem.getModel();
    Color saved = g.getColor();
    if (mod.isArmed() || ((menuItem instanceof JMenu) && mod.isSelected()))
      {
        g.setColor(bgColor);
        g.fillRect(0, 0, menuItem.getWidth(), menuItem.getHeight());
      }
    else if (menuItem.isOpaque())
      {
        g.setColor(menuItem.getBackground());
        g.fillRect(0, 0, menuItem.getWidth(), menuItem.getHeight());
      }
    g.setColor(saved);
  }

  /**
   * Paints specified menu item
   * 
   * @param g
   *          The graphics context used to paint this menu item
   * @param c
   *          menu item to paint
   * @param checkIcon
   *          check icon to use when painting menu item
   * @param arrowIcon
   *          arrow icon to use when painting menu item
   * @param background
   *          Background color of the menu item
   * @param foreground
   *          Foreground color of the menu item
   * @param defaultTextIconGap
   *          space to use between icon and text when painting menu item
   */
  protected void paintMenuItem(Graphics g, JComponent c, Icon checkIcon,
                               Icon arrowIcon, Color background,
                               Color foreground, int defaultTextIconGap)
  {
    JMenuItem m = (JMenuItem) c;

    // Fetch fonts.
    Font oldFont = g.getFont();
    Font font = c.getFont();
    g.setFont(font);
    FontMetrics accelFm = m.getFontMetrics(acceleratorFont);

    // Create accelerator string.
    String accelText = getAcceleratorString(m);

    // Layout menu item. The result gets stored in the rectangle fields
    // of this class.
    layoutMenuItem(m, accelText);

    // Paint the background.
    paintBackground(g, m, background);

    Color oldColor = g.getColor();

    // Paint the check icon.
    if (checkIcon != null)
      {
        checkIcon.paintIcon(m, g, checkIconRect.x, checkIconRect.y);
      }

    // Paint the icon.
    ButtonModel model = m.getModel();
    if (m.getIcon() != null)
      {
        // Determine icon depending on the menu item
        // state (normal/disabled/pressed).
        Icon icon;
        if (! m.isEnabled())
          {
            icon = m.getDisabledIcon();
          }
        else if (model.isPressed() && model.isArmed())
          {
            icon = m.getPressedIcon();
            if (icon == null)
              {
                icon = m.getIcon();
              }
          }
        else
          {
            icon = m.getIcon();
          }

        if (icon != null)
          {
            icon.paintIcon(m, g, iconRect.x, iconRect.y);
          }
      }

    // Paint the text.
    String text = m.getText();
    if (text != null)
      {
        // Handle HTML.
        View html = (View) m.getClientProperty(BasicHTML.propertyKey);
        if (html != null)
          {
            html.paint(g, textRect);
          }
        else
          {
            paintText(g, m, textRect, text);
          }
      }

    // Paint accelerator text.
    if (! accelText.equals(""))
      {
        // Align the accelerator text. In getPreferredMenuItemSize() we
        // store a client property 'maxAccelWidth' in the parent which holds
        // the maximum accelerator width for the children of this parent.
        // We use this here to align the accelerators properly.
        int accelOffset = 0;
        Container parent = m.getParent();
        if (parent != null && parent instanceof JComponent)
          {
            JComponent p = (JComponent) parent;
            Integer maxAccelWidth =
              (Integer) p.getClientProperty("maxAccelWidth");
            int maxAccelValue = maxAccelWidth == null ? 0
                                                    : maxAccelWidth.intValue();
            accelOffset = maxAccelValue - accelRect.width;
          }

        g.setFont(acceleratorFont);
        if (! m.isEnabled())
          {
            // Paint accelerator disabled.
            g.setColor(disabledForeground);
          }
        else
          {
            if (m.isArmed() || (m instanceof JMenu && m.isSelected()))
              g.setColor(acceleratorSelectionForeground);
            else
              g.setColor(acceleratorForeground);
          }
        g.drawString(accelText, accelRect.x - accelOffset,
                     accelRect.y + accelFm.getAscent());
      }

    // Paint arrow.
    if (arrowIcon != null
        && ! (m instanceof JMenu && ((JMenu) m).isTopLevelMenu()))
      {
        arrowIcon.paintIcon(m, g, arrowIconRect.x, arrowIconRect.y);
      }

    g.setFont(oldFont);
    g.setColor(oldColor);

  }

  /**
   * Paints label for the given menu item
   * 
   * @param g
   *          The graphics context used to paint this menu item
   * @param menuItem
   *          menu item for which to draw its label
   * @param textRect
   *          rectangle specifiying position of the text relative to the given
   *          menu item
   * @param text
   *          label of the menu item
   */
  protected void paintText(Graphics g, JMenuItem menuItem, Rectangle textRect,
                           String text)
  {
    Font f = menuItem.getFont();
    g.setFont(f);
    FontMetrics fm = g.getFontMetrics(f);

    if (text != null && !text.equals(""))
      {
        if (menuItem.isEnabled())
          {
            // Menu item is considered to be highlighted when it is selected.
            // But not if it's a JCheckBoxMenuItem
            ButtonModel mod = menuItem.getModel();
            if ((menuItem.isSelected() && checkIcon == null)
                || (mod != null && mod.isArmed())
                && (menuItem.getParent() instanceof MenuElement))
              g.setColor(selectionForeground);
            else
              g.setColor(menuItem.getForeground());
          }
        else
          // FIXME: should fix this to use 'disabledForeground', but its
          // default value in BasicLookAndFeel is null.

          // FIXME: should there be different foreground colours for selected
          // or deselected, when disabled?
          g.setColor(Color.gray);

        int mnemonicIndex = menuItem.getDisplayedMnemonicIndex();

        if (mnemonicIndex != -1)
          BasicGraphicsUtils.drawStringUnderlineCharAt(menuItem, g, text,
                                                       mnemonicIndex,
                                                       textRect.x,
                                                       textRect.y
                                                           + fm.getAscent());
        else
          BasicGraphicsUtils.drawString(menuItem, g, text, 0, textRect.x,
                                        textRect.y + fm.getAscent());
      }
  }

  /**
   * This method uninstalls the components for this {@link JMenuItem}.
   * 
   * @param menuItem
   *          The {@link JMenuItem} to uninstall components for.
   */
  protected void uninstallComponents(JMenuItem menuItem)
  {
    // FIXME: need to implement
  }

  /**
   * This method uninstalls the defaults and sets any objects created during
   * install to null
   */
  protected void uninstallDefaults()
  {
    menuItem.setForeground(null);
    menuItem.setBackground(null);
    menuItem.setBorder(null);
    menuItem.setMargin(null);
    menuItem.setBackground(null);
    menuItem.setBorder(null);
    menuItem.setFont(null);
    menuItem.setForeground(null);
    menuItem.setMargin(null);
    acceleratorFont = null;
    acceleratorForeground = null;
    acceleratorSelectionForeground = null;
    arrowIcon = null;
    selectionBackground = null;
    selectionForeground = null;
    acceleratorDelimiter = null;
  }

  /**
   * Uninstalls any keyboard actions.
   */
  protected void uninstallKeyboardActions()
  {   
    SwingUtilities.replaceUIInputMap(menuItem,
                                     JComponent.WHEN_IN_FOCUSED_WINDOW, null);
  }

  /**
   * Unregisters all the listeners that this UI delegate was using.
   */
  protected void uninstallListeners()
  {
    menuItem.removeMouseListener(mouseInputListener);
    menuItem.removeMenuDragMouseListener(menuDragMouseListener);
    menuItem.removeMenuKeyListener(menuKeyListener);
    menuItem.removeItemListener(itemListener);
    menuItem.removePropertyChangeListener(propertyChangeListener);
  }

  /**
   * Performs the opposite of installUI. Any properties or resources that need
   * to be cleaned up will be done now. It will also uninstall any listeners it
   * has. In addition, any properties of this UI will be nulled.
   * 
   * @param c
   *          The {@link JComponent} that is having this UI uninstalled.
   */
  public void uninstallUI(JComponent c)
  {
    uninstallListeners();
    uninstallDefaults();
    uninstallComponents(menuItem);
    menuItem = null;
  }

  /**
   * This method calls paint.
   * 
   * @param g
   *          The graphics context used to paint this menu item
   * @param c
   *          The menu item to paint
   */
  public void update(Graphics g, JComponent c)
  {
    paint(g, c);
  }

  /**
   * Return text representation of the specified accelerator
   * 
   * @param accelerator
   *          Accelerator for which to return string representation
   * @return $String$ Text representation of the given accelerator
   */
  private String getAcceleratorText(KeyStroke accelerator)
  {
    // convert keystroke into string format
    String modifiersText = "";
    int modifiers = accelerator.getModifiers();
    char keyChar = accelerator.getKeyChar();
    int keyCode = accelerator.getKeyCode();

    if (modifiers != 0)
      modifiersText = KeyEvent.getKeyModifiersText(modifiers)
                      + acceleratorDelimiter;

    if (keyCode == KeyEvent.VK_UNDEFINED)
      return modifiersText + keyChar;
    else
      return modifiersText + KeyEvent.getKeyText(keyCode);
  }

  /**
   * Calculates and return rectange in which accelerator should be displayed
   * 
   * @param accelerator
   *          accelerator for which to return the display rectangle
   * @param fm
   *          The font metrics used to measure the text
   * @return $Rectangle$ reactangle which will be used to display accelerator
   */
  private Rectangle getAcceleratorRect(KeyStroke accelerator, FontMetrics fm)
  {
    int width = fm.stringWidth(getAcceleratorText(accelerator));
    int height = fm.getHeight();
    return new Rectangle(0, 0, width, height);
  }

  /**
   * This class handles mouse events occuring inside the menu item. Most of the
   * events are forwarded for processing to MenuSelectionManager of the current
   * menu hierarchy.
   */
  protected class MouseInputHandler implements MouseInputListener
  {
    /**
     * Creates a new MouseInputHandler object.
     */
    protected MouseInputHandler()
    {
      // Nothing to do here.
    }

    /**
     * This method is called when mouse is clicked on the menu item. It forwards
     * this event to MenuSelectionManager.
     * 
     * @param e
     *          A {@link MouseEvent}.
     */
    public void mouseClicked(MouseEvent e)
    {
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      manager.processMouseEvent(e);
    }

    /**
     * This method is called when mouse is dragged inside the menu item. It
     * forwards this event to MenuSelectionManager.
     * 
     * @param e
     *          A {@link MouseEvent}.
     */
    public void mouseDragged(MouseEvent e)
    {
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      manager.processMouseEvent(e);
    }

    /**
     * This method is called when mouse enters menu item. When this happens menu
     * item is considered to be selected and selection path in
     * MenuSelectionManager is set. This event is also forwarded to
     * MenuSelection Manager for further processing.
     * 
     * @param e
     *          A {@link MouseEvent}.
     */
    public void mouseEntered(MouseEvent e)
    {
      Component source = (Component) e.getSource();
      if (source.getParent() instanceof MenuElement)
        {
          MenuSelectionManager manager = MenuSelectionManager.defaultManager();
          manager.setSelectedPath(getPath());
          manager.processMouseEvent(e);
        }
    }

    /**
     * This method is called when mouse exits menu item. The event is forwarded
     * to MenuSelectionManager for processing.
     * 
     * @param e
     *          A {@link MouseEvent}.
     */
    public void mouseExited(MouseEvent e)
    {
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      manager.processMouseEvent(e);
    }

    /**
     * This method is called when mouse is inside the menu item. This event is
     * forwarder to MenuSelectionManager for further processing.
     * 
     * @param e
     *          A {@link MouseEvent}.
     */
    public void mouseMoved(MouseEvent e)
    {
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      manager.processMouseEvent(e);
    }

    /**
     * This method is called when mouse is pressed. This event is forwarded to
     * MenuSelectionManager for further processing.
     * 
     * @param e
     *          A {@link MouseEvent}.
     */
    public void mousePressed(MouseEvent e)
    {
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      manager.processMouseEvent(e);
    }

    /**
     * This method is called when mouse is released. If the mouse is released
     * inside this menuItem, then this menu item is considered to be chosen and
     * the menu hierarchy should be closed.
     * 
     * @param e
     *          A {@link MouseEvent}.
     */
    public void mouseReleased(MouseEvent e)
    {
      Rectangle size = menuItem.getBounds();
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      if (e.getX() > 0 && e.getX() < size.width && e.getY() > 0
          && e.getY() < size.height)
        {
          manager.clearSelectedPath();
          menuItem.doClick();
        }

      else
        manager.processMouseEvent(e);
    }
  }

  /**
   * This class handles mouse dragged events.
   */
  private class MenuDragMouseHandler implements MenuDragMouseListener
  {
    /**
     * Tbis method is invoked when mouse is dragged over the menu item.
     * 
     * @param e
     *          The MenuDragMouseEvent
     */
    public void menuDragMouseDragged(MenuDragMouseEvent e)
    {
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      manager.setSelectedPath(e.getPath());
    }

    /**
     * Tbis method is invoked when mouse enters the menu item while it is being
     * dragged.
     * 
     * @param e
     *          The MenuDragMouseEvent
     */
    public void menuDragMouseEntered(MenuDragMouseEvent e)
    {
      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      manager.setSelectedPath(e.getPath());
    }

    /**
     * Tbis method is invoked when mouse exits the menu item while it is being
     * dragged
     * 
     * @param e the MenuDragMouseEvent
     */
    public void menuDragMouseExited(MenuDragMouseEvent e)
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * Tbis method is invoked when mouse was dragged and released inside the
     * menu item.
     * 
     * @param e
     *          The MenuDragMouseEvent
     */
    public void menuDragMouseReleased(MenuDragMouseEvent e)
    {
      MenuElement[] path = e.getPath();

      if (path[path.length - 1] instanceof JMenuItem)
        ((JMenuItem) path[path.length - 1]).doClick();

      MenuSelectionManager manager = MenuSelectionManager.defaultManager();
      manager.clearSelectedPath();
    }
  }

  /**
   * This class handles key events occuring when menu item is visible on the
   * screen.
   */
  private class MenuKeyHandler implements MenuKeyListener
  {
    /**
     * This method is invoked when key has been pressed
     * 
     * @param e
     *          A {@link MenuKeyEvent}.
     */
    public void menuKeyPressed(MenuKeyEvent e)
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * This method is invoked when key has been pressed
     * 
     * @param e
     *          A {@link MenuKeyEvent}.
     */
    public void menuKeyReleased(MenuKeyEvent e)
    {
      // TODO: What should be done here, if anything?
    }

    /**
     * This method is invoked when key has been typed It handles the mnemonic
     * key for the menu item.
     * 
     * @param e
     *          A {@link MenuKeyEvent}.
     */
    public void menuKeyTyped(MenuKeyEvent e)
    {
      // TODO: What should be done here, if anything?
    }
  }
  
  /**
   * Helper class that listens for item changes to the properties of the {@link
   * JMenuItem}.
   */
  private class ItemHandler implements ItemListener
  {
    /**
     * This method is called when one of the menu item changes.
     *
     * @param evt A {@link ItemEvent}.
     */
    public void itemStateChanged(ItemEvent evt)
    {
      boolean state = false;
      if (menuItem instanceof JCheckBoxMenuItem)
        {
          if (evt.getStateChange() == ItemEvent.SELECTED)
            state = true;
          ((JCheckBoxMenuItem) menuItem).setState(state);
        }
      menuItem.revalidate();
      menuItem.repaint();
    }
  }

  /**
   * A helper method to create the accelerator string from the menu item's
   * accelerator property. The returned string is empty if there is
   * no accelerator defined.
   *
   * @param m the menu item
   *
   * @return the accelerator string, not null
   */
  private String getAcceleratorString(JMenuItem m)
  {
    // Create accelerator string.
    KeyStroke accel = m.getAccelerator();
    String accelText = "";
    if (accel != null)
      {
        int mods = accel.getModifiers();
        if (mods > 0)
          {
            accelText = KeyEvent.getKeyModifiersText(mods);
            accelText += acceleratorDelimiter;
          }
        int keycode = accel.getKeyCode();
        if (keycode != 0)
          accelText += KeyEvent.getKeyText(keycode);
        else
          accelText += accel.getKeyChar();
      }
    return accelText;
  }

  /**
   * A helper method that lays out the menu item. The layout is stored
   * in the fields of this class.
   *
   * @param m the menu item to layout
   * @param accelText the accelerator text
   */
  private void layoutMenuItem(JMenuItem m, String accelText)
  {
    int width = m.getWidth();
    int height = m.getHeight();

    // Reset rectangles.
    iconRect.setBounds(0, 0, 0, 0);
    textRect.setBounds(0, 0, 0, 0);
    accelRect.setBounds(0, 0, 0, 0);
    checkIconRect.setBounds(0, 0, 0, 0);
    arrowIconRect.setBounds(0, 0, 0, 0);
    viewRect.setBounds(0, 0, width, height);

    // Substract insets to the view rect.
    Insets insets = m.getInsets();
    viewRect.x += insets.left;
    viewRect.y += insets.top;
    viewRect.width -= insets.left + insets.right;
    viewRect.height -= insets.top + insets.bottom;

    // Fetch the fonts.
    Font font = m.getFont();
    FontMetrics fm = m.getFontMetrics(font);
    FontMetrics accelFm = m.getFontMetrics(acceleratorFont);

    String text = m.getText();
    SwingUtilities.layoutCompoundLabel(m, fm, text, m.getIcon(),
                                       m.getVerticalAlignment(),
                                       m.getHorizontalAlignment(),
                                       m.getVerticalTextPosition(),
                                       m.getHorizontalTextPosition(),
                                       viewRect, iconRect, textRect,
                                       defaultTextIconGap);

    // Initialize accelerator width and height.
    if (! accelText.equals(""))
      {
        accelRect.width = accelFm.stringWidth(accelText);
        accelRect.height = accelFm.getHeight();
      }

    // Initialize check and arrow icon width and height.
    if (! (m instanceof JMenu && ((JMenu) m).isTopLevelMenu()))
      {
        if (checkIcon != null)
          {
            checkIconRect.width = checkIcon.getIconWidth();
            checkIconRect.height = checkIcon.getIconHeight();
          }
        if (arrowIcon != null)
          {
            arrowIconRect.width = arrowIcon.getIconWidth();
            arrowIconRect.height = arrowIcon.getIconHeight();
          }
      }

    // The union of the icon and text of the menu item is the 'label area'.
    cachedRect.setBounds(textRect);
    Rectangle labelRect = SwingUtilities.computeUnion(iconRect.x,
                                                      iconRect.y,
                                                      iconRect.width,
                                                      iconRect.height,
                                                      cachedRect);
    textRect.x += defaultTextIconGap;
    iconRect.x += defaultTextIconGap;

    // Layout accelerator rect.
    accelRect.x = viewRect.x + viewRect.width - arrowIconRect.width
      - defaultTextIconGap - accelRect.width;
    // Layout check and arrow icons only when not in toplevel menu.
    if (! (m instanceof JMenu && ((JMenu) m).isTopLevelMenu()))
      {
        checkIconRect.x = viewRect.x + defaultTextIconGap;
        textRect.x += defaultTextIconGap + checkIconRect.width;
        iconRect.x += defaultTextIconGap + checkIconRect.width;
        arrowIconRect.x = viewRect.x + viewRect.width - defaultTextIconGap
          - arrowIconRect.width;
      }

    // Align the accelerator text and all the icons vertically centered to
    // the menu text.
    accelRect.y = labelRect.y + (labelRect.height / 2)
      - (accelRect.height / 2);
    if (! (m instanceof JMenu && ((JMenu) m).isTopLevelMenu()))
      {
        arrowIconRect.y = labelRect.y + (labelRect.height / 2)
          - (arrowIconRect.height / 2);
        checkIconRect.y = labelRect.y + (labelRect.height / 2)
          - (checkIconRect.height / 2);
      }
  }
}
