/* JMenuBar.java --
   Copyright (C) 2002, 2004, 2005, 2006  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;

import javax.swing.border.Border;

/**
 * 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()];

    int j = 0;
    boolean doResize = false;
    MenuElement menu;
    for (int i = 0; i < getComponentCount(); i++)
      {
        menu = getMenu(i);
        if (menu != null)
          {
            subElements[j++] = (MenuElement) menu;
          }
        else
          doResize = true;
      }

    if (! doResize)
      return subElements;
    else
      {
        MenuElement[] subElements2 = new MenuElement[j];
        for (int i = 0; i < j; i++)
          subElements2[i] = subElements[i];

        return subElements2;
      }
  }

  /**
    * 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)
      {
        Border border = getBorder();
        if (border != null)
          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)
  {
    if (menuElement == null)
      return false;

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