/* DefaultButtonModel.java --
   Copyright (C) 2002, 2004, 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.ItemSelectable;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyEvent;
import java.io.Serializable;
import java.util.EventListener;

import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;

/**
 * The default implementation of {@link ButtonModel}.
 * The purpose of this class is to model the dynamic state of an abstract
 * button. The concrete button type holding this state may be a a "toggle"
 * button (checkbox, radio button) or a "push" button (menu button, button).
 * If the model is disabled, only the "selected" property can be changed. An
 * attempt to change the "armed", "rollover" or "pressed" properties  while
 * the model is disabled will be blocked. Any successful (non-blocked) change
 * to the model's properties will trigger the firing of a ChangeEvent. Any
 * change to the "selected" property will trigger the firing of an ItemEvent
 * in addition to ChangeEvent. This is true whether the model is enabled or
 * not. One other state change is special: the transition from "enabled,
 * armed and pressed" to "enabled, armed and not-pressed". This is considered
 * the "trailing edge" of a successful mouse click, and therefore fires an
 * ActionEvent in addition to a ChangeEvent. In all other respects this class
 * is just a container of boolean flags.
 *
 * @author Graydon Hoare (graydon_at_redhat.com)
 */
public class DefaultButtonModel implements ButtonModel, Serializable
{
  /** DOCUMENT ME! */
  private static final long serialVersionUID = -5342609566534980231L;

  /**
   * Indicates that the button is <em>partially</em> committed to being
   * pressed, but not entirely. This usually happens when a user has pressed
   * but not yet released the mouse button.
   */
  public static final int ARMED = 1;

  /**
   * State constant indicating that the button is enabled. Buttons cannot be
   * pressed or selected unless they are enabled.
   */
  public static final int ENABLED = 8;

  /**
   * State constant indicating that the user is holding down the button. When
   * this transitions from true to false, an ActionEvent may be fired,
   * depending on the value of the "armed" property.
   */
  public static final int PRESSED = 4;

  /**
   * State constant indicating that the mouse is currently positioned over the
   * button.
   */
  public static final int ROLLOVER = 16;

  /**
   * State constant indicating that the button is selected. This constant is
   * only meaningful for toggle-type buttons (radio buttons, checkboxes).
   */
  public static final int SELECTED = 2;

  /**
   * Represents the "state properties" (armed, enabled, pressed, rollover and
   * selected) by a bitwise combination of integer constants.
   */
  protected int stateMask = ENABLED;

  /**
   * List of ItemListeners, ChangeListeners, and ActionListeners registered on
   * this model.
   */
  protected EventListenerList listenerList = new EventListenerList();

  /** The single ChangeEvent this model (re)uses to call its ChangeListeners. */
  protected ChangeEvent changeEvent = new ChangeEvent(this);

  /**
   * The group this model belongs to. Only one button in a group may be
   * selected at any given time.
   */
  protected ButtonGroup group;

  /**
   * The key code (one of {@link java.awt.event.KeyEvent} VK_) used to press
   * this button via a keyboard interface.
   */
  protected int mnemonic = KeyEvent.VK_UNDEFINED;

  /**
   * The string used as the "command" property of any ActionEvent this model
   * sends.
   */
  protected String actionCommand;

  /**
   * Creates a new DefaultButtonModel object.
   */
  public DefaultButtonModel()
  {
    // Nothing to do here.
  }

  /**
   * Return <code>null</code>. Use {@link AbstractButton} if you wish to
   * interface with a button via an {@link ItemSelectable} interface.
   *
   * @return <code>null</code>
   */
  public Object[] getSelectedObjects()
  {
    return null;
  }

  /**
   * Returns a specified class of listeners.
   *
   * @param listenerType the type of listener to return
   *
   * @return array of listeners
   */
  public <T extends EventListener> T[] getListeners(Class<T> listenerType)
  {
    return listenerList.getListeners(listenerType);
  }

  /**
   * Add an ActionListener to the model. Usually only called to subscribe an
   * AbstractButton's listener to the model.
   *
   * @param l The listener to add
   */
  public void addActionListener(ActionListener l)
  {
    listenerList.add(ActionListener.class, l);
  }

  /**
   * Remove an ActionListener to the model. Usually only called to unsubscribe
   * an AbstractButton's listener to the model.
   *
   * @param l The listener to remove
   */
  public void removeActionListener(ActionListener l)
  {
    listenerList.remove(ActionListener.class, l);
  }

  /**
   * Returns all registered <code>ActionListener</code> objects.
   *
   * @return array of <code>ActionListener</code> objects
   */
  public ActionListener[] getActionListeners()
  {
    return (ActionListener[]) listenerList.getListeners(ActionListener.class);
  }

  /**
   * Add an ItemListener to the model. Usually only called to subscribe an
   * AbstractButton's listener to the model.
   *
   * @param l The listener to add
   */
  public void addItemListener(ItemListener l)
  {
    listenerList.add(ItemListener.class, l);
  }

  /**
   * Remove an ItemListener to the model. Usually only called to unsubscribe
   * an AbstractButton's listener to the model.
   *
   * @param l The listener to remove
   */
  public void removeItemListener(ItemListener l)
  {
    listenerList.remove(ItemListener.class, l);
  }

  /**
   * Returns all registered <code>ItemListener</code> objects.
   *
   * @return array of <code>ItemListener</code> objects
   */
  public ItemListener[] getItemListeners()
  {
    return (ItemListener[]) listenerList.getListeners(ItemListener.class);
  }

  /**
   * Add a ChangeListener to the model. Usually only called to subscribe an
   * AbstractButton's listener to the model.
   *
   * @param l The listener to add
   */
  public void addChangeListener(ChangeListener l)
  {
    listenerList.add(ChangeListener.class, l);
  }

  /**
   * Remove a ChangeListener to the model. Usually only called to unsubscribe
   * an AbstractButton's listener to the model.
   *
   * @param l The listener to remove
   */
  public void removeChangeListener(ChangeListener l)
  {
    listenerList.remove(ChangeListener.class, l);
  }

  /**
   * Returns all registered <code>ChangeListener</code> objects.
   *
   * @return array of <code>ChangeListener</code> objects
   */
  public ChangeListener[] getChangeListeners()
  {
    return (ChangeListener[]) listenerList.getListeners(ChangeListener.class);
  }

  /**
   * Inform each ItemListener in the {@link #listenerList} that an ItemEvent
   * has occurred. This happens in response to any change to the {@link
   * #stateMask} field.
   *
   * @param e The ItemEvent to fire
   */
  protected void fireItemStateChanged(ItemEvent e)
  {
    ItemListener[] ll = getItemListeners();

    for (int i = 0; i < ll.length; i++)
      ll[i].itemStateChanged(e);
  }

  /**
   * Inform each ActionListener in the {@link #listenerList} that an
   * ActionEvent has occurred. This happens in response to the any change to
   * the {@link #stateMask} field which makes the enabled, armed and pressed
   * properties all simultaneously <code>true</code>.
   *
   * @param e The ActionEvent to fire
   */
  protected void fireActionPerformed(ActionEvent e)
  {
    ActionListener[] ll = getActionListeners();

    for (int i = 0; i < ll.length; i++)
      ll[i].actionPerformed(e);
  }

  /**
   * Inform each ChangeListener in the {@link #listenerList} that a ChangeEvent
   * has occurred. This happens in response to the any change to a property
   * of the model.
   */
  protected void fireStateChanged()
  {
    ChangeListener[] ll = getChangeListeners();

    for (int i = 0; i < ll.length; i++)
      ll[i].stateChanged(changeEvent);
  }

  /**
   * Get the value of the model's "armed" property.
   *
   * @return The current "armed" property
   */
  public boolean isArmed()
  {
    return (stateMask & ARMED) == ARMED;
  }

  /**
   * Set the value of the model's "armed" property.
   *
   * @param a The new "armed" property
   */
  public void setArmed(boolean a)
  {
    // if this call does not represent a CHANGE in state, then return
    if ((a && isArmed()) || (!a && !isArmed()))
      return;
    
    // cannot change ARMED state unless button is enabled
    if (!isEnabled())
      return;

    // make the change
    if (a)
      stateMask = stateMask | ARMED;
    else
      stateMask = stateMask & (~ARMED);

    // notify interested ChangeListeners
    fireStateChanged();
  }

  /**
   * Get the value of the model's "enabled" property.
   *
   * @return The current "enabled" property.
   */
  public boolean isEnabled()
  {
    return (stateMask & ENABLED) == ENABLED;
  }

  /**
   * Set the value of the model's "enabled" property.
   *
   * @param e The new "enabled" property
   */
  public void setEnabled(boolean e)
  {
    // if this call does not represent a CHANGE in state, then return
    if ((e && isEnabled()) || (!e && !isEnabled()))
      return;

    // make the change
    if (e)
      stateMask = stateMask | ENABLED;
    else
      stateMask = stateMask & (~ENABLED) & (~ARMED) & (~PRESSED);

    // notify interested ChangeListeners
    fireStateChanged();
  }

  /**
   * Set the value of the model's "pressed" property.
   *
   * @param p The new "pressed" property
   */
  public void setPressed(boolean p)
  {
    // if this call does not represent a CHANGE in state, then return
    if ((p && isPressed()) || (!p && !isPressed()))
      return;

    // cannot changed PRESSED state unless button is enabled
    if (!isEnabled())
      return;

    // make the change
    if (p)
      stateMask = stateMask | PRESSED;
    else
      stateMask = stateMask & (~PRESSED);

    // if button is armed and was released, fire action event
    if (!p && isArmed())
      fireActionPerformed(new ActionEvent(this, ActionEvent.ACTION_PERFORMED,
                                          actionCommand));

    // notify interested ChangeListeners
    fireStateChanged();
  }

  /**
   * Get the value of the model's "pressed" property.
   *
   * @return The current "pressed" property
   */
  public boolean isPressed()
  {
    return (stateMask & PRESSED) == PRESSED;
  }

  /**
   * Set the value of the model's "rollover" property.
   *
   * @param r The new "rollover" property
   */
  public void setRollover(boolean r)
  {
    // if this call does not represent a CHANGE in state, then return
    if (r == isRollover())
      return;
    
    // cannot set ROLLOVER property unless button is enabled
    if (!isEnabled())
      return;

    // make the change
    if (r)
      stateMask = stateMask | ROLLOVER;
    else
      stateMask = stateMask & (~ROLLOVER);

    // notify interested ChangeListeners
    fireStateChanged();
  }

  /**
   * Set the value of the model's "selected" property.
   *
   * @param s The new "selected" property
   */
  public void setSelected(boolean s)
  {
    // if this call does not represent a CHANGE in state, then return
    if ((s && isSelected()) || (!s && !isSelected()))
      return;
    
    // make the change
    if (s)
      stateMask = stateMask | SELECTED;
    else
      stateMask = stateMask & (~SELECTED);

    // notify interested ChangeListeners
    fireStateChanged();

    // fire ItemStateChanged events
    if (s)
      {
        fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
                                           this, ItemEvent.SELECTED));
        if (group != null)
          group.setSelected(this, true);
      }
    else
      {
        fireItemStateChanged(new ItemEvent(this, ItemEvent.ITEM_STATE_CHANGED,
                                           this, ItemEvent.DESELECTED));
        if (group != null)
          group.setSelected(this, false);
      }
  }

  /**
   * Get the value of the model's "selected" property.
   *
   * @return The current "selected" property
   */
  public boolean isSelected()
  {
    return (stateMask & SELECTED) == SELECTED;
  }

  /**
   * Get the value of the model's "rollover" property.
   *
   * @return The current "rollover" property
   */
  public boolean isRollover()
  {
    return (stateMask & ROLLOVER) == ROLLOVER;
  }

  /**
   * Get the value of the model's "mnemonic" property.
   *
   * @return The current "mnemonic" property
   */
  public int getMnemonic()
  {
    return mnemonic;
  }

  /**
   * Set the value of the model's "mnemonic" property.
   *
   * @param key The new "mnemonic" property
   */
  public void setMnemonic(int key)
  {
    if (mnemonic != key)
      {
        mnemonic = key;
        fireStateChanged();
      }
  }

  /**
   * Set the value of the model's "actionCommand" property. This property is
   * used as the "command" property of the {@link ActionEvent} fired from the
   * model.
   *
   * @param s The new "actionCommand" property.
   */
  public void setActionCommand(String s)
  {
    if (actionCommand != s)
      {
        actionCommand = s;
        fireStateChanged();
      }
  }

  /**
   * Returns the current value of the model's "actionCommand" property.
   *
   * @return The current "actionCommand" property
   */
  public String getActionCommand()
  {
    return actionCommand;
  }

  /**
   * Set the value of the model's "group" property. The model is said to be a
   * member of the {@link ButtonGroup} held in its "group" property, and only
   * one model in a given group can have their "selected" property be
   * <code>true</code> at a time.
   *
   * @param g The new "group" property (<code>null</code> permitted).
   * 
   * @see #getGroup()
   */
  public void setGroup(ButtonGroup g)
  {
    group = g;
  }

  /**
   * Returns the current value of the model's "group" property.
   *
   * @return The value of the "group" property
   * 
   * @see #setGroup(ButtonGroup)
   */
  public ButtonGroup getGroup()
  {
    return group;
  }
}
