/* InputEvent.java -- common superclass of component input events
   Copyright (C) 1999, 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 java.awt.event;

import gnu.java.awt.EventModifier;
import gnu.java.lang.CPStringBuilder;

import java.awt.Component;

/**
 * This is the common superclass for all component input classes. These are
 * passed to listeners before the component, so that listeners can consume
 * the event before it does its default behavior.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @see KeyEvent
 * @see KeyAdapter
 * @see MouseEvent
 * @see MouseAdapter
 * @see MouseMotionAdapter
 * @see MouseWheelEvent
 * @since 1.1
 * @status updated to 1.4
 */
public abstract class InputEvent extends ComponentEvent
{
  /**
   * Compatible with JDK 1.1+.
   */
  private static final long serialVersionUID = -2482525981698309786L;

  /**
   * This is the bit mask which indicates the shift key is down. It is
   * recommended that SHIFT_DOWN_MASK be used instead.
   *
   * @see #SHIFT_DOWN_MASK
   */
  public static final int SHIFT_MASK = 1;

  /**
   * This is the bit mask which indicates the control key is down. It is
   * recommended that CTRL_DOWN_MASK be used instead.
   *
   * @see #CTRL_DOWN_MASK
   */
  public static final int CTRL_MASK = 2;

  /**
   * This is the bit mask which indicates the meta key is down. It is
   * recommended that META_DOWN_MASK be used instead.
   *
   * @see #META_DOWN_MASK
   */
  public static final int META_MASK = 4;

  /**
   * This is the bit mask which indicates the alt key is down. It is
   * recommended that ALT_DOWN_MASK be used instead.
   *
   * @see #ALT_DOWN_MASK
   */
  public static final int ALT_MASK = 8;

  /**
   * This is the bit mask which indicates the alt-graph modifier is in effect.
   * It is recommended that ALT_GRAPH_DOWN_MASK be used instead.
   *
   * @see #ALT_GRAPH_DOWN_MASK
   */
  public static final int ALT_GRAPH_MASK = 0x20;

  /**
   * This bit mask indicates mouse button one is down. It is recommended that
   * BUTTON1_DOWN_MASK be used instead.
   *
   * @see #BUTTON1_DOWN_MASK
   */
  public static final int BUTTON1_MASK = 0x10;

  /**
   * This bit mask indicates mouse button two is down. It is recommended that
   * BUTTON2_DOWN_MASK be used instead.
   *
   * @see #BUTTON2_DOWN_MASK
   */
  public static final int BUTTON2_MASK = 8;

  /**
   * This bit mask indicates mouse button three is down. It is recommended
   * that BUTTON3_DOWN_MASK be used instead.
   *
   * @see #BUTTON3_DOWN_MASK
   */
  public static final int BUTTON3_MASK = 4;

  /**
   * The SHIFT key extended modifier.
   *
   * @since 1.4
   */
  public static final int SHIFT_DOWN_MASK = 0x0040;

  /**
   * The CTRL key extended modifier.
   *
   * @since 1.4
   */
  public static final int CTRL_DOWN_MASK = 0x0080;

  /**
   * The META key extended modifier.
   *
   * @since 1.4
   */
  public static final int META_DOWN_MASK = 0x0100;

  /**
   * The ALT key extended modifier.
   *
   * @since 1.4
   */
  public static final int ALT_DOWN_MASK = 0x0200;

  /**
   * The mouse button1 key extended modifier.
   *
   * @since 1.4
   */
  public static final int BUTTON1_DOWN_MASK = 0x0400;

  /**
   * The mouse button2 extended modifier.
   *
   * @since 1.4
   */
  public static final int BUTTON2_DOWN_MASK = 0x0800;

  /**
   * The mouse button3 extended modifier.
   *
   * @since 1.4
   */
  public static final int BUTTON3_DOWN_MASK = 0x1000;

  /**
   * The ALT_GRAPH key extended modifier.
   *
   * @since 1.4
   */
  public static final int ALT_GRAPH_DOWN_MASK = 0x2000;

  /** The mask to convert new to old, package visible for use in subclasses. */
  static final int CONVERT_MASK
    = EventModifier.NEW_MASK & ~(BUTTON2_DOWN_MASK | BUTTON3_DOWN_MASK);

  /**
   * The timestamp when this event occurred.
   *
   * @see #getWhen()
   * @serial the timestamp
   */
  private final long when;

  /**
   * The old-style modifiers in effect for this event. Package visible
   * for use by subclasses. The old style (bitmask 0x3f) should not be
   * mixed with the new style (bitmasks 0xffffffc0).
   *
   * @see #getModifiers()
   * @see MouseEvent
   * @serial the modifier state, stored in the old style
   */
  int modifiers;

  /**
   * The new-style modifiers in effect for this event. Package visible
   * for use by subclasses. The old style (bitmask 0x3f) should not be
   * mixed with the new style (bitmasks 0xffffffc0).
   *
   * @see #getModifiersEx()
   * @see MouseEvent
   * @serial the modifier state, stored in the new style
   */
  int modifiersEx;

  /**
   * Initializes a new instance of <code>InputEvent</code> with the specified
   * source, id, timestamp, and modifiers. Note that an invalid id leads to
   * unspecified results.
   *
   * @param source the source of the event
   * @param id the event id
   * @param when the timestamp when the event occurred
   * @param modifiers the modifiers in effect for this event, old or new style
   * @throws IllegalArgumentException if source is null
   */
  InputEvent(Component source, int id, long when, int modifiers)
  {
    super(source, id);
    this.when = when;
    this.modifiers = modifiers & EventModifier.OLD_MASK;
    this.modifiersEx = modifiers & EventModifier.NEW_MASK;
  }

  /**
   * This method tests whether or not the shift key was down during the event.
   *
   * @return true if the shift key is down
   */
  public boolean isShiftDown()
  {
    return ((modifiers & SHIFT_MASK) != 0)
      || ((modifiersEx & SHIFT_DOWN_MASK) != 0);
  }

  /**
   * This method tests whether or not the control key was down during the
   * event.
   *
   * @return true if the control key is down
   */
  public boolean isControlDown()
  {
    return ((modifiers & CTRL_MASK) != 0)
      || ((modifiersEx & CTRL_DOWN_MASK) != 0);
  }

  /**
   * This method tests whether or not the meta key was down during the event.
   *
   * @return true if the meta key is down
   */
  public boolean isMetaDown()
  {
    return ((modifiers & META_MASK) != 0)
      || ((modifiersEx & META_DOWN_MASK) != 0);
  }

  /**
   * This method tests whether or not the alt key was down during the event.
   *
   * @return true if the alt key is down
   */
  public boolean isAltDown()
  {
    return ((modifiers & ALT_MASK) != 0)
      || ((modifiersEx & ALT_DOWN_MASK) != 0);
  }

  /**
   * This method tests whether or not the alt-graph modifier was in effect
   * during the event.
   *
   * @return true if the alt-graph modifier is down
   */
  public boolean isAltGraphDown()
  {
    return ((modifiers & ALT_GRAPH_MASK) != 0)
      || ((modifiersEx & ALT_GRAPH_DOWN_MASK) != 0);
  }

  /**
   * This method returns the timestamp when this event occurred.
   *
   * @return the timestamp when this event occurred
   */
  public long getWhen()
  {
    return when;
  }

  /**
   * This method returns the old-style modifiers in effect for this event.
   * Note that this is ambiguous between button2 and alt, and between
   * button3 and meta. Also, code which generated these modifiers tends to
   * only list the modifier that just changed, even if others were down at
   * the time. Consider using getModifiersEx instead. This will be a union
   * of the bit masks defined in this class that are applicable to the event.
   *
   * @return the modifiers in effect for this event
   * @see #getModifiersEx()
   */
  public int getModifiers()
  {
    return modifiers;
  }

  /**
   * Returns the extended modifiers (new-style) for this event. This represents
   * the state of all modal keys and mouse buttons at the time of the event,
   * and does not suffer from the problems mentioned in getModifiers.
   *
   * <p>For an example of checking multiple modifiers, this code will return
   * true only if SHIFT and BUTTON1 were pressed and CTRL was not:
   * <pre>
   * int onmask = InputEvent.SHIFT_DOWN_MASK | InputEvent.BUTTON1_DOWN_MASK;
   * int offmask = InputEvent.CTRL_DOWN_MASK;
   * return (event.getModifiersEx() & (onmask | offmask)) == onmask;
   * </pre>
   *
   * @return the bitwise or of all modifiers pressed during the event
   * @since 1.4
   */
  public int getModifiersEx()
  {
    return modifiersEx;
  }

  /**
   * Consumes this event.  A consumed event is not processed further by the AWT
   * system.
   */
  public void consume()
  {
    consumed = true;
  }

  /**
   * This method tests whether or not this event has been consumed.
   *
   * @return true if this event has been consumed
   */
  public boolean isConsumed()
  {
    return consumed;
  }

  /**
   * Convert the extended modifier bitmask into a String, such as "Shift" or
   * "Ctrl+Button1".
   *
   * XXX Sun claims this can be localized via the awt.properties file - how
   * do we implement that?
   *
   * @param modifiers the modifiers
   * @return a string representation of the modifiers in this bitmask
   * @since 1.4
   */
  public static String getModifiersExText(int modifiers)
  {
    modifiers &= EventModifier.NEW_MASK;
    if (modifiers == 0)
      return "";
    CPStringBuilder s = new CPStringBuilder();
    if ((modifiers & META_DOWN_MASK) != 0)
      s.append("Meta+");
    if ((modifiers & CTRL_DOWN_MASK) != 0)
      s.append("Ctrl+");
    if ((modifiers & ALT_DOWN_MASK) != 0)
      s.append("Alt+");
    if ((modifiers & SHIFT_DOWN_MASK) != 0)
      s.append("Shift+");
    if ((modifiers & ALT_GRAPH_DOWN_MASK) != 0)
      s.append("Alt Graph+");
    if ((modifiers & BUTTON1_DOWN_MASK) != 0)
      s.append("Button1+");
    if ((modifiers & BUTTON2_DOWN_MASK) != 0)
      s.append("Button2+");
    if ((modifiers & BUTTON3_DOWN_MASK) != 0)
      s.append("Button3+");
    return s.substring(0, s.length() - 1);
  }
} // class InputEvent
