// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef UI_EVENTS_EVENT_H_
#define UI_EVENTS_EVENT_H_

#include <cstdint>
#include <memory>
#include <string>
#include <vector>

#include "base/containers/flat_map.h"
#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/time/time.h"
#include "build/build_config.h"
#include "ui/events/event_constants.h"
#include "ui/events/gesture_event_details.h"
#include "ui/events/gestures/gesture_types.h"
#include "ui/events/keycodes/dom/dom_key.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/events/platform_event.h"
#include "ui/events/pointer_details.h"
#include "ui/events/types/event_type.h"
#include "ui/gfx/geometry/point.h"
#include "ui/gfx/geometry/point_conversions.h"
#include "ui/latency/latency_info.h"

namespace gfx {
class Transform;
}

namespace ui {

class CancelModeEvent;
class Event;
class EventTarget;
class KeyEvent;
class LocatedEvent;
class MouseEvent;
class MouseWheelEvent;
class ScrollEvent;
class TouchEvent;

enum class DomCode;

// Note: In order for Clone() to work properly, every concrete class
// transitively inheriting Event must implement Clone() explicitly, even if any
// ancestors have provided an implementation.
class EVENTS_EXPORT Event {
 public:
  using Properties = base::flat_map<std::string, std::vector<uint8_t>>;

  virtual ~Event();

  class DispatcherApi {
   public:
    explicit DispatcherApi(Event* event) : event_(event) {}

    DispatcherApi(const DispatcherApi&) = delete;
    DispatcherApi& operator=(const DispatcherApi&) = delete;

    void set_target(EventTarget* target) { event_->target_ = target; }

    void set_phase(EventPhase phase) { event_->phase_ = phase; }
    void set_result(int result) {
      event_->result_ = static_cast<EventResult>(result);
    }
    void set_time_stamp(base::TimeTicks time) { event_->time_stamp_ = time; }

   private:
    raw_ptr<Event, DanglingUntriaged> event_;
  };

  void SetNativeEvent(const PlatformEvent& event);
  const PlatformEvent& native_event() const { return native_event_; }
  EventType type() const { return type_; }
  // time_stamp represents time since machine was booted.
  const base::TimeTicks time_stamp() const { return time_stamp_; }
  int flags() const { return flags_; }

  // Returns a name for the event, typically used in logging/debugging. This is
  // a convenience for EventTypeName(type()) (EventTypeName() is in
  // event_utils).
  const char* GetName() const;

  // This is only intended to be used externally by classes that are modifying
  // events in an EventRewriter.
  void set_flags(int flags) { flags_ = flags; }

  EventTarget* target() const { return target_; }
  EventPhase phase() const { return phase_; }
  EventResult result() const { return result_; }

  LatencyInfo* latency() { return &latency_; }
  const LatencyInfo* latency() const { return &latency_; }
  void set_latency(const LatencyInfo& latency) { latency_ = latency; }

  int source_device_id() const { return source_device_id_; }
  void set_source_device_id(int id) { source_device_id_ = id; }

  // Sets the properties associated with this Event.
  void SetProperties(const Properties& properties);

  // Returns the properties associated with this event, which may be null.
  // The properties are meant to provide a way to associate arbitrary key/value
  // pairs with Events and not used by Event.
  const Properties* properties() const { return properties_.get(); }

  // By default, events are "cancelable", this means any default processing that
  // the containing abstraction layer may perform can be prevented by calling
  // SetHandled(). SetHandled() or StopPropagation() must not be called for
  // events that are not cancelable.
  bool cancelable() const { return cancelable_; }

  // The following methods return true if the respective keys were pressed at
  // the time the event was created.
  bool IsShiftDown() const { return (flags_ & EF_SHIFT_DOWN) != 0; }
  bool IsControlDown() const { return (flags_ & EF_CONTROL_DOWN) != 0; }
  bool IsAltDown() const { return (flags_ & EF_ALT_DOWN) != 0; }
  bool IsCommandDown() const { return (flags_ & EF_COMMAND_DOWN) != 0; }
  bool IsAltGrDown() const { return (flags_ & EF_ALTGR_DOWN) != 0; }
  bool IsCapsLockOn() const { return (flags_ & EF_CAPS_LOCK_ON) != 0; }

  bool IsSynthesized() const { return (flags_ & EF_IS_SYNTHESIZED) != 0; }

  bool IsCancelModeEvent() const { return type_ == ET_CANCEL_MODE; }

  bool IsKeyEvent() const {
    return type_ == ET_KEY_PRESSED || type_ == ET_KEY_RELEASED;
  }

  bool IsMouseEvent() const {
    return type_ == ET_MOUSE_PRESSED ||
           type_ == ET_MOUSE_DRAGGED ||
           type_ == ET_MOUSE_RELEASED ||
           type_ == ET_MOUSE_MOVED ||
           type_ == ET_MOUSE_ENTERED ||
           type_ == ET_MOUSE_EXITED ||
           type_ == ET_MOUSEWHEEL ||
           type_ == ET_MOUSE_CAPTURE_CHANGED;
  }

  bool IsTouchEvent() const {
    return type_ == ET_TOUCH_RELEASED ||
           type_ == ET_TOUCH_PRESSED ||
           type_ == ET_TOUCH_MOVED ||
           type_ == ET_TOUCH_CANCELLED;
  }

  bool IsGestureEvent() const {
    switch (type_) {
      case ET_GESTURE_SCROLL_BEGIN:
      case ET_GESTURE_SCROLL_END:
      case ET_GESTURE_SCROLL_UPDATE:
      case ET_GESTURE_TAP:
      case ET_GESTURE_DOUBLE_TAP:
      case ET_GESTURE_TAP_CANCEL:
      case ET_GESTURE_TAP_DOWN:
      case ET_GESTURE_TAP_UNCONFIRMED:
      case ET_GESTURE_BEGIN:
      case ET_GESTURE_END:
      case ET_GESTURE_TWO_FINGER_TAP:
      case ET_GESTURE_PINCH_BEGIN:
      case ET_GESTURE_PINCH_END:
      case ET_GESTURE_PINCH_UPDATE:
      case ET_GESTURE_LONG_PRESS:
      case ET_GESTURE_LONG_TAP:
      case ET_GESTURE_SWIPE:
      case ET_GESTURE_SHOW_PRESS:
        // When adding a gesture event which is paired with an event which
        // occurs earlier, add the event to |IsEndingEvent|.
        return true;

      case ET_SCROLL_FLING_CANCEL:
      case ET_SCROLL_FLING_START:
        // These can be ScrollEvents too. EF_FROM_TOUCH determines if they're
        // Gesture or Scroll events.
        return (flags_ & EF_FROM_TOUCH) == EF_FROM_TOUCH;

      default:
        break;
    }
    return false;
  }

  // An ending event is paired with the event which started it. Setting capture
  // should not prevent ending events from getting to their initial target.
  bool IsEndingEvent() const {
    switch (type_) {
      case ET_TOUCH_CANCELLED:
      case ET_GESTURE_TAP_CANCEL:
      case ET_GESTURE_END:
      case ET_GESTURE_SCROLL_END:
      case ET_GESTURE_PINCH_END:
        return true;
      default:
        return false;
    }
  }

  bool IsScrollEvent() const {
    // Flings can be GestureEvents too. EF_FROM_TOUCH determines if they're
    // Gesture or Scroll events.
    return type_ == ET_SCROLL || ((type_ == ET_SCROLL_FLING_START ||
                                   type_ == ET_SCROLL_FLING_CANCEL) &&
                                  !(flags() & EF_FROM_TOUCH));
  }

  bool IsPinchEvent() const {
    return type_ == ET_GESTURE_PINCH_BEGIN ||
           type_ == ET_GESTURE_PINCH_UPDATE || type_ == ET_GESTURE_PINCH_END;
  }

  bool IsScrollGestureEvent() const {
    return type_ == ET_GESTURE_SCROLL_BEGIN ||
           type_ == ET_GESTURE_SCROLL_UPDATE || type_ == ET_GESTURE_SCROLL_END;
  }

  bool IsFlingScrollEvent() const {
    return type_ == ET_SCROLL_FLING_CANCEL || type_ == ET_SCROLL_FLING_START;
  }

  bool IsMouseWheelEvent() const { return type_ == ET_MOUSEWHEEL; }

  bool IsLocatedEvent() const {
    return IsMouseEvent() || IsScrollEvent() || IsTouchEvent() ||
           IsGestureEvent() || type_ == ET_DROP_TARGET_EVENT;
  }

  // Convenience methods to cast |this| to a CancelModeEvent.
  // IsCancelModeEvent() must be true as a precondition to calling these
  // methods.
  CancelModeEvent* AsCancelModeEvent();
  const CancelModeEvent* AsCancelModeEvent() const;

  // Convenience methods to cast |this| to a GestureEvent. IsGestureEvent()
  // must be true as a precondition to calling these methods.
  GestureEvent* AsGestureEvent();
  const GestureEvent* AsGestureEvent() const;

  // Convenience methods to cast |this| to a KeyEvent. IsKeyEvent()
  // must be true as a precondition to calling these methods.
  KeyEvent* AsKeyEvent();
  const KeyEvent* AsKeyEvent() const;

  // Convenience methods to cast |this| to a LocatedEvent. IsLocatedEvent()
  // must be true as a precondition to calling these methods.
  LocatedEvent* AsLocatedEvent();
  const LocatedEvent* AsLocatedEvent() const;

  // Convenience methods to cast |this| to a MouseEvent. IsMouseEvent()
  // must be true as a precondition to calling these methods.
  MouseEvent* AsMouseEvent();
  const MouseEvent* AsMouseEvent() const;

  // Convenience methods to cast |this| to a MouseWheelEvent.
  // IsMouseWheelEvent() must be true as a precondition to calling these
  // methods.
  MouseWheelEvent* AsMouseWheelEvent();
  const MouseWheelEvent* AsMouseWheelEvent() const;

  // Convenience methods to cast |this| to a ScrollEvent. IsScrollEvent()
  // must be true as a precondition to calling these methods.
  ScrollEvent* AsScrollEvent();
  const ScrollEvent* AsScrollEvent() const;

  // Convenience methods to cast |this| to a TouchEvent. IsTouchEvent()
  // must be true as a precondition to calling these methods.
  TouchEvent* AsTouchEvent();
  const TouchEvent* AsTouchEvent() const;

  // Returns true if the event has a valid |native_event_|.
  bool HasNativeEvent() const;

  // Immediately stops the propagation of the event. This must be called only
  // from an EventHandler during an event-dispatch. Any event handler that may
  // be in the list will not receive the event after this is called.
  // Note that StopPropagation() can be called only for cancelable events.
  void StopPropagation();
  bool stopped_propagation() const { return !!(result_ & ER_CONSUMED); }

  // Marks the event as having been handled. A handled event does not reach the
  // next event phase. For example, if an event is handled during the pre-target
  // phase, then the event is dispatched to all pre-target handlers, but not to
  // the target or post-target handlers.
  // Note that SetHandled() can be called only for cancelable events.
  void SetHandled();
  bool handled() const { return result_ != ER_UNHANDLED; }

  // For debugging. Not a stable serialization format.
  virtual std::string ToString() const;

  // Copies an arbitrary event. If you have a typed event (e.g. a MouseEvent)
  // just use its copy constructor.
  //
  // Every concrete class transitively inheriting Event must implement this
  // method, even if any ancestors have provided an implementation.
  virtual std::unique_ptr<Event> Clone() const = 0;

 protected:
  Event(EventType type, base::TimeTicks time_stamp, int flags);
  Event(const PlatformEvent& native_event, EventType type, int flags);
  Event(const Event& copy);
  Event& operator=(const Event& rhs);

  void SetType(EventType type);
  void set_cancelable(bool cancelable) { cancelable_ = cancelable; }

  void set_time_stamp(base::TimeTicks time_stamp) { time_stamp_ = time_stamp; }

 private:
  friend class EventTestApi;

  EventType type_;
  base::TimeTicks time_stamp_;
  LatencyInfo latency_;
  int flags_;
  PlatformEvent native_event_;
  bool delete_native_event_ = false;
  bool cancelable_ = true;
  // Neither Event copy constructor nor the assignment operator copies
  // `target_`, as `target_` should be explicitly set so the setter will be
  // responsible for tracking it.
  raw_ptr<EventTarget, DanglingUntriaged> target_ = nullptr;
  EventPhase phase_ = EP_PREDISPATCH;
  EventResult result_ = ER_UNHANDLED;

  // The device id the event came from, or ED_UNKNOWN_DEVICE if the information
  // is not available.
  int source_device_id_ = ED_UNKNOWN_DEVICE;

  std::unique_ptr<Properties> properties_;
};

class EVENTS_EXPORT CancelModeEvent : public Event {
 public:
  CancelModeEvent();
  ~CancelModeEvent() override;

  // Event:
  std::unique_ptr<Event> Clone() const override;
};

class EVENTS_EXPORT LocatedEvent : public Event {
 public:
  // Convenience function that casts |event| to a LocatedEvent if it is one,
  // otherwise returns null.
  static const LocatedEvent* FromIfValid(const Event* event) {
    return event && event->IsLocatedEvent() ? event->AsLocatedEvent() : nullptr;
  }

  ~LocatedEvent() override;

  float x() const { return location_.x(); }
  float y() const { return location_.y(); }
  void set_location(const gfx::Point& location) {
    location_ = gfx::PointF(location);
  }
  void set_location_f(const gfx::PointF& location) { location_ = location; }
  gfx::Point location() const { return gfx::ToFlooredPoint(location_); }
  const gfx::PointF& location_f() const { return location_; }
  void set_root_location(const gfx::Point& root_location) {
    root_location_ = gfx::PointF(root_location);
  }
  void set_root_location_f(const gfx::PointF& root_location) {
    root_location_ = root_location;
  }
  gfx::Point root_location() const {
    return gfx::ToFlooredPoint(root_location_);
  }
  const gfx::PointF& root_location_f() const { return root_location_; }

  // Transform the locations using |inverted_root_transform| and
  // |inverted_local_transform|. |inverted_local_transform| is only used if
  // the event has a target.
  virtual void UpdateForRootTransform(
      const gfx::Transform& inverted_root_transform,
      const gfx::Transform& inverted_local_transform);

  template <class T>
  void ConvertLocationToTarget(const T* source, const T* target) {
    if (!target || target == source)
      return;
    gfx::Point offset = gfx::ToFlooredPoint(location_);
    T::ConvertPointToTarget(source, target, &offset);
    gfx::Vector2d diff = gfx::ToFlooredPoint(location_) - offset;
    location_ = location_ - diff;
  }

  // Event:
  std::string ToString() const override;

 protected:
  friend class LocatedEventTestApi;

  LocatedEvent(const LocatedEvent& copy);

  explicit LocatedEvent(const PlatformEvent& native_event);

  // Create a new LocatedEvent which is identical to the provided model.
  // If source / target windows are provided, the model location will be
  // converted from |source| coordinate system to |target| coordinate system.
  template <class T>
  LocatedEvent(const LocatedEvent& model, T* source, T* target)
      : Event(model),
        location_(model.location_),
        root_location_(model.root_location_) {
    ConvertLocationToTarget(source, target);
  }

  // Used for synthetic events in testing.
  LocatedEvent(EventType type,
               const gfx::PointF& location,
               const gfx::PointF& root_location,
               base::TimeTicks time_stamp,
               int flags);

  // Location of the event relative to the target window and in the target
  // window's coordinate space. If there is no target this is the same as
  // |root_location_|. Native events may generate float values with sub-pixel
  // precision.
  gfx::PointF location_;

  // Location of the event. What coordinate system this is in depends upon the
  // phase of event dispatch. For client code (meaning EventHandlers) it is
  // generally in screen coordinates, but early on it may be in pixels and
  // relative to a display. Native events may generate float values with
  // sub-pixel precision.
  gfx::PointF root_location_;
};

class EVENTS_EXPORT MouseEvent : public LocatedEvent {
 public:
  // NOTE: On some platforms this will allow an event to be constructed from a
  // void*, see PlatformEvent.
  explicit MouseEvent(const PlatformEvent& native_event);

  // Create a new MouseEvent based on the provided model.
  // Uses the provided |type| and |flags| for the new event.
  // If source / target windows are provided, the model location will be
  // converted from |source| coordinate system to |target| coordinate system.
  template <class T>
  MouseEvent(const MouseEvent& model, T* source, T* target)
      : LocatedEvent(model, source, target),
        changed_button_flags_(model.changed_button_flags_),
        movement_(model.movement_),
        pointer_details_(model.pointer_details_) {}

  template <class T>
  MouseEvent(const MouseEvent& model,
             T* source,
             T* target,
             EventType type,
             int flags)
      : LocatedEvent(model, source, target),
        changed_button_flags_(model.changed_button_flags_),
        movement_(model.movement_),
        pointer_details_(model.pointer_details_) {
    SetType(type);
    set_flags(flags);
  }

  // Note: Use the ctor for MouseWheelEvent if type is ET_MOUSEWHEEL.
  MouseEvent(EventType type,
             const gfx::PointF& location,
             const gfx::PointF& root_location,
             base::TimeTicks time_stamp,
             int flags,
             int changed_button_flags,
             const PointerDetails& pointer_details =
                 PointerDetails(EventPointerType::kMouse, kPointerIdMouse));

  // DEPRECATED: Prefer constructor that takes gfx::PointF.
  MouseEvent(EventType type,
             const gfx::Point& location,
             const gfx::Point& root_location,
             base::TimeTicks time_stamp,
             int flags,
             int changed_button_flags,
             const PointerDetails& pointer_details =
                 PointerDetails(EventPointerType::kMouse, kPointerIdMouse));

  MouseEvent(const MouseEvent& copy);
  ~MouseEvent() override;

  void InitializeNative();

  class DispatcherApi {
   public:
    explicit DispatcherApi(MouseEvent* event) : event_(event) {}

    DispatcherApi(const DispatcherApi&) = delete;
    DispatcherApi& operator=(const DispatcherApi&) = delete;

    // TODO(eirage): convert this to builder pattern.
    void set_movement(const gfx::Vector2dF& movement) {
      event_->movement_ = movement;
      event_->set_flags(event_->flags() | EF_UNADJUSTED_MOUSE);
    }

   private:
    raw_ptr<MouseEvent> event_;
  };

  // Conveniences to quickly test what button is down
  bool IsOnlyLeftMouseButton() const {
    return button_flags() == EF_LEFT_MOUSE_BUTTON;
  }

  bool IsLeftMouseButton() const {
    return (flags() & EF_LEFT_MOUSE_BUTTON) != 0;
  }

  bool IsOnlyMiddleMouseButton() const {
    return button_flags() == EF_MIDDLE_MOUSE_BUTTON;
  }

  bool IsMiddleMouseButton() const {
    return (flags() & EF_MIDDLE_MOUSE_BUTTON) != 0;
  }

  bool IsOnlyRightMouseButton() const {
    return button_flags() == EF_RIGHT_MOUSE_BUTTON;
  }

  bool IsRightMouseButton() const {
    return (flags() & EF_RIGHT_MOUSE_BUTTON) != 0;
  }

  bool IsAnyButton() const { return button_flags() != 0; }

  // Returns the flags for the mouse buttons.
  int button_flags() const {
    return flags() & (EF_LEFT_MOUSE_BUTTON | EF_MIDDLE_MOUSE_BUTTON |
                      EF_RIGHT_MOUSE_BUTTON | EF_BACK_MOUSE_BUTTON |
                      EF_FORWARD_MOUSE_BUTTON);
  }

  // Compares two mouse down events and returns true if the second one should
  // be considered a repeat of the first.
  static bool IsRepeatedClickEvent(const MouseEvent& event1,
                                   const MouseEvent& event2);

  // Get the click count. Can be 1, 2 or 3 for mousedown messages, 0 otherwise.
  int GetClickCount() const;

  // Set the click count for a mousedown message. Can be 1, 2 or 3.
  void SetClickCount(int click_count);

  // Identifies the button that changed. During a press this corresponds to the
  // button that was pressed and during a release this corresponds to the button
  // that was released.
  // NOTE: during a press and release flags() contains the complete set of
  // flags. Use this to determine the button that was pressed or released.
  int changed_button_flags() const { return changed_button_flags_; }

  // Updates the button that changed.
  void set_changed_button_flags(int flags) { changed_button_flags_ = flags; }

  const gfx::Vector2dF& movement() const { return movement_; }

  const PointerDetails& pointer_details() const { return pointer_details_; }

  // Event:
  std::string ToString() const override;
  std::unique_ptr<Event> Clone() const override;

  // Resets the last_click_event_ for unit tests.
  static void ResetLastClickForTest();

 private:
  FRIEND_TEST_ALL_PREFIXES(EventTest, DoubleClickRequiresUniqueTimestamp);
  FRIEND_TEST_ALL_PREFIXES(EventTest, SingleClickRightLeft);

  // Returns the repeat count based on the previous mouse click, if it is
  // recent enough and within a small enough distance.
  static int GetRepeatCount(const MouseEvent& click_event);

  // See description above getter for details.
  int changed_button_flags_;

  // Raw mouse movement value reported from mouse hardware. The value of this is
  // platform dependent and may change depending upon the hardware connected to
  // the device. This field is only set if the flag EF_UNADJUSTED_MOUSE is
  // present (which is the case on windows platforms, and CrOS if the
  // kEnableOrdinalMotion flag is set).
  //
  // TODO(b/171249701): always enable on CrOS.
  gfx::Vector2dF movement_;

  // The most recent user-generated MouseEvent, used to detect double clicks.
  static MouseEvent* last_click_event_;

  // Structure for holding pointer details for implementing PointerEvents API.
  PointerDetails pointer_details_;
};

class ScrollEvent;

class EVENTS_EXPORT MouseWheelEvent : public MouseEvent {
 public:
  // See |offset| for details.
  static const int kWheelDelta;

  explicit MouseWheelEvent(const PlatformEvent& native_event);
  explicit MouseWheelEvent(const ScrollEvent& scroll_event);
  MouseWheelEvent(const MouseEvent& mouse_event, int x_offset, int y_offset);
  MouseWheelEvent(const MouseWheelEvent& copy);
  ~MouseWheelEvent() override;

  template <class T>
  MouseWheelEvent(const MouseWheelEvent& model, T* source, T* target)
      : MouseEvent(model, source, target, model.type(), model.flags()),
        offset_(model.x_offset(), model.y_offset()),
        tick_120ths_(model.tick_120ths()) {}

  // Used for synthetic events in testing and by the gesture recognizer.
  MouseWheelEvent(
      const gfx::Vector2d& offset,
      const gfx::PointF& location,
      const gfx::PointF& root_location,
      base::TimeTicks time_stamp,
      int flags,
      int changed_button_flags,
      const absl::optional<gfx::Vector2d> tick_120ths = absl::nullopt);

  // DEPRECATED: Prefer the constructor that takes gfx::PointF.
  MouseWheelEvent(const gfx::Vector2d& offset,
                  const gfx::Point& location,
                  const gfx::Point& root_location,
                  base::TimeTicks time_stamp,
                  int flags,
                  int changed_button_flags);

  // The amount to scroll. This is not necessarily linearly related to the
  // amount that the wheel moved, due to scroll acceleration.
  // Note: x_offset() > 0/y_offset() > 0 means scroll left/up.
  int x_offset() const { return offset_.x(); }
  int y_offset() const { return offset_.y(); }
  const gfx::Vector2d& offset() const { return offset_; }

  // The amount the wheel(s) moved, in 120ths of a tick.
  const gfx::Vector2d& tick_120ths() const { return tick_120ths_; }

  // Event:
  std::unique_ptr<Event> Clone() const override;

 private:
  gfx::Vector2d offset_;
  gfx::Vector2d tick_120ths_;
};

// NOTE: Pen (stylus) events use TouchEvent with kPen. They were
// originally implemented as MouseEvent but switched to TouchEvent when UX
// decided not to show hover effects for pen.
class EVENTS_EXPORT TouchEvent : public LocatedEvent {
 public:
  explicit TouchEvent(const PlatformEvent& native_event);

  // Create a new TouchEvent which is identical to the provided model.
  // If source / target windows are provided, the model location will be
  // converted from |source| coordinate system to |target| coordinate system.
  template <class T>
  TouchEvent(const TouchEvent& model, T* source, T* target)
      : LocatedEvent(model, source, target),
        unique_event_id_(model.unique_event_id_),
        may_cause_scrolling_(model.may_cause_scrolling_),
        hovering_(false),
        pointer_details_(model.pointer_details_) {}

  TouchEvent(EventType type,
             const gfx::PointF& location,
             const gfx::PointF& root_location,
             base::TimeTicks time_stamp,
             const PointerDetails& pointer_details,
             int flags = 0);

  // DEPRECATED: Prefer the constructor that takes gfx::PointF.
  TouchEvent(EventType type,
             const gfx::Point& location,
             base::TimeTicks time_stamp,
             const PointerDetails& pointer_details,
             int flags = 0);

  TouchEvent(const TouchEvent& copy);

  ~TouchEvent() override;

  // A unique identifier for this event.
  uint32_t unique_event_id() const { return unique_event_id_; }

  void set_may_cause_scrolling(bool causes) { may_cause_scrolling_ = causes; }
  bool may_cause_scrolling() const { return may_cause_scrolling_; }

  void set_hovering(bool hovering) { hovering_ = hovering; }
  bool hovering() const { return hovering_; }

  // Overridden from LocatedEvent.
  void UpdateForRootTransform(
      const gfx::Transform& inverted_root_transform,
      const gfx::Transform& inverted_local_transform) override;

  // Marks the event as not participating in synchronous gesture recognition.
  void DisableSynchronousHandling();
  bool synchronous_handling_disabled() const {
    return !!(result() & ER_DISABLE_SYNC_HANDLING);
  }

  const PointerDetails& pointer_details() const { return pointer_details_; }
  void SetPointerDetailsForTest(const PointerDetails& pointer_details);

  float ComputeRotationAngle() const;

  // Event:
  std::unique_ptr<Event> Clone() const override;

 private:
  // A unique identifier for the touch event.
  // NOTE: this is *not* serialized over mojom, as the number is unique to
  // a particular process, and as mojom may go cross process, to serialize could
  // lead to conflicts.
  uint32_t unique_event_id_;

  // Whether the (unhandled) touch event will produce a scroll event (e.g., a
  // touchmove that exceeds the platform slop region, or a touchend that
  // causes a fling). Defaults to false.
  bool may_cause_scrolling_ = false;

  // True for devices like some pens when they support hovering over
  // digitizer and they send events while hovering.
  bool hovering_ = false;

  // Structure for holding pointer details for implementing PointerEvents API.
  PointerDetails pointer_details_;
};

// A KeyEvent is really two distinct classes, melded together due to the
// DOM legacy of Windows key events: a keystroke event (is_char_ == false),
// or a character event (is_char_ == true).
//
// For a keystroke event,
// -- |bool is_char_| is false.
// -- |EventType Event::type()| can be ET_KEY_PRESSED or ET_KEY_RELEASED.
// -- |DomCode code_| and |int Event::flags()| represent the physical key event.
//    - code_ is a platform-independent representation of the physical key,
//      based on DOM UI Events KeyboardEvent |code| values. It does not
//      vary depending on key layout.
//      http://www.w3.org/TR/DOM-Level-3-Events-code/
//    - Event::flags() provides the active modifiers for the physical key
//      press. Its value reflects the state after the event; that is, for
//      a modifier key, a press includes the corresponding flag and a release
//      does not.
// -- |DomKey key_| provides the meaning (character or action) of the key
//    event, in the context of the active layout and modifiers. It corresponds
//    to DOM UI Events KeyboardEvent |key| values.
//    http://www.w3.org/TR/DOM-Level-3-Events-key/
// -- |KeyboardCode key_code_| supports the legacy web event |keyCode| field,
//    and its VKEY_ values are chosen to match Windows/IE for compatibility.
//    For printable characters, this may or may not be a layout-mapped value,
//    imitating MS Windows: if the mapped key generates a character that has
//    an associated VKEY_ code, then key_code_ is that code; if not, then
//    key_code_ is the unmapped VKEY_ code. For example, US, Greek, Cyrillic,
//    Japanese, etc. all use VKEY_Q for the key beside Tab, while French uses
//    VKEY_A. The stored key_code_ is non-located (e.g. VKEY_SHIFT rather than
//    VKEY_LSHIFT, VKEY_1 rather than VKEY_NUMPAD1).
// -- |uint32_t scan_code_| [IS_OZONE only] supports remapping of the top
//    function row based on a sysfs attribute provided by the kernel. This
//    allows devices to have a custom top row layout and still be able to
//    perform translation back and forth between F-Key and Action-Key. The
//    value of this scan code is device specific.
//
// For a character event,
// -- |bool is_char_| is true.
// -- |EventType Event::type()| is ET_KEY_PRESSED.
// -- |DomCode code_| is DomCode::NONE.
// -- |DomKey key_| is a UTF-16 code point.
// -- |KeyboardCode key_code_| is conflated with the character-valued key_
//    by some code, because both arrive in the wParam field of a Windows event.
//
class EVENTS_EXPORT KeyEvent : public Event {
 public:
  // Create a KeyEvent from a NativeEvent. For Windows this native event can
  // be either a keystroke message (WM_KEYUP/WM_KEYDOWN) or a character message
  // (WM_CHAR). Other systems have only keystroke events.
  explicit KeyEvent(const PlatformEvent& native_event);

  // Create a KeyEvent from a NativeEvent but with mocked flags.
  // This method is necessary for Windows since MSG does not contain all flags.
  KeyEvent(const PlatformEvent& native_event, int event_flags);

  // Create a keystroke event from a legacy KeyboardCode.
  // This should not be used in new code.
  KeyEvent(EventType type,
           KeyboardCode key_code,
           int flags,
           base::TimeTicks time_stamp = base::TimeTicks());

  // Create a fully defined keystroke event.
  KeyEvent(EventType type,
           KeyboardCode key_code,
           DomCode code,
           int flags,
           DomKey key,
           base::TimeTicks time_stamp,
           bool is_char = false);

  // Create a character event.
  KeyEvent(char16_t character,
           KeyboardCode key_code,
           DomCode code,
           int flags,
           base::TimeTicks time_stamp = base::TimeTicks());

  // Used for synthetic events with code of DOM KeyboardEvent (e.g. 'KeyA')
  // See also: ui/events/keycodes/dom/dom_values.txt
  KeyEvent(EventType type, KeyboardCode key_code, DomCode code, int flags);

  KeyEvent(const KeyEvent& rhs);

  KeyEvent& operator=(const KeyEvent& rhs);

  ~KeyEvent() override;

  // Returns true if synthesizing key repeat in InitializeNative is enabled.
  static bool IsSynthesizeKeyRepeatEnabled();

  // Sets whether to enable synthesizing key repeat in InitializeNative().
  static void SetSynthesizeKeyRepeatEnabled(bool enabled);

  void InitializeNative();

  // This bypasses the normal mapping from keystroke events to characters,
  // which allows an I18N virtual keyboard to fabricate a keyboard event that
  // does not have a corresponding KeyboardCode (example: U+00E1 Latin small
  // letter A with acute, U+0410 Cyrillic capital letter A).
  void set_character(char16_t character) {
    key_ = DomKey::FromCharacter(character);
  }

  // Gets the character generated by this key event. It only supports Unicode
  // BMP characters.
  char16_t GetCharacter() const;

  // If this is a keystroke event with key_code_ VKEY_RETURN, returns '\r';
  // otherwise returns the same as GetCharacter().
  char16_t GetUnmodifiedText() const;

  // If the Control key is down in the event, returns a layout-independent
  // character (corresponding to US layout); otherwise returns the same
  // as GetUnmodifiedText().
  char16_t GetText() const;

  // True if this is a character event, false if this is a keystroke event.
  bool is_char() const { return is_char_; }

  bool is_repeat() const { return (flags() & EF_IS_REPEAT) != 0; }

  // Gets the associated (Windows-based) KeyboardCode for this key event.
  // Historically, this has also been used to obtain the character associated
  // with a character event, because both use the Window message 'wParam' field.
  // This should be avoided; if necessary for backwards compatibility, use
  // GetConflatedWindowsKeyCode().
  KeyboardCode key_code() const { return key_code_; }

  // This is only intended to be used externally by classes that are modifying
  // events in an EventRewriter.
  void set_key_code(KeyboardCode key_code) { key_code_ = key_code; }

#if BUILDFLAG(IS_OZONE)
  // The scan code of the physical key. This is used to perform the mapping
  // of top row keys from Actions back to F-Keys on new Chrome OS keyboards
  // that supply the mapping via the kernel.
  uint32_t scan_code() const { return scan_code_; }
  void set_scan_code(uint32_t scan_code) { scan_code_ = scan_code; }
#endif  // BUILDFLAG(IS_OZONE)

  // Returns the same value as key_code(), except that located codes are
  // returned in place of non-located ones (e.g. VKEY_LSHIFT or VKEY_RSHIFT
  // instead of VKEY_SHIFT). This is a hybrid of semantic and physical
  // for legacy DOM reasons.
  KeyboardCode GetLocatedWindowsKeyboardCode() const;

  // For a keystroke event, returns the same value as key_code().
  // For a character event, returns the same value as GetCharacter().
  // This exists for backwards compatibility with Windows key events.
  uint16_t GetConflatedWindowsKeyCode() const;

  // Returns true for [Alt]+<num-pad digit> Unicode alt key codes used by Win.
  // TODO(msw): Additional work may be needed for analogues on other platforms.
  bool IsUnicodeKeyCode() const;

  // Returns the DOM .code (physical key identifier) for a keystroke event.
  DomCode code() const { return code_; }
  std::string GetCodeString() const;

  // Returns the DOM .key (layout meaning) for a keystroke event.
  DomKey GetDomKey() const;

  // Normalizes flags_ so that it describes the state after the event.
  // (Native X11 event flags describe the state before the event.)
  void NormalizeFlags();

  // Event:
  std::string ToString() const override;
  std::unique_ptr<Event> Clone() const override;

 protected:
  friend class KeyEventTestApi;

  // This allows a subclass TranslatedKeyEvent to be a non character event.
  void set_is_char(bool is_char) { is_char_ = is_char; }

 private:
  // Determine key_ on a keystroke event from code_ and flags().
  void ApplyLayout() const;

  // Tells if this is a repeated KeyEvent based on |last_key_event|, which is
  // then updated with the new last KeyEvent address.
  bool IsRepeated(KeyEvent** last_key_event);

  // Returns the pointer for the last processed KeyEvent.
  KeyEvent** GetLastKeyEvent();

  KeyboardCode key_code_;

#if BUILDFLAG(IS_OZONE)
  // The scan code of the physical key on Chrome OS.
  uint32_t scan_code_ = 0;
#endif  // BUILDFLAG(IS_OZONE)

  // DOM KeyboardEvent |code| (e.g. DomCode::US_A, DomCode::SPACE).
  // http://www.w3.org/TR/DOM-Level-3-Events-code/
  //
  // This value represents the physical position in the keyboard and can be
  // converted from / to keyboard scan code like XKB.
  DomCode code_;

  // True if this is a character event, false if this is a keystroke event.
  bool is_char_ = false;

  // TODO(kpschoedel): refactor so that key_ is not mutable.
  // This requires defining the KeyEvent completely at construction rather
  // than lazily under GetCharacter(), which likely also means removing
  // the two 'incomplete' constructors. crbug.com/444045
  //
  // DOM KeyboardEvent |key|
  // http://www.w3.org/TR/DOM-Level-3-Events-key/
  //
  // This value represents the meaning of a key, which is either a Unicode
  // character, or a named DomKey:: value.
  // This is not necessarily initialized when the event is constructed;
  // it may be set only if and when GetCharacter() or GetDomKey() is called.
  mutable DomKey key_ = DomKey::NONE;

  static KeyEvent* last_key_event_;
#if BUILDFLAG(IS_OZONE)
  static KeyEvent* last_ibus_key_event_;
#endif

  static bool synthesize_key_repeat_enabled_;
};

class EVENTS_EXPORT ScrollEvent : public MouseEvent {
 public:
  explicit ScrollEvent(const PlatformEvent& native_event);

  template <class T>
  ScrollEvent(const ScrollEvent& model, T* source, T* target)
      : MouseEvent(model, source, target),
        x_offset_(model.x_offset_),
        y_offset_(model.y_offset_),
        x_offset_ordinal_(model.x_offset_ordinal_),
        y_offset_ordinal_(model.y_offset_ordinal_),
        finger_count_(model.finger_count_),
        momentum_phase_(model.momentum_phase_),
        scroll_event_phase_(model.scroll_event_phase_) {}

  ScrollEvent(EventType type,
              const gfx::PointF& location,
              const gfx::PointF& root_location,
              base::TimeTicks time_stamp,
              int flags,
              float x_offset,
              float y_offset,
              float x_offset_ordinal,
              float y_offset_ordinal,
              int finger_count,
              EventMomentumPhase momentum_phase = EventMomentumPhase::NONE,
              ScrollEventPhase phase = ScrollEventPhase::kNone);

  // DEPRECATED: Prefer the constructor that takes gfx::PointF.
  ScrollEvent(EventType type,
              const gfx::Point& location,
              base::TimeTicks time_stamp,
              int flags,
              float x_offset,
              float y_offset,
              float x_offset_ordinal,
              float y_offset_ordinal,
              int finger_count,
              EventMomentumPhase momentum_phase = EventMomentumPhase::NONE,
              ScrollEventPhase phase = ScrollEventPhase::kNone);

  ScrollEvent(const ScrollEvent& copy);
  ~ScrollEvent() override;

  // Scale the scroll event's offset value.
  // This is useful in the multi-monitor setup where it needs to be scaled
  // to provide a consistent user experience.
  void Scale(const float factor);

  float x_offset() const { return x_offset_; }
  float y_offset() const { return y_offset_; }
  float x_offset_ordinal() const { return x_offset_ordinal_; }
  float y_offset_ordinal() const { return y_offset_ordinal_; }
  int finger_count() const { return finger_count_; }
  EventMomentumPhase momentum_phase() const { return momentum_phase_; }
  ScrollEventPhase scroll_event_phase() const { return scroll_event_phase_; }

  // Event:
  std::string ToString() const override;
  std::unique_ptr<Event> Clone() const override;

 private:
  // Potential accelerated offsets.
  float x_offset_;
  float y_offset_;
  // Unaccelerated offsets.
  float x_offset_ordinal_;
  float y_offset_ordinal_;
  // Number of fingers on the pad.
  int finger_count_;

  // For non-fling events, provides momentum information (e.g. for the case
  // where the device provides continuous event updates during a fling).
  EventMomentumPhase momentum_phase_ = EventMomentumPhase::NONE;

  // Provides phase information if device can provide.
  ScrollEventPhase scroll_event_phase_ = ScrollEventPhase::kNone;
};

class EVENTS_EXPORT GestureEvent : public LocatedEvent {
 public:
  // The constructor takes a default unique_touch_id of zero to support many
  // (80+) existing tests that doesn't care about this id.
  GestureEvent(float x,
               float y,
               int flags,
               base::TimeTicks time_stamp,
               const GestureEventDetails& details,
               uint32_t unique_touch_event_id = 0);

  // Create a new GestureEvent which is identical to the provided model.
  // If source / target windows are provided, the model location will be
  // converted from |source| coordinate system to |target| coordinate system.
  template <typename T>
  GestureEvent(const GestureEvent& model, T* source, T* target)
      : LocatedEvent(model, source, target), details_(model.details_) {}
  GestureEvent(const GestureEvent& copy);
  ~GestureEvent() override;

  const GestureEventDetails& details() const { return details_; }

  uint32_t unique_touch_event_id() const { return unique_touch_event_id_; }

  // Event:
  std::string ToString() const override;
  std::unique_ptr<Event> Clone() const override;

 private:
  GestureEventDetails details_;

  // The unique id of the touch event that caused the gesture event to be
  // dispatched. This field gets a non-zero value only for gestures that are
  // released through TouchDispositionGestureFilter::SendGesture. The gesture
  // events that aren't fired directly in response to processing a touch-event
  // (e.g. timer fired ones), this id is zero. See crbug.com/618738.
  uint32_t unique_touch_event_id_;
};

}  // namespace ui

#endif  // UI_EVENTS_EVENT_H_
