/* JPopupMenu.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.Dimension;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.EventListener;

import javax.accessibility.Accessible;
import javax.accessibility.AccessibleContext;
import javax.accessibility.AccessibleRole;
import javax.swing.event.MenuKeyListener;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.PopupMenuUI;

/**
 * JPopupMenu is a container that is used to display popup menu's menu
 * items. By default JPopupMenu is a lightweight container, however if it
 * is the case that JPopupMenu's bounds are outside of main window, then
 * heawyweight container will be used to display menu items. It is also
 * possible to change JPopupMenu's default  behavior and set JPopupMenu
 * to always use heavyweight container.
 *
 * JPopupMenu can be displayed anywhere; it is a floating free popup menu.
 * However before JPopupMenu is diplayed, its invoker property should be set.
 * JPopupMenu's invoker is a component relative to which popup menu is
 * displayed.
 *
 * JPopupMenu fires PopupMenuEvents to its registered listeners. Whenever
 * JPopupMenu becomes visible on the screen then PopupMenuEvent indicating
 * that popup menu became visible will be fired. In the case when
 * JPopupMenu becomes invisible or cancelled without selection, then
 * popupMenuBecomeInvisible() or popupMenuCancelled() methods of
 * PopupMenuListeners will be invoked.
 *
 * JPopupMenu also fires PropertyChangeEvents when its bound properties 
 * change.In addittion to inheritted bound properties, JPopupMenu has 
 * 'visible' bound property. When JPopupMenu becomes visible/invisible on
 * the screen it fires PropertyChangeEvents to its registered 
 * PropertyChangeListeners.
 */
public class JPopupMenu extends JComponent implements Accessible, MenuElement
{
  private static final long serialVersionUID = -8336996630009646009L;

  /* indicates if popup's menu border should be painted*/
  private boolean borderPainted = true;

  /** Flag indicating whether lightweight, mediumweight or heavyweight popup
     is used to display menu items.

     These are the possible cases:

     1. if DefaultLightWeightPopupEnabled true
         (i)  use lightweight container if popup feets inside top-level window
         (ii) only use heavyweight container (JDialog) if popup doesn't fit.

     2. if DefaultLightWeightPopupEnabled false
         (i) if popup fits, use awt.Panel (mediumWeight)
         (ii) if popup doesn't fit, use JDialog (heavyWeight)
  */
  private static boolean DefaultLightWeightPopupEnabled = true;

  /* Component that invokes popup menu. */
  transient Component invoker;

  /* Label for this popup menu. It is not used in most of the look and feel themes. */
  private String label;

  /*Amount of space between menuItem's in JPopupMenu and JPopupMenu's border */
  private Insets margin;

  /** Indicates whether ligthWeight container can be used to display popup
     menu. This flag is the same as DefaultLightWeightPopupEnabled, but setting
     this flag can change popup menu after creation of the object */
  private boolean lightWeightPopupEnabled;

  /** SelectionModel that keeps track of menu selection. */
  protected SingleSelectionModel selectionModel;

  /* Popup that is used to display JPopupMenu */
  private transient Popup popup;

  /**
   * Location of the popup, X coordinate.
   */
  private int popupLocationX;

  /**
   * Location of the popup, Y coordinate.
   */
  private int popupLocationY;

  /* Field indicating if popup menu is visible or not */
  private boolean visible = false;
  
  /**
   * Creates a new JPopupMenu object.
   */
  public JPopupMenu()
  {
    this(null);
  }

  /**
   * Creates a new JPopupMenu with specified label
   *
   * @param label Label for popup menu.
   */
  public JPopupMenu(String label)
  {
    lightWeightPopupEnabled = getDefaultLightWeightPopupEnabled();
    setLabel(label);
    setSelectionModel(new DefaultSingleSelectionModel());
    super.setVisible(false);
    updateUI();
  }

  /**
  * Adds given menu item to the popup menu
  *
  * @param item menu item to add to the popup menu
  *
  * @return menu item that was added to the popup menu
  */
  public JMenuItem add(JMenuItem item)
  {
    this.insert(item, -1);
    return item;
  }

  /**
   * Constructs menu item with a specified label and adds it to
   * popup menu
   *
   * @param text label for the menu item to be added
   *
   * @return constructed menu item that was added to the popup menu
   */
  public JMenuItem add(String text)
  {
    JMenuItem item = new JMenuItem(text);
    return add(item);
  }

  /**
   * Constructs menu item associated with the specified action
   * and adds it to the popup menu
   *
   * @param action Action for the new menu item
   *
   * @return menu item that was added to the menu
   */
  public JMenuItem add(Action action)
  {
    JMenuItem item = createActionComponent(action);

    if (action != null)
      action.addPropertyChangeListener(createActionChangeListener(item));

    return add(item);
  }

  /**
   * Revomes component at the given index from the menu.
   *
   * @param index index of the component that will be removed in the menu
   */
  public void remove(int index)
  {
    super.remove(index);
    revalidate();
  }

  /**
   * Create menu item associated with the given action
   * and inserts it into the popup menu at the specified index
   *
   * @param action Action for the new menu item
   * @param index index in the popup menu at which to insert new menu item.
   */
  public void insert(Action action, int index)
  {
    JMenuItem item = new JMenuItem(action);
    this.insert(item, index);
  }

  /**
   * Insert given component to the popup menu at the
   * specified index
   *
   * @param component Component to insert
   * @param index Index at which to insert given component
   */
  public void insert(Component component, int index)
  {
    super.add(component, index);
  }

  /**
   * Returns flag indicating if newly created JPopupMenu will use
   * heavyweight or lightweight container to display its menu items
   *
   * @return true if JPopupMenu will use lightweight container to display
   * menu items by default, and false otherwise.
   */
  public static boolean getDefaultLightWeightPopupEnabled()
  {
    return DefaultLightWeightPopupEnabled;
  }

  /**
   * Sets whether JPopupMenu should use ligthWeight container to
   * display it menu items by default
   *
   * @param enabled true if JPopupMenu should use lightweight container
   * for displaying its menu items, and false otherwise.
   */
  public static void setDefaultLightWeightPopupEnabled(boolean enabled)
  {
    DefaultLightWeightPopupEnabled = enabled;
  }

  /**
   * This method returns the UI used to display the JPopupMenu.
   *
   * @return The UI used to display the JPopupMenu.
   */
  public PopupMenuUI getUI()
  {
    return (PopupMenuUI) ui;
  }

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

  /**
   * This method sets this menuItem's UI to the UIManager's default for the
   * current look and feel.
   */
  public void updateUI()
  {
    setUI((PopupMenuUI) UIManager.getUI(this));
  }

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

  /**
   * Returns selectionModel used by this popup menu to keep
   * track of the selection.
   *
   * @return popup menu's selection model
   */
  public SingleSelectionModel getSelectionModel()
  {
    return selectionModel;
  }

  /**
   * Sets selection model for this popup menu
   *
   * @param model new selection model of this popup menu
   */
  public void setSelectionModel(SingleSelectionModel model)
  {
	selectionModel = model;
  }

  /**
   * Creates new menu item associated with a given action.
   *
   * @param action Action used to create new menu item
   *
   * @return new created menu item associated with a given action.
   */
  protected JMenuItem createActionComponent(Action action)
  {
    return new JMenuItem(action);
  }

  /**
   * Creates PropertyChangeListener that listens to PropertyChangeEvents
   * occuring in the Action associated with given menu item in this popup menu.
   *
   * @param item MenuItem
   *
   * @return The PropertyChangeListener
   */
  protected PropertyChangeListener createActionChangeListener(JMenuItem item)
  {
    return new ActionChangeListener();
  }

  /**
   * Returns true if this popup menu will display its menu item in
   * a lightweight container and false otherwise.
   *
   * @return true if this popup menu will display its menu items
   * in a lightweight container and false otherwise.
   */
  public boolean isLightWeightPopupEnabled()
  {
    return lightWeightPopupEnabled;
  }

  /**
   * DOCUMENT ME!
   *
   * @param enabled DOCUMENT ME!
   */
  public void setLightWeightPopupEnabled(boolean enabled)
  {
    lightWeightPopupEnabled = enabled;
  }

  /**
   * Returns label for this popup menu
   *
   * @return label for this popup menu
   */
  public String getLabel()
  {
    return label;
  }

  /**
   * Sets label for this popup menu. This method fires PropertyChangeEvent
   * when the label property is changed. Please note that most
   * of the Look &amp; Feel will ignore this property.
   *
   * @param label label for this popup menu
   */
  public void setLabel(String label)
  {
    if (label != this.label)
      {
	String oldLabel = this.label;
	this.label = label;
	firePropertyChange("label", oldLabel, label);
      }
  }

  /**
   * Adds separator to this popup menu
   */
  public void addSeparator()
  {
    // insert separator at the end of the list of menu items    
    this.insert(new Separator(), -1);
  }

  /**
   * Adds a MenuKeyListener to the popup.
   * 
   * @param l - the listener to add.
   */
  public void addMenuKeyListener(MenuKeyListener l)
  {
    listenerList.add(MenuKeyListener.class, l);
  }
  
  /**
   * Removes a MenuKeyListener from the popup.
   * 
   * @param l - the listener to remove.
   */
  public void removeMenuKeyListener(MenuKeyListener l)
  {
    listenerList.remove(MenuKeyListener.class, l);
  }
  
  /**
   * Returns array of getMenuKeyListeners that are listening to JPopupMenu.
   * 
   * @return array of getMenuKeyListeners that are listening to JPopupMenu
   */
  public MenuKeyListener[] getMenuKeyListeners()
  {
    return ((MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class));
  }
  
  /**
   * Adds popupMenuListener to listen for PopupMenuEvents fired
   * by the JPopupMenu
   *
   * @param listener PopupMenuListener to add to JPopupMenu
   */
  public void addPopupMenuListener(PopupMenuListener listener)
  {
    listenerList.add(PopupMenuListener.class, listener);
  }

  /**
   * Removes PopupMenuListener from JPopupMenu's list of listeners
   *
   * @param listener PopupMenuListener which needs to be removed
   */
  public void removePopupMenuListener(PopupMenuListener listener)
  {
    listenerList.remove(PopupMenuListener.class, listener);
  }

  /**
   * Returns array of PopupMenuListeners that are listening to JPopupMenu
   *
   * @return Array of PopupMenuListeners that are listening to JPopupMenu
   */
  public PopupMenuListener[] getPopupMenuListeners()
  {
    return ((PopupMenuListener[]) listenerList.getListeners(PopupMenuListener.class));
  }

  /**
   * This method calls popupMenuWillBecomeVisible() of popup menu's
   * PopupMenuListeners. This method is invoked just before popup menu
   * will appear on the screen.
   */
  protected void firePopupMenuWillBecomeVisible()
  {
    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);

    for (int i = 0; i < ll.length; i++)
      ((PopupMenuListener) ll[i]).popupMenuWillBecomeVisible(new PopupMenuEvent(this));
  }

  /**
   * This method calls popupMenuWillBecomeInvisible() of popup
   * menu's PopupMenuListeners. This method is invoked just before popup
   * menu will disappear from the screen
   */
  protected void firePopupMenuWillBecomeInvisible()
  {
    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);

    for (int i = 0; i < ll.length; i++)
      ((PopupMenuListener) ll[i]).popupMenuWillBecomeInvisible(new PopupMenuEvent(this));
  }

  /**
   * This method calls popupMenuCanceled() of popup menu's PopupMenuListeners.
   * This method is invoked just before popup menu is cancelled. This happens
   * when popup menu is closed without selecting any of its menu items. This
   * usually happens when the top-level window is resized or moved.
   */
  protected void firePopupMenuCanceled()
  {
    EventListener[] ll = listenerList.getListeners(PopupMenuListener.class);

    for (int i = 0; i < ll.length; i++)
      ((PopupMenuListener) ll[i]).popupMenuCanceled(new PopupMenuEvent(this));
  }

  /**
   * This methods sets popup menu's size to its' preferred size. If the
   * popup menu's size is previously set it will be ignored.
   */
  public void pack()
  {
    // Hook up this call so that it gets executed on the event thread in order
    // to avoid synchronization problems when calling the layout manager.
    if (! SwingUtilities.isEventDispatchThread())
      {
        SwingUtilities.invokeLater(new Runnable()
          {
            public void run()
            {
              show();
            }
          });
      }

    setSize(getPreferredSize());
  }

  /**
   * Return visibility of the popup menu
   *
   * @return true if popup menu is visible on the screen and false otherwise.
   */
  public boolean isVisible()
  {
    return visible;
  }

  /**
   * Sets visibility property of this popup menu. If the property is
   * set to true then popup menu will be dispayed and popup menu will
   * hide itself if visible property is set to false.
   *
   * @param visible true if popup menu will become visible and false otherwise.
   */
  public void setVisible(final boolean visible)
  {
    // Hook up this call so that it gets executed on the event thread in order
    // to avoid synchronization problems when calling the layout manager.
    if (! SwingUtilities.isEventDispatchThread())
      {
        SwingUtilities.invokeLater(new Runnable()
          {
            public void run()
            {
              setVisible(visible);
            }
          });
      }

    if (visible == isVisible())
      return;

    boolean old = isVisible();
    this.visible = visible;
    if (old != isVisible())
      {
        if (visible)
          {
            if (invoker != null && !(invoker instanceof JMenu))
              {
                MenuElement[] menuEls;
                if (getSubElements().length > 0)
                  {
                    menuEls = new MenuElement[2];
                    menuEls[0] = this;
                    menuEls[1] = getSubElements()[0];
                }
                else
                  {
                    menuEls = new MenuElement[1];
                    menuEls[0] = this;
                  }
                MenuSelectionManager.defaultManager().setSelectedPath(menuEls);
              }
            firePopupMenuWillBecomeVisible();
            PopupFactory pf = PopupFactory.getSharedInstance();
            pack();
            popup = pf.getPopup(invoker, this, popupLocationX, popupLocationY);
            popup.show();
          }
        else
          {
            getSelectionModel().clearSelection();
            firePopupMenuWillBecomeInvisible();
            popup.hide();
          }
        firePropertyChange("visible", old, isVisible());
      }
  }

  /**
   * Sets location of the popup menu.
   *
   * @param x X coordinate of the popup menu's location
   * @param y Y coordinate of the popup menu's location
   */
  public void setLocation(int x, int y)
  {
    popupLocationX = x;
    popupLocationY = y;
    // Handle the case when the popup is already showing. In this case we need
    // to fetch a new popup from PopupFactory and use this. See the general
    // contract of the PopupFactory.
  }

  /**
   * Returns popup menu's invoker.
   *
   * @return popup menu's invoker
   */
  public Component getInvoker()
  {
    return invoker;
  }

  /**
   * Sets popup menu's invoker.
   *
   * @param component The new invoker of this popup menu
   */
  public void setInvoker(Component component)
  {
    invoker = component;
  }

  /**
   * This method displays JPopupMenu on the screen at the specified
   * location. Note that x and y coordinates given to this method
   * should be expressed in terms of the popup menus' invoker.
   *
   * @param component Invoker for this popup menu
   * @param x x-coordinate of the popup menu relative to the specified invoker
   * @param y y-coordiate of the popup menu relative to the specified invoker
   */
  public void show(Component component, int x, int y)
  {
    if (component.isShowing())
      {
        setInvoker(component);
        Point p = new Point(x, y);
        SwingUtilities.convertPointToScreen(p, component);
        setLocation(p.x, p.y);
        setVisible(true);
      }
  }

  /**
   * Returns component located at the specified index in the popup menu
   *
   * @param index index of the component to return
   *
   * @return component located at the specified index in the popup menu
   *
   * @deprecated Replaced by getComponent(int)
   */
  public Component getComponentAtIndex(int index)
  {
    return getComponent(index);
  }

  /**
   * Returns index of the specified component in the popup menu
   *
   * @param component Component to look for
   *
   * @return index of the specified component in the popup menu
   */
  public int getComponentIndex(Component component)
  {
    Component[] items = getComponents();

    for (int i = 0; i < items.length; i++)
      {
	if (items[i].equals(component))
	  return i;
      }

    return -1;
  }

  /**
   * Sets size of the popup
   *
   * @param size Dimensions representing new size of the popup menu
   */
  public void setPopupSize(Dimension size)
  {
    super.setSize(size);
  }

  /**
   * Sets size of the popup menu
   *
   * @param width width for the new size
   * @param height height for the new size
   */
  public void setPopupSize(int width, int height)
  {
    super.setSize(width, height);
  }

  /**
   * Selects specified component in this popup menu.
   *
   * @param selected component to select
   */
  public void setSelected(Component selected)
  {
    int index = getComponentIndex(selected);
    selectionModel.setSelectedIndex(index);
  }

  /**
   * Checks if this popup menu paints its border.
   *
   * @return true if this popup menu paints its border and false otherwise.
   */
  public boolean isBorderPainted()
  {
    return borderPainted;
  }

  /**
   * Sets if the border of the popup menu should be
   * painter or not.
   *
   * @param painted true if the border should be painted and false otherwise
   */
  public void setBorderPainted(boolean painted)
  {
    borderPainted = painted;
  }

  /**
   * Returns margin for this popup menu.
   *
   * @return margin for this popup menu.
   */
  public Insets getMargin()
  {
    return margin;
  }

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

  /**
  * 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)
  {
    // Empty Implementation. This method is needed for the implementation
    // of MenuElement interface
  }

  /**
   * Process key 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 processKeyEvent(KeyEvent event, MenuElement[] path,
                              MenuSelectionManager manager)
  {
    // Empty Implementation. This method is needed for the implementation
    // of MenuElement interface
  }

  /**
   * Method of MenuElement Interface. It is invoked when
   * popupMenu's selection has changed
   *
   * @param changed true if this popupMenu is part of current menu
   * hierarchy and false otherwise.
   */
  public void menuSelectionChanged(boolean changed)
  {
    if (! changed)
      setVisible(false);
  }

  /**
   * Return subcomonents of this popup menu. This method returns only
   * components that implement the <code>MenuElement</code> interface.
   *
   * @return array of menu items belonging to this popup menu
   */
  public MenuElement[] getSubElements()
  {
    Component[] items = getComponents();
    ArrayList subElements = new ArrayList();

    for (int i = 0; i < items.length; i++)
      if (items[i] instanceof MenuElement)
	subElements.add(items[i]);

    return (MenuElement[])
      subElements.toArray(new MenuElement[subElements.size()]);
  }

  /**
   * Method of the MenuElement interface. Returns reference to itself.
   *
   * @return Returns reference to itself
   */
  public Component getComponent()
  {
    return this;
  }

  /**
   * Checks if observing mouse event should trigger popup
   * menu to show on the screen.
   *
   * @param event MouseEvent to check
   *
   * @return true if the observing mouse event is popup trigger and false otherwise
   */
  public boolean isPopupTrigger(MouseEvent event)
  {
    return ((PopupMenuUI) getUI()).isPopupTrigger(event);
  }

  /**
   * DOCUMENT ME!
   *
   * @return DOCUMENT ME!
   */
  public AccessibleContext getAccessibleContext()
  {
    if (accessibleContext == null)
      accessibleContext = new AccessibleJPopupMenu();

    return accessibleContext;
  }

  /**
   * This is the separator that can be used in popup menu.
   */
  public static class Separator extends JSeparator
  {
    public Separator()
    {
      super();
    }

    public String getUIClassID()
    {
      return "PopupMenuSeparatorUI";
    }
  }

  protected class AccessibleJPopupMenu extends AccessibleJComponent
  {
    private static final long serialVersionUID = 7423261328879849768L;

    protected AccessibleJPopupMenu()
    {
      // Nothing to do here.
    }

    public AccessibleRole getAccessibleRole()
    {
      return AccessibleRole.POPUP_MENU;
    }
  }

  /* This class resizes popup menu and repaints popup menu appropriately if one
   of item's action has changed */
  private class ActionChangeListener implements PropertyChangeListener
  {
    public void propertyChange(PropertyChangeEvent evt)
    {
      // We used to have a revalidate() and repaint() call here. However I think
      // this is not needed. Instead, a new Popup has to be fetched from the
      // PopupFactory and used here.
    }
  }
}
