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

import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.accessibility.AccessibleSelection;
import javax.accessibility.AccessibleStateSet;
import javax.swing.plaf.MenuBarUI;

/**
 * JMenuBar is a container for menu's. For a menu bar to be seen on the
 * screen, at least one menu should be added to it. Just like adding
 * components to container, one can use add() to add menu's to the menu bar.
 * Menu's will be displayed in the menu  bar in the order they were added.
 * The JMenuBar uses selectionModel to keep track of selected menu index.
 * JMenuBar's selectionModel will fire ChangeEvents to its registered 
 * listeners when the selected index changes.
 */
public class JMenuBar extends JComponent implements Accessible, MenuElement
{
  /**
   * Provides accessibility support for <code>JMenuBar</code>.
   * 
   * @author Roman Kennke (kennke@aicas.com)
   */
  protected class AccessibleJMenuBar extends AccessibleJComponent
    implements AccessibleSelection
  {

    /**
     * Returns the number of selected items in the menu bar. Possible values
     * are <code>0</code> if nothing is selected, or <code>1</code> if one
     * item is selected.
     *
     * @return the number of selected items in the menu bar
     */
    public int getAccessibleSelectionCount()
    {
      int count = 0;
      if (getSelectionModel().getSelectedIndex() != -1)
        count = 1;
      return count;
    }

    /**
     * Returns the selected with index <code>i</code> menu, or
     * <code>null</code> if the specified menu is not selected.
     *
     * @param i the index of the menu to return
     *
     * @return the selected with index <code>i</code> menu, or
     *         <code>null</code> if the specified menu is not selected
     */
    public Accessible getAccessibleSelection(int i)
    {
      if (getSelectionModel().getSelectedIndex() != i)
        return null;
      return getMenu(i);
    }

    /**
     * Returns <code>true</code> if the specified menu is selected,
     * <code>false</code> otherwise.
     *
     * @param i the index of the menu to check
     *
     *@return <code>true</code> if the specified menu is selected,
     *        <code>false</code> otherwise
     */
    public boolean isAccessibleChildSelected(int i)
    {
      return getSelectionModel().getSelectedIndex() == i;
    }

    /**
     * Selects the menu with index <code>i</code>. If another menu is already
     * selected, this will be deselected.
     *
     * @param i the menu to be selected
     */
    public void addAccessibleSelection(int i)
    {
      getSelectionModel().setSelectedIndex(i);
    }

    /**
     * Deselects the menu with index <code>i</code>.
     *
     * @param i the menu index to be deselected
     */
    public void removeAccessibleSelection(int i)
    {
      if (getSelectionModel().getSelectedIndex() == i)
        getSelectionModel().clearSelection();
    }

    /**
     * Deselects all possibly selected menus.
     */
    public void clearAccessibleSelection()
    {
      getSelectionModel().clearSelection();
    }

    /**
     * In menu bars it is not possible to select all items, so this method
     * does nothing.
     */
    public void selectAllAccessibleSelection()
    {
      // In menu bars it is not possible to select all items, so this method
      // does nothing.
    }

    /**
     * Returns the accessible role of <code>JMenuBar</code>, which is
     * {@link AccessibleRole#MENU_BAR}.
     *
     * @return the accessible role of <code>JMenuBar</code>, which is
     *         {@link AccessibleRole#MENU_BAR}
     */
    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.MENU_BAR;
    }

    /**
     * Returns the <code>AccessibleSelection</code> for this object. This
     * method returns <code>this</code>, since the
     * <code>AccessibleJMenuBar</code> manages its selection itself.
     *
     * @return the <code>AccessibleSelection</code> for this object
     */
    public AccessibleSelection getAccessibleSelection()
    {
      return this;
    }

    /**
     * Returns the state of this <code>AccessibleJMenuBar</code>.
     *
     * @return the state of this <code>AccessibleJMenuBar</code>.
     */
    public AccessibleStateSet getAccessibleStateSet()
    {
      AccessibleStateSet stateSet = super.getAccessibleStateSet();
      // TODO: Figure out what state must be added to the super state set.
      return stateSet;
    }
  }

  private static final long serialVersionUID = -8191026883931977036L;

  /** JMenuBar's model. It keeps track of selected menu's index */
  private transient SingleSelectionModel selectionModel;

  /* borderPainted property indicating if the menuBar's border will be painted*/
  private boolean borderPainted;

  /* margin between menu bar's border and its menues*/
  private Insets margin;

  /**
   * Creates a new JMenuBar object.
   */
  public JMenuBar()
  {
    selectionModel = new DefaultSingleSelectionModel();
    borderPainted = true;
    updateUI();
  }

  /**
   * Adds menu to the menu bar
   *
   * @param c menu to add
   *
   * @return reference to the added menu
   */
  public JMenu add(JMenu c)
  {
    c.setAlignmentX(Component.LEFT_ALIGNMENT);
    super.add(c);
    return c;
  }

  /**
   * This method overrides addNotify() in the Container to register
   * this menu bar with the current keyboard manager.
   */
  public void addNotify()
  {
    super.addNotify();
    KeyboardManager.getManager().registerJMenuBar(this);
  }

  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJMenuBar();
    return accessibleContext;
  }

  /**
   * Returns reference to this menu bar
   *
   * @return reference to this menu bar
   */
  public Component getComponent()
  {
    return this;
  }

  /**
   * Returns component at the specified index.
   *
   * @param i index of the component to get
   *
   * @return component at the specified index. Null is returned if
   * component at the specified index doesn't exist.
   * @deprecated Replaced by getComponent(int)
   */
  public Component getComponentAtIndex(int i)
  {
    return getComponent(i);
  }

  /**
   * Returns index of the specified component
   *
   * @param c Component to search for
   *
   * @return index of the specified component. -1 is returned if
   * specified component doesnt' exist in the menu bar.
   */
  public int getComponentIndex(Component c)
  {
    Component[] comps = getComponents();

    int index = -1;

    for (int i = 0; i < comps.length; i++)
      {
	if (comps[i].equals(c))
	  {
	    index = i;
	    break;
	  }
      }

    return index;
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public JMenu getHelpMenu()
  {
    return null;
  }

  /**
   * Returns margin betweeen menu bar's border and its menues
   *
   * @return margin between menu bar's border and its menues
   */
  public Insets getMargin()
  {
    if (margin == null)
      return new Insets(0, 0, 0, 0);
    else
      return margin;
  }

  /**
   * Return menu at the specified index. If component at the
   * specified index is not a menu, then null is returned.
   *
   * @param index index to look for the menu
   *
   * @return menu at specified index, or null if menu doesn't exist
   * at the specified index.
   */
  public JMenu getMenu(int index)
  {
    if (getComponentAtIndex(index) instanceof JMenu)
      return (JMenu) getComponentAtIndex(index);
    else
      return null;
  }

  /**
   * Returns number of menu's in this menu bar
   *
   * @return number of menu's in this menu bar
   */
  public int getMenuCount()
  {
    return getComponentCount();
  }

  /**
   * Returns selection model for this menu bar. SelectionModel
   * keeps track of the selected menu in the menu bar. Whenever
   * selected property of selectionModel changes, the ChangeEvent
   * will be fired its ChangeListeners.
   *
   * @return selection model for this menu bar.
   */
  public SingleSelectionModel getSelectionModel()
  {
    return selectionModel;
  }

  /**
   * Method of MenuElement interface. It returns subcomponents
   * of the menu bar, which are all the menues that it contains.
   *
   * @return MenuElement[] array containing menues in this menu bar
   */
  public MenuElement[] getSubElements()
  {
    MenuElement[] subElements = new MenuElement[getComponentCount()];

    for (int i = 0; i < getComponentCount(); i++)
      subElements[i] = (MenuElement) getMenu(i);

    return subElements;
  }

  /**
    * Set the "UI" property of the menu bar, which is a look and feel class
    * responsible for handling the menuBar's input events and painting it.
    *
    * @return The current "UI" property
    */
  public MenuBarUI getUI()
  {
    return (MenuBarUI) ui;
  }

  /**
   * This method returns a name to identify which look and feel class will be
   * the UI delegate for the menu bar.
   *
   * @return The Look and Feel classID. "MenuBarUI"
   */
  public String getUIClassID()
  {
    return "MenuBarUI";
  }

  /**
   * Returns true if menu bar paints its border and false otherwise
   *
   * @return true if menu bar paints its border and false otherwise
   */
  public boolean isBorderPainted()
  {
    return borderPainted;
  }

  /**
   * Returns true if some menu in menu bar is selected.
   *
   * @return true if some menu in menu bar is selected and false otherwise
   */
  public boolean isSelected()
  {
    return selectionModel.isSelected();
  }

  /**
   * This method does nothing by default. This method is need for the
   * MenuElement interface to be implemented.
   *
   * @param isIncluded true if menuBar is included in the selection
   * and false otherwise
   */
  public void menuSelectionChanged(boolean isIncluded)
  {
    // Do nothing - needed for implementation of MenuElement interface
  }

  /**
   * Paints border of the menu bar, if its borderPainted property is set to
   * true.
   *
   * @param g The graphics context with which to paint the border
   */
  protected void paintBorder(Graphics g)
  {
    if (borderPainted)
      getBorder().paintBorder(this, g, 0, 0, getSize(null).width,
                              getSize(null).height);
  }

  /**
   * A string that describes this JMenuBar. Normally only used
   * for debugging.
   *
   * @return A string describing this JMenuBar
   */
  protected String paramString()
  {
    StringBuffer sb = new StringBuffer();
    sb.append(super.paramString());
    sb.append(",margin=");
    if (getMargin() != null)
      sb.append(getMargin());
    sb.append(",paintBorder=").append(isBorderPainted());
    return sb.toString();
  }

  /**
   * Process key events forwarded from MenuSelectionManager. This method
   * doesn't do anything. It is here to conform to the MenuElement interface.
   *
   * @param e event forwarded from MenuSelectionManager
   * @param path path to the menu element from which event was generated
   * @param manager MenuSelectionManager for the current menu hierarchy
   *
   */
  public void processKeyEvent(KeyEvent e, MenuElement[] path,
                              MenuSelectionManager manager)
  {
    // Do nothing - needed for implementation of MenuElement interface
  }

  /**
   * This method overrides JComponent.processKeyBinding to allow the 
   * JMenuBar to check all the child components (recursiveley) to see 
   * if they'll consume the event.
   * 
   * @param ks the KeyStroke for the event
   * @param e the KeyEvent for the event
   * @param condition the focus condition for the binding
   * @param pressed true if the key is pressed 
   */
  protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition,
                                      boolean pressed)
  {
    // See if the regular JComponent behavior consumes the event
    if (super.processKeyBinding(ks, e, condition, pressed))
      return true;
    
    // If not, have to recursively check all the child menu elements to see 
    // if they want it    
    MenuElement[] children = getSubElements();
    for (int i = 0; i < children.length; i++)
      if (processKeyBindingHelper(children[i], ks, e, condition, pressed))
        return true;
    return false;
  }
  
  /**
   * This is a helper method to recursively check the children of this
   * JMenuBar to see if they will consume a key event via key bindings.  
   * This is used for menu accelerators.
   * @param menuElement the menuElement to check (and check all its children)
   * @param ks the KeyStroke for the event
   * @param e the KeyEvent that may be consumed
   * @param condition the focus condition for the binding
   * @param pressed true if the key was pressed
   * @return true <code>menuElement</code> or one of its children consume
   * the event (processKeyBinding returns true for menuElement or one of
   * its children).
   */
  static boolean processKeyBindingHelper(MenuElement menuElement, KeyStroke ks,
                                         KeyEvent e, int condition,
                                         boolean pressed)
  {
    // First check the menuElement itself, if it's a JComponent
    if (menuElement instanceof JComponent
        && ((JComponent) menuElement).processKeyBinding(ks, e, condition,
                                                        pressed))
      return true;
    
    // If that didn't consume it, check all the children recursively
    MenuElement[] children = menuElement.getSubElements();
    for (int i = 0; i < children.length; i++)
      if (processKeyBindingHelper(children[i], ks, e, condition, pressed))
        return true;
    return false;
  }
  
  /**
   * Process mouse events forwarded from MenuSelectionManager. This method
   * doesn't do anything. It is here to conform to the MenuElement interface.
   *
   * @param event event forwarded from MenuSelectionManager
   * @param path path to the menu element from which event was generated
   * @param manager MenuSelectionManager for the current menu hierarchy
   *
   */
  public void processMouseEvent(MouseEvent event, MenuElement[] path,
                                MenuSelectionManager manager)
  {
    // Do nothing - needed for implementation of MenuElement interface
  }

  /**
   * This method overrides removeNotify() in the Container to
   * unregister this menu bar from the current keyboard manager.
   */
  public void removeNotify()
  {
    KeyboardManager.getManager().unregisterJMenuBar(this);
    super.removeNotify();
  }

  /**
   * Sets painting status of the border. If 'b' is true then menu bar's
   * border will be painted, and it will not be painted otherwise.
   *
   * @param b indicates if menu bar's border should be painted.
   */
  public void setBorderPainted(boolean b)
  {
    if (b != borderPainted)
      {
	boolean old = borderPainted;
	borderPainted = b;
	firePropertyChange("borderPainted", old, b);
	revalidate();
	repaint();
      }
  }

  /**
   * Sets help menu for this menu bar
   *
   * @param menu help menu
   *
   * @specnote The specification states that this method is not yet implemented
   *           and should throw an exception.
   */
  public void setHelpMenu(JMenu menu)
  {
    // We throw an Error here, just as Sun's JDK does.
    throw new Error("setHelpMenu() not yet implemented.");
  }

  /**
   * Sets the menu bar's "margin" bound property,  which represents
   * distance between the menubar's border and its menus.
   * icon. When marging property is modified, PropertyChangeEvent will
   * be fired to menuBar's PropertyChangeListener's.
   *
   * @param m distance between the menubar's border and its menus.
   *
   */
  public void setMargin(Insets m)
  {
    if (m != margin)
      {
	Insets oldMargin = margin;
	margin = m;
	firePropertyChange("margin", oldMargin, margin);
      }
  }

  /**
   * Changes menu bar's selection to the specified menu.
   * This method updates selected index of menu bar's selection model,
   * which results in a model firing change event.
   *
   * @param sel menu to select
   */
  public void setSelected(Component sel)
  {
    int index = getComponentIndex(sel);
    selectionModel.setSelectedIndex(index);
  }

  /**
   * Sets menuBar's selection model to the one specified
   *
   * @param model SingleSelectionModel that needs to be set for this menu bar
   */
  public void setSelectionModel(SingleSelectionModel model)
  {
    if (selectionModel != model)
      {
	SingleSelectionModel oldModel = selectionModel;
	selectionModel = model;
	firePropertyChange("model", oldModel, selectionModel);
      }
  }

  /**
   * Set the "UI" property of the menu bar, which is a look and feel class
   * responsible for handling menuBar's input events and painting it.
   *
   * @param ui The new "UI" property
   */
  public void setUI(MenuBarUI ui)
  {
    super.setUI(ui);
  }

  /**
   * Set the "UI" property to a class constructed, via the {@link
   * UIManager}, from the current look and feel.
   */
  public void updateUI()
  {
    setUI((MenuBarUI) UIManager.getUI(this));
    invalidate();
  }
}
