/*
 * Copyright (c) 1996, 2025, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code 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
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package java.awt;

import java.awt.event.ActionEvent;
import java.awt.event.AdjustmentEvent;
import java.awt.event.ComponentEvent;
import java.awt.event.FocusEvent;
import java.awt.event.InputEvent;
import java.awt.event.InputMethodEvent;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.TextEvent;
import java.awt.event.WindowEvent;
import java.awt.peer.ComponentPeer;
import java.awt.peer.LightweightPeer;
import java.io.Serial;
import java.util.EventObject;

import sun.awt.AWTAccessor;

/**
 * The root event class for all AWT events.
 * This class and its subclasses supersede the original
 * java.awt.Event class.
 * Subclasses of this root AWTEvent class defined outside of the
 * java.awt.event package should define event ID values greater than
 * the value defined by RESERVED_ID_MAX.
 * <p>
 * The event masks defined in this class are needed by Component subclasses
 * which are using Component.enableEvents() to select for event types not
 * selected by registered listeners. If a listener is registered on a
 * component, the appropriate event mask is already set internally by the
 * component.
 * <p>
 * The masks are also used to specify to which types of events an
 * AWTEventListener should listen. The masks are bitwise-ORed together
 * and passed to Toolkit.addAWTEventListener.
 *
 * @see Component#enableEvents
 * @see Toolkit#addAWTEventListener
 *
 * @see java.awt.event.ActionEvent
 * @see java.awt.event.AdjustmentEvent
 * @see java.awt.event.ComponentEvent
 * @see java.awt.event.ContainerEvent
 * @see java.awt.event.FocusEvent
 * @see java.awt.event.InputMethodEvent
 * @see java.awt.event.InvocationEvent
 * @see java.awt.event.ItemEvent
 * @see java.awt.event.HierarchyEvent
 * @see java.awt.event.KeyEvent
 * @see java.awt.event.MouseEvent
 * @see java.awt.event.MouseWheelEvent
 * @see java.awt.event.PaintEvent
 * @see java.awt.event.TextEvent
 * @see java.awt.event.WindowEvent
 *
 * @author Carl Quinn
 * @author Amy Fowler
 * @since 1.1
 */
public abstract class AWTEvent extends EventObject {

    /**
     * @serial The private data.
     */
    private byte[] bdata;

    /**
     * The event's id.
     * @serial
     * @see #getID()
     * @see #AWTEvent
     */
    protected int id;

    /**
     * Controls whether or not the event is sent back down to the peer once the
     * source has processed it - false means it's sent to the peer; true means
     * it's not. Semantic events always have a 'true' value since they were
     * generated by the peer in response to a low-level event.
     * @serial
     * @see #consume
     * @see #isConsumed
     */
    protected boolean consumed = false;

    transient boolean focusManagerIsDispatching = false;
    transient boolean isPosted;

    /**
     * Indicates whether this AWTEvent was generated by the system as
     * opposed to by user code.
     */
    private transient boolean isSystemGenerated;

    /**
     * The event mask for selecting component events.
     */
    public static final long COMPONENT_EVENT_MASK = 0x01;

    /**
     * The event mask for selecting container events.
     */
    public static final long CONTAINER_EVENT_MASK = 0x02;

    /**
     * The event mask for selecting focus events.
     */
    public static final long FOCUS_EVENT_MASK = 0x04;

    /**
     * The event mask for selecting key events.
     */
    public static final long KEY_EVENT_MASK = 0x08;

    /**
     * The event mask for selecting mouse events.
     */
    public static final long MOUSE_EVENT_MASK = 0x10;

    /**
     * The event mask for selecting mouse motion events.
     */
    public static final long MOUSE_MOTION_EVENT_MASK = 0x20;

    /**
     * The event mask for selecting window events.
     */
    public static final long WINDOW_EVENT_MASK = 0x40;

    /**
     * The event mask for selecting action events.
     */
    public static final long ACTION_EVENT_MASK = 0x80;

    /**
     * The event mask for selecting adjustment events.
     */
    public static final long ADJUSTMENT_EVENT_MASK = 0x100;

    /**
     * The event mask for selecting item events.
     */
    public static final long ITEM_EVENT_MASK = 0x200;

    /**
     * The event mask for selecting text events.
     */
    public static final long TEXT_EVENT_MASK = 0x400;

    /**
     * The event mask for selecting input method events.
     */
    public static final long INPUT_METHOD_EVENT_MASK = 0x800;

    /**
     * The pseudo event mask for enabling input methods.
     * We're using one bit in the eventMask so we don't need
     * a separate field inputMethodsEnabled.
     */
    static final long INPUT_METHODS_ENABLED_MASK = 0x1000;

    /**
     * The event mask for selecting paint events.
     */
    public static final long PAINT_EVENT_MASK = 0x2000;

    /**
     * The event mask for selecting invocation events.
     */
    public static final long INVOCATION_EVENT_MASK = 0x4000;

    /**
     * The event mask for selecting hierarchy events.
     */
    public static final long HIERARCHY_EVENT_MASK = 0x8000;

    /**
     * The event mask for selecting hierarchy bounds events.
     */
    public static final long HIERARCHY_BOUNDS_EVENT_MASK = 0x10000;

    /**
     * The event mask for selecting mouse wheel events.
     * @since 1.4
     */
    public static final long MOUSE_WHEEL_EVENT_MASK = 0x20000;

    /**
     * The event mask for selecting window state events.
     * @since 1.4
     */
    public static final long WINDOW_STATE_EVENT_MASK = 0x40000;

    /**
     * The event mask for selecting window focus events.
     * @since 1.4
     */
    public static final long WINDOW_FOCUS_EVENT_MASK = 0x80000;

    /**
     * WARNING: there are more mask defined privately.  See
     * SunToolkit.GRAB_EVENT_MASK.
     */

    /**
     * The maximum value for reserved AWT event IDs. Programs defining
     * their own event IDs should use IDs greater than this value.
     */
    public static final int RESERVED_ID_MAX = 1999;

    /**
     * Use serialVersionUID from JDK 1.1 for interoperability.
     */
    @Serial
    private static final long serialVersionUID = -1825314779160409405L;

    static {
        /* ensure that the necessary native libraries are loaded */
        Toolkit.loadLibraries();
        if (!GraphicsEnvironment.isHeadless()) {
            initIDs();
        }
        AWTAccessor.setAWTEventAccessor(
            new AWTAccessor.AWTEventAccessor() {
                public void setPosted(AWTEvent ev) {
                    ev.isPosted = true;
                }

                public void setSystemGenerated(AWTEvent ev) {
                    ev.isSystemGenerated = true;
                }

                public boolean isSystemGenerated(AWTEvent ev) {
                    return ev.isSystemGenerated;
                }

                public byte[] getBData(AWTEvent ev) {
                    return ev.bdata;
                }

                public void setBData(AWTEvent ev, byte[] bdata) {
                    ev.bdata = bdata;
                }

            });
    }

    /**
     * Initialize JNI field and method IDs for fields that may be
     * accessed from C.
     */
    private static native void initIDs();

    /**
     * Constructs an AWTEvent object from the parameters of a 1.0-style event.
     *
     * @param event the old-style event
     * @deprecated It is recommended that {@link #AWTEvent(Object, int)} be used
     *             instead
     */
    @Deprecated(since = "9")
    public AWTEvent(Event event) {
        this(event.target, event.id);
    }

    /**
     * Constructs an AWTEvent object with the specified source object and type.
     *
     * @param source the object where the event originated
     * @param id the event type
     */
    public AWTEvent(Object source, int id) {
        super(source);
        this.id = id;
        switch(id) {
          case ActionEvent.ACTION_PERFORMED:
          case ItemEvent.ITEM_STATE_CHANGED:
          case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
          case TextEvent.TEXT_VALUE_CHANGED:
            consumed = true;
            break;
          default:
        }
    }

    /**
     * Retargets an event to a new source. This method is typically used to
     * retarget an event to a lightweight child Component of the original
     * heavyweight source.
     * <p>
     * This method is intended to be used only by event targeting subsystems,
     * such as client-defined KeyboardFocusManagers. It is not for general
     * client use.
     *
     * @param newSource the new Object to which the event should be dispatched
     * @since 1.4
     */
    public void setSource(Object newSource) {
        if (source == newSource) {
            return;
        }

        Component comp = null;
        if (newSource instanceof Component) {
            comp = (Component)newSource;
            while (comp != null && (comp.peer instanceof LightweightPeer)) {
                comp = comp.parent;
            }
        }

        synchronized (this) {
            source = newSource;
            if (comp != null) {
                ComponentPeer peer = comp.peer;
                if (peer != null) {
                    nativeSetSource(peer);
                }
            }
        }
    }

    private native void nativeSetSource(ComponentPeer peer);

    /**
     * Returns the event type.
     *
     * @return the event's type id
     */
    public int getID() {
        return id;
    }

    /**
     * Returns a String representation of this object.
     */
    public String toString() {
        String srcName = null;
        if (source instanceof Component) {
            srcName = ((Component)source).getName();
        } else if (source instanceof MenuComponent) {
            srcName = ((MenuComponent)source).getName();
        }
        return getClass().getName() + "[" + paramString() + "] on " +
            (srcName != null? srcName : source);
    }

    /**
     * Returns a string representing the state of this {@code Event}.
     * This method is intended to be used only for debugging purposes, and the
     * content and format of the returned string may vary between
     * implementations. The returned string may be empty but may not be
     * {@code null}.
     *
     * @return  a string representation of this event
     */
    public String paramString() {
        return "";
    }

    /**
     * Consumes this event, if this event can be consumed. Only low-level,
     * system events can be consumed
     */
    protected void consume() {
        switch(id) {
          case KeyEvent.KEY_PRESSED:
          case KeyEvent.KEY_RELEASED:
          case MouseEvent.MOUSE_PRESSED:
          case MouseEvent.MOUSE_RELEASED:
          case MouseEvent.MOUSE_MOVED:
          case MouseEvent.MOUSE_DRAGGED:
          case MouseEvent.MOUSE_ENTERED:
          case MouseEvent.MOUSE_EXITED:
          case MouseEvent.MOUSE_WHEEL:
          case InputMethodEvent.INPUT_METHOD_TEXT_CHANGED:
          case InputMethodEvent.CARET_POSITION_CHANGED:
              consumed = true;
              break;
          default:
              // event type cannot be consumed
        }
    }

    /**
     * Returns whether this event has been consumed.
     *
     * @return {@code true} if this event has been consumed;
     *          otherwise {@code false}
     */
    protected boolean isConsumed() {
        return consumed;
    }

    /**
     * Converts a new event to an old one (used for compatibility).
     * If the new event cannot be converted (because no old equivalent
     * exists) then this returns null.
     *
     * Note: this method is here instead of in each individual new
     * event class in java.awt.event because we don't want to make
     * it public and it needs to be called from java.awt.
     */
    @SuppressWarnings("deprecation")
    Event convertToOld() {
        Object src = getSource();
        int newid = id;

        switch(id) {
          case KeyEvent.KEY_PRESSED:
          case KeyEvent.KEY_RELEASED:
              KeyEvent ke = (KeyEvent)this;
              if (ke.isActionKey()) {
                  newid = (id == KeyEvent.KEY_PRESSED?
                           Event.KEY_ACTION : Event.KEY_ACTION_RELEASE);
              }
              int keyCode = ke.getKeyCode();
              if (keyCode == KeyEvent.VK_SHIFT ||
                  keyCode == KeyEvent.VK_CONTROL ||
                  keyCode == KeyEvent.VK_ALT) {
                  return null;  // suppress modifier keys in old event model.
              }
              // no mask for button1 existed in old Event - strip it out
              return new Event(src, ke.getWhen(), newid, 0, 0,
                               Event.getOldEventKey(ke),
                               (ke.getModifiers() & ~InputEvent.BUTTON1_MASK));

          case MouseEvent.MOUSE_PRESSED:
          case MouseEvent.MOUSE_RELEASED:
          case MouseEvent.MOUSE_MOVED:
          case MouseEvent.MOUSE_DRAGGED:
          case MouseEvent.MOUSE_ENTERED:
          case MouseEvent.MOUSE_EXITED:
              MouseEvent me = (MouseEvent)this;
              // no mask for button1 existed in old Event - strip it out
              Event olde = new Event(src, me.getWhen(), newid,
                               me.getX(), me.getY(), 0,
                               (me.getModifiers() & ~InputEvent.BUTTON1_MASK));
              olde.clickCount = me.getClickCount();
              return olde;

          case FocusEvent.FOCUS_GAINED:
              return new Event(src, Event.GOT_FOCUS, null);

          case FocusEvent.FOCUS_LOST:
              return new Event(src, Event.LOST_FOCUS, null);

          case WindowEvent.WINDOW_CLOSING:
          case WindowEvent.WINDOW_ICONIFIED:
          case WindowEvent.WINDOW_DEICONIFIED:
              return new Event(src, newid, null);

          case ComponentEvent.COMPONENT_MOVED:
              if (src instanceof Frame || src instanceof Dialog) {
                  Point p = ((Component)src).getLocation();
                  return new Event(src, 0, Event.WINDOW_MOVED, p.x, p.y, 0, 0);
              }
              break;

          case ActionEvent.ACTION_PERFORMED:
              ActionEvent ae = (ActionEvent)this;
              String cmd;
              if (src instanceof Button) {
                  cmd = ((Button)src).getLabel();
              } else if (src instanceof MenuItem) {
                  cmd = ((MenuItem)src).getLabel();
              } else {
                  cmd = ae.getActionCommand();
              }
              return new Event(src, 0, newid, 0, 0, 0, ae.getModifiers(), cmd);

          case ItemEvent.ITEM_STATE_CHANGED:
              ItemEvent ie = (ItemEvent)this;
              Object arg;
              if (src instanceof List) {
                  newid = (ie.getStateChange() == ItemEvent.SELECTED?
                           Event.LIST_SELECT : Event.LIST_DESELECT);
                  arg = ie.getItem();
              } else {
                  newid = Event.ACTION_EVENT;
                  if (src instanceof Choice) {
                      arg = ie.getItem();

                  } else { // Checkbox
                      arg = Boolean.valueOf(ie.getStateChange() == ItemEvent.SELECTED);
                  }
              }
              return new Event(src, newid, arg);

          case AdjustmentEvent.ADJUSTMENT_VALUE_CHANGED:
              AdjustmentEvent aje = (AdjustmentEvent)this;
              switch(aje.getAdjustmentType()) {
                case AdjustmentEvent.UNIT_INCREMENT:
                  newid = Event.SCROLL_LINE_DOWN;
                  break;
                case AdjustmentEvent.UNIT_DECREMENT:
                  newid = Event.SCROLL_LINE_UP;
                  break;
                case AdjustmentEvent.BLOCK_INCREMENT:
                  newid = Event.SCROLL_PAGE_DOWN;
                  break;
                case AdjustmentEvent.BLOCK_DECREMENT:
                  newid = Event.SCROLL_PAGE_UP;
                  break;
                case AdjustmentEvent.TRACK:
                  if (aje.getValueIsAdjusting()) {
                      newid = Event.SCROLL_ABSOLUTE;
                  }
                  else {
                      newid = Event.SCROLL_END;
                  }
                  break;
                default:
                  return null;
              }
              return new Event(src, newid, Integer.valueOf(aje.getValue()));

          default:
        }
        return null;
    }

    /**
     * Copies all private data from this event into that.
     * Space is allocated for the copied data that will be
     * freed when the that is finalized. Upon completion,
     * this event is not changed.
     */
    void copyPrivateDataInto(AWTEvent that) {
        that.bdata = this.bdata;
        // Copy canAccessSystemClipboard value from this into that.
        if (this instanceof InputEvent && that instanceof InputEvent) {

            AWTAccessor.InputEventAccessor accessor
                    = AWTAccessor.getInputEventAccessor();

            boolean b = accessor.canAccessSystemClipboard((InputEvent) this);
            accessor.setCanAccessSystemClipboard((InputEvent) that, b);
        }
        that.isSystemGenerated = this.isSystemGenerated;
    }

    void dispatched() {
        if (this instanceof InputEvent) {
            AWTAccessor.getInputEventAccessor().
                    setCanAccessSystemClipboard((InputEvent) this, false);
        }
    }
} // class AWTEvent
