/* 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
