/* MouseEvent.java -- a mouse event
   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;
import java.awt.Point;
import java.awt.PopupMenu;
import java.io.IOException;
import java.io.ObjectInputStream;

/**
 * This event is generated for a mouse event. There are three main categories
 * of mouse events: Regular events include pressing, releasing, and clicking
 * buttons, as well as moving over the boundary of the unobscured portion of
 * a component. Motion events include movement and dragging. Wheel events are
 * covered separately by the subclass MouseWheelEvent.
 *
 * <p>A mouse event is tied to the unobstructed visible component that the
 * mouse cursor was over at the time of the action. The button that was
 * most recently pressed is the only one that shows up in
 * <code>getModifiers</code>, and is returned by <code>getButton</code>,
 * while all buttons that are down show up in <code>getModifiersEx</code>.
 *
 * <p>Drag events may be cut short if native drag-and-drop operations steal
 * the event. Likewise, if a mouse drag exceeds the bounds of a window or
 * virtual device, some platforms may clip the path to fit in the bounds of
 * the component.
 *
 * @author Aaron M. Renn (arenn@urbanophile.com)
 * @author Eric Blake (ebb9@email.byu.edu)
 * @see MouseAdapter
 * @see MouseListener
 * @see MouseMotionAdapter
 * @see MouseMotionListener
 * @see MouseWheelListener
 * @since 1.1
 * @status updated to 1.4
 */
public class MouseEvent extends InputEvent
{
  /**
   * Compatible with JDK 1.1+.
   */
  private static final long serialVersionUID = -991214153494842848L;

  /** This is the first id in the range of event ids used by this class. */
  public static final int MOUSE_FIRST = 500;

  /** This is the last id in the range of event ids used by this class. */
  public static final int MOUSE_LAST = 507;

  /** This event id indicates that the mouse was clicked. */
  public static final int MOUSE_CLICKED = 500;

  /** This event id indicates that the mouse was pressed. */
  public static final int MOUSE_PRESSED = 501;

  /** This event id indicates that the mouse was released. */
  public static final int MOUSE_RELEASED = 502;

  /** This event id indicates that the mouse was moved. */
  public static final int MOUSE_MOVED = 503;

  /** This event id indicates that the mouse entered a component. */
  public static final int MOUSE_ENTERED = 504;

  /** This event id indicates that the mouse exited a component. */
  public static final int MOUSE_EXITED = 505;

  /**
   * This indicates that no button changed state.
   *
   * @see #getButton()
   * @since 1.4
   */
  public static final int NOBUTTON = 0;

  /**
   * This indicates that button 1 changed state.
   *
   * @see #getButton()
   * @since 1.4
   */
  public static final int BUTTON1 = 1;

  /**
   * This indicates that button 2 changed state.
   *
   * @see #getButton()
   * @since 1.4
   */
  public static final int BUTTON2 = 2;

  /**
   * This indicates that button 3 changed state.
   *
   * @see #getButton()
   * @since 1.4
   */
  public static final int BUTTON3 = 3;

  /** This event id indicates that the mouse was dragged over a component. */
  public static final int MOUSE_DRAGGED = 506;

  /**
   * This event id indicates that the mouse wheel was rotated.
   *
   * @since 1.4
   */
  public static final int MOUSE_WHEEL = 507;

  /**
   * The X coordinate of the mouse cursor at the time of the event.
   *
   * @see #getX()
   * @serial the x coordinate
  */
  private int x;

  /**
   * The Y coordinate of the mouse cursor at the time of the event.
   *
   * @see #getY()
   * @serial the y coordinate
   */
  private int y;

  /**
   * The screen position of that mouse event, X coordinate.
   */
  private int absX;

  /**
   * The screen position of that mouse event, Y coordinate.
   */
  private int absY;

  /**
   * The number of clicks that took place. For MOUSE_CLICKED, MOUSE_PRESSED,
   * and MOUSE_RELEASED, this will be at least 1; otherwise it is 0.
   *
   * see #getClickCount()
   * @serial the number of clicks
   */
  private final int clickCount;

  /**
   * Indicates which mouse button changed state. Can only be one of
   * {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or
   * {@link #BUTTON3}.
   *
   * @see #getButton()
   * @since 1.4
   */
  private int button;

  /**
   * Whether or not this event should trigger a popup menu.
   *
   * @see PopupMenu
   * @see #isPopupTrigger()
   * @serial true if this is a popup trigger
   */
  private final boolean popupTrigger;

  /**
   * Initializes a new instance of <code>MouseEvent</code> with the specified
   * information. 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 of when the event occurred
   * @param modifiers the modifier keys during the event, in old or new style
   * @param x the X coordinate of the mouse point
   * @param y the Y coordinate of the mouse point
   * @param clickCount the number of mouse clicks for this event
   * @param popupTrigger true if this event triggers a popup menu
   * @param button the most recent mouse button to change state
   * @throws IllegalArgumentException if source is null or button is invalid
   * @since 1.4
   */
  public MouseEvent(Component source, int id, long when, int modifiers,
                    int x, int y, int clickCount, boolean popupTrigger,
                    int button)
  {
    this(source, id, when, modifiers, x, y, 0, 0, clickCount, popupTrigger,
         button);
  }

  /**
   * Initializes a new instance of <code>MouseEvent</code> with the specified
   * information. 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 of when the event occurred
   * @param modifiers the modifier keys during the event, in old or new style
   * @param x the X coordinate of the mouse point
   * @param y the Y coordinate of the mouse point
   * @param clickCount the number of mouse clicks for this event
   * @param popupTrigger true if this event triggers a popup menu
   * @throws IllegalArgumentException if source is null
   */
  public MouseEvent(Component source, int id, long when, int modifiers,
                    int x, int y, int clickCount, boolean popupTrigger)
  {
    this(source, id, when, modifiers, x, y, clickCount, popupTrigger,
         NOBUTTON);
  }

  /**
   * Creates a new MouseEvent. This is like the other constructors and adds
   * specific absolute coordinates.
   *
   * @param source the source of the event
   * @param id the event id
   * @param when the timestamp of when the event occurred
   * @param modifiers the modifier keys during the event, in old or new style
   * @param x the X coordinate of the mouse point
   * @param y the Y coordinate of the mouse point
   * @param absX the absolute X screen coordinate of this event
   * @param absY the absolute Y screen coordinate of this event
   * @param clickCount the number of mouse clicks for this event
   * @param popupTrigger true if this event triggers a popup menu
   * @param button the most recent mouse button to change state
   *
   * @throws IllegalArgumentException if source is null or button is invalid
   *
   * @since 1.6
   */
  public MouseEvent(Component source, int id, long when, int modifiers,
                    int x, int y, int absX, int absY, int clickCount,
                    boolean popupTrigger, int button)
  {
    super(source, id, when, modifiers);

    this.x = x;
    this.y = y;
    this.clickCount = clickCount;
    this.popupTrigger = popupTrigger;
    this.button = button;
    if (button < NOBUTTON || button > BUTTON3)
      throw new IllegalArgumentException();
    if ((modifiers & EventModifier.OLD_MASK) != 0)
      {
        if ((modifiers & BUTTON1_MASK) != 0)
          this.button = BUTTON1;
        else if ((modifiers & BUTTON2_MASK) != 0)
          this.button = BUTTON2;
        else if ((modifiers & BUTTON3_MASK) != 0)
          this.button = BUTTON3;
      }
    // clear the mouse button modifier masks if this is a button
    // release event.
    if (id == MOUSE_RELEASED)
      this.modifiersEx &= ~(BUTTON1_DOWN_MASK
			    | BUTTON2_DOWN_MASK
			    | BUTTON3_DOWN_MASK);

    this.absX = absX;
    this.absY = absY;
  }

  /**
   * This method returns the X coordinate of the mouse position. This is
   * relative to the source component.
   *
   * @return the x coordinate
   */
  public int getX()
  {
    return x;
  }

  /**
   * This method returns the Y coordinate of the mouse position. This is
   * relative to the source component.
   *
   * @return the y coordinate
   */
  public int getY()
  {
    return y;
  }

  /**
   * @since 1.6
   */
  public Point getLocationOnScreen()
  {
    return new Point(absX, absY);
  }

  /**
   * @since 1.6
   */
  public int getXOnScreen()
  {
    return absX;
  }

  /**
   * @since 1.6
   */
  public int getYOnScreen()
  {
    return absY;
  }

  /**
   * This method returns a <code>Point</code> for the x,y position of
   * the mouse pointer. This is relative to the source component.
   *
   * @return a <code>Point</code> for the event position
   */
  public Point getPoint()
  {
    return new Point(x, y);
  }

  /**
   * Translates the event coordinates by the specified x and y offsets.
   *
   * @param dx the value to add to the X coordinate of this event
   * @param dy the value to add to the Y coordiante of this event
   */
  public void translatePoint(int dx, int dy)
  {
    x += dx;
    y += dy;
  }

  /**
   * This method returns the number of mouse clicks associated with this
   * event.
   *
   * @return the number of mouse clicks for this event
   */
  public int getClickCount()
  {
    return clickCount;
  }

  /**
   * Returns which button, if any, was the most recent to change state. This
   * will be one of {@link #NOBUTTON}, {@link #BUTTON1}, {@link #BUTTON2}, or
   * {@link #BUTTON3}.
   *
   * @return the button that changed state
   * @since 1.4
   */
  public int getButton()
  {
    return button;
  }

  /**
   * This method tests whether or not the event is a popup menu trigger. This
   * should be checked in both MousePressed and MouseReleased to be
   * cross-platform compatible, as different systems have different popup
   * triggers.
   *
   * @return true if the event is a popup menu trigger
   */
  public boolean isPopupTrigger()
  {
    return popupTrigger;
  }

  /**
   * Returns a string describing the modifiers, 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 old-style modifiers to convert to text
   * @return a string representation of the modifiers in this bitmask
   */
  public static String getMouseModifiersText(int modifiers)
  {
    modifiers &= EventModifier.OLD_MASK;
    if ((modifiers & BUTTON2_MASK) != 0)
      modifiers |= BUTTON2_DOWN_MASK;
    if ((modifiers & BUTTON3_MASK) != 0)
      modifiers |= BUTTON3_DOWN_MASK;
    return getModifiersExText(EventModifier.extend(modifiers));
  }

  /**
   * Returns a string identifying this event. This is formatted as the field
   * name of the id type, followed by the (x,y) point, the most recent button
   * changed, modifiers (if any), extModifiers (if any), and clickCount.
   *
   * @return a string identifying this event
   */
  public String paramString()
  {
    CPStringBuilder s = new CPStringBuilder();
    switch (id)
      {
      case MOUSE_CLICKED:
        s.append("MOUSE_CLICKED,(");
        break;
      case MOUSE_PRESSED:
        s.append("MOUSE_PRESSED,(");
        break;
      case MOUSE_RELEASED:
        s.append("MOUSE_RELEASED,(");
        break;
      case MOUSE_MOVED:
        s.append("MOUSE_MOVED,(");
        break;
      case MOUSE_ENTERED:
        s.append("MOUSE_ENTERED,(");
        break;
      case MOUSE_EXITED:
        s.append("MOUSE_EXITED,(");
        break;
      case MOUSE_DRAGGED:
        s.append("MOUSE_DRAGGED,(");
        break;
      case MOUSE_WHEEL:
        s.append("MOUSE_WHEEL,(");
        break;
      default:
        s.append("unknown type,(");
      }
    s.append(x).append(',').append(y).append("),button=").append(button);
    // FIXME: need a mauve test for this method
    if (modifiersEx != 0)
      s.append(",extModifiers=").append(getModifiersExText(modifiersEx));
    
    s.append(",clickCount=").append(clickCount);
    s.append(",consumed=").append(consumed);
    
    return s.toString();
  }

  /**
   * Reads in the object from a serial stream.
   *
   * @param s the stream to read from
   * @throws IOException if deserialization fails
   * @throws ClassNotFoundException if deserialization fails
   * @serialData default, except that the modifiers are converted to new style
   */
  private void readObject(ObjectInputStream s)
    throws IOException, ClassNotFoundException
  {
    s.defaultReadObject();
    if ((modifiers & EventModifier.OLD_MASK) != 0)
      {
        if ((modifiers & BUTTON1_MASK) != 0)
          button = BUTTON1;
        else if ((modifiers & BUTTON2_MASK) != 0)
          button = BUTTON2;
        else if ((modifiers & BUTTON3_MASK) != 0)
          button = BUTTON3;
        modifiersEx = EventModifier.extend(modifiers) & EventModifier.NEW_MASK;
      }
  }
} // class MouseEvent
