/*
 * Copyright (C) 2001 Peter Kelly (pmk@post.com)
 * Copyright (C) 2001 Tobias Anton (anton@stud.fbi.fh-darmstadt.de)
 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights
 * reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_H_

#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/events/event_dispatch_result.h"
#include "third_party/blink/renderer/core/probe/async_task_id.h"
#include "third_party/blink/renderer/platform/bindings/script_wrappable.h"
#include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"

namespace blink {

class DOMWrapperWorld;
class EventDispatcher;
class EventInit;
class EventPath;
class EventTarget;
class ScriptState;
class ScriptValue;

class CORE_EXPORT Event : public ScriptWrappable {
  DEFINE_WRAPPERTYPEINFO();

 public:
  enum class Bubbles {
    kYes,
    kNo,
  };

  enum class Cancelable {
    kYes,
    kNo,
  };

  enum PhaseType {
    kNone = 0,
    kCapturingPhase = 1,
    kAtTarget = 2,
    kBubblingPhase = 3
  };

  enum RailsMode {
    kRailsModeFree = 0,
    kRailsModeHorizontal = 1,
    kRailsModeVertical = 2
  };

  enum class ComposedMode {
    kComposed,
    kScoped,
  };

  enum class PassiveMode {
    // Not passive, default initialized.
    kNotPassiveDefault,
    // Not passive, explicitly specified.
    kNotPassive,
    // Passive, explicitly specified.
    kPassive,
    // Passive, not explicitly specified and forced due to document level
    // listener.
    kPassiveForcedDocumentLevel,
    // Passive, default initialized.
    kPassiveDefault,
  };

  static Event* Create() { return MakeGarbageCollected<Event>(); }

  static Event* Create(const AtomicString& type) {
    return MakeGarbageCollected<Event>(type, Bubbles::kNo, Cancelable::kNo);
  }
  static Event* CreateCancelable(const AtomicString& type) {
    return MakeGarbageCollected<Event>(type, Bubbles::kNo, Cancelable::kYes);
  }
  static Event* CreateBubble(const AtomicString& type) {
    return MakeGarbageCollected<Event>(type, Bubbles::kYes, Cancelable::kNo);
  }
  static Event* CreateCancelableBubble(const AtomicString& type) {
    return MakeGarbageCollected<Event>(type, Bubbles::kYes, Cancelable::kYes);
  }

  static Event* Create(const AtomicString& type, const EventInit* initializer) {
    return MakeGarbageCollected<Event>(type, initializer);
  }

  Event();
  Event(const AtomicString& type,
        Bubbles,
        Cancelable,
        ComposedMode,
        base::TimeTicks platform_time_stamp);
  Event(const AtomicString& type,
        Bubbles,
        Cancelable,
        base::TimeTicks platform_time_stamp);
  Event(const AtomicString& type,
        Bubbles,
        Cancelable,
        ComposedMode = ComposedMode::kScoped);
  Event(const AtomicString& type,
        const EventInit*,
        base::TimeTicks platform_time_stamp);
  Event(const AtomicString& type, const EventInit* init)
      : Event(type, init, base::TimeTicks::Now()) {}
  ~Event() override;

  void initEvent(const AtomicString& type, bool bubbles, bool cancelable);
  void initEvent(const AtomicString& event_type_arg,
                 bool bubbles_arg,
                 bool cancelable_arg,
                 EventTarget* related_target);

  const AtomicString& type() const { return type_; }
  void SetType(const AtomicString& type) { type_ = type; }

  EventTarget* target() const { return target_.Get(); }
  void SetTarget(EventTarget*);

  EventTarget* currentTarget() const;
  void SetCurrentTarget(EventTarget* current_target) {
    current_target_ = current_target;
  }

  // This callback is invoked when an event listener has been dispatched
  // at the current target. It should only be used to influence UMA metrics
  // and not change functionality since observing the presence of listeners
  // is dangerous.
  virtual void DoneDispatchingEventAtCurrentTarget() {}

  void SetRelatedTargetIfExists(EventTarget* related_target);

  uint8_t eventPhase() const { return event_phase_; }
  void SetEventPhase(uint8_t event_phase) { event_phase_ = event_phase; }

  void SetFireOnlyCaptureListenersAtTarget(
      bool fire_only_capture_listeners_at_target) {
    DCHECK_EQ(event_phase_, kAtTarget);
    fire_only_capture_listeners_at_target_ =
        fire_only_capture_listeners_at_target;
  }

  void SetFireOnlyNonCaptureListenersAtTarget(
      bool fire_only_non_capture_listeners_at_target) {
    DCHECK_EQ(event_phase_, kAtTarget);
    fire_only_non_capture_listeners_at_target_ =
        fire_only_non_capture_listeners_at_target;
  }

  bool FireOnlyCaptureListenersAtTarget() const {
    return fire_only_capture_listeners_at_target_;
  }
  bool FireOnlyNonCaptureListenersAtTarget() const {
    return fire_only_non_capture_listeners_at_target_;
  }

  bool bubbles() const { return bubbles_; }
  bool cancelable() const { return cancelable_; }
  bool composed() const { return composed_; }
  bool IsScopedInV0() const;

  // Event creation timestamp in milliseconds. It returns a DOMHighResTimeStamp
  // using the platform timestamp (see |platform_time_stamp_|).
  // For more info see http://crbug.com/160524
  double timeStamp(ScriptState*) const;
  base::TimeTicks PlatformTimeStamp() const { return platform_time_stamp_; }

  void stopPropagation() { propagation_stopped_ = true; }
  void SetStopPropagation(bool stop_propagation) {
    propagation_stopped_ = stop_propagation;
  }
  void stopImmediatePropagation() { immediate_propagation_stopped_ = true; }
  void SetStopImmediatePropagation(bool stop_immediate_propagation) {
    immediate_propagation_stopped_ = stop_immediate_propagation;
  }

  // IE Extensions
  EventTarget* srcElement() const {
    return target();
  }  // MSIE extension - "the object that fired the event"

  bool legacyReturnValue(ScriptState*) const;
  void setLegacyReturnValue(ScriptState*, bool return_value);

  virtual const AtomicString& InterfaceName() const;
  bool HasInterface(const AtomicString&) const;

  // These events are general classes of events.
  virtual bool IsUIEvent() const;
  virtual bool IsMouseEvent() const;
  virtual bool IsFocusEvent() const;
  virtual bool IsKeyboardEvent() const;
  virtual bool IsTouchEvent() const;
  virtual bool IsGestureEvent() const;
  virtual bool IsWheelEvent() const;
  virtual bool IsPointerEvent() const;
  virtual bool IsInputEvent() const;
  virtual bool IsCompositionEvent() const;

  // Drag events are a subset of mouse events.
  virtual bool IsDragEvent() const;

  // These events lack a DOM interface.
  virtual bool IsClipboardEvent() const;
  virtual bool IsBeforeTextInsertedEvent() const;

  virtual bool IsBeforeUnloadEvent() const;
  virtual bool IsErrorEvent() const;

  bool PropagationStopped() const {
    return propagation_stopped_ || immediate_propagation_stopped_;
  }
  bool ImmediatePropagationStopped() const {
    return immediate_propagation_stopped_;
  }
  bool WasInitialized() { return was_initialized_; }

  bool defaultPrevented() const { return default_prevented_; }
  virtual void preventDefault();

  bool DefaultHandled() const { return default_handled_; }
  void SetDefaultHandled() { default_handled_ = true; }

  bool cancelBubble(ScriptState* = nullptr) const {
    return PropagationStopped();
  }
  void setCancelBubble(ScriptState*, bool);

  const Event* UnderlyingEvent() const { return underlying_event_.Get(); }
  void SetUnderlyingEvent(const Event*);

  bool HasEventPath() { return event_path_; }
  EventPath& GetEventPath() const {
    DCHECK(event_path_);
    return *event_path_;
  }
  void InitEventPath(Node&);

  ScriptValue path(ScriptState*) const;
  HeapVector<Member<EventTarget>> composedPath(ScriptState*) const;

  bool IsBeingDispatched() const { return eventPhase(); }

  // Events that must not leak across isolated world, similar to how
  // ErrorEvent behaves, can override this method.
  virtual bool CanBeDispatchedInWorld(const DOMWrapperWorld&) const {
    return true;
  }

  bool isTrusted() const { return is_trusted_; }
  void SetTrusted(bool value) { is_trusted_ = value; }

  void SetComposed(bool composed) {
    DCHECK(!IsBeingDispatched());
    composed_ = composed;
  }

  void SetHandlingPassive(PassiveMode);

  bool PreventDefaultCalledOnUncancelableEvent() const {
    return prevent_default_called_on_uncancelable_event_;
  }

  bool LegacyDidListenersThrow() const {
    return legacy_did_listeners_throw_flag_;
  }

  void LegacySetDidListenersThrowFlag() {
    legacy_did_listeners_throw_flag_ = true;
  }

  void SetCopyEventPathFromUnderlyingEvent() {
    copy_event_path_from_underlying_event_ = true;
  }

  // In general, event listeners do not run when related execution contexts are
  // paused.  However, when this function returns true, event listeners ignore
  // the pause and run.
  virtual bool ShouldDispatchEvenWhenExecutionContextIsPaused() const {
    return false;
  }

  virtual DispatchEventResult DispatchEvent(EventDispatcher&);

  probe::AsyncTaskId* async_task_id() { return &async_task_id_; }

  void Trace(Visitor*) override;

 protected:
  virtual void ReceivedTarget();

  void SetBubbles(bool bubble) { bubbles_ = bubble; }

  PassiveMode HandlingPassive() const { return handling_passive_; }

 private:
  enum EventPathMode { kEmptyAfterDispatch, kNonEmptyAfterDispatch };

  HeapVector<Member<EventTarget>> PathInternal(ScriptState*,
                                               EventPathMode) const;

  AtomicString type_;
  unsigned bubbles_ : 1;
  unsigned cancelable_ : 1;
  unsigned composed_ : 1;
  unsigned is_event_type_scoped_in_v0_ : 1;

  unsigned propagation_stopped_ : 1;
  unsigned immediate_propagation_stopped_ : 1;
  unsigned default_prevented_ : 1;
  unsigned default_handled_ : 1;
  unsigned was_initialized_ : 1;
  unsigned is_trusted_ : 1;

  // Whether preventDefault was called on uncancelable event.
  unsigned prevent_default_called_on_uncancelable_event_ : 1;

  // Whether any of listeners have thrown an exception or not.
  // Corresponds to |legacyOutputDidListenersThrowFlag| in DOM standard.
  // https://dom.spec.whatwg.org/#dispatching-events
  // https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
  unsigned legacy_did_listeners_throw_flag_ : 1;

  unsigned fire_only_capture_listeners_at_target_ : 1;
  unsigned fire_only_non_capture_listeners_at_target_ : 1;

  unsigned copy_event_path_from_underlying_event_ : 1;

  PassiveMode handling_passive_;
  uint8_t event_phase_;
  probe::AsyncTaskId async_task_id_;

  Member<EventTarget> current_target_;
  Member<EventTarget> target_;
  Member<const Event> underlying_event_;
  Member<EventPath> event_path_;
  // The monotonic platform time in seconds, for input events it is the
  // event timestamp provided by the host OS and reported in the original
  // WebInputEvent instance.
  base::TimeTicks platform_time_stamp_;
};

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_DOM_EVENTS_EVENT_H_
