// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_DOM_EVENT_TARGET_H_
#define COBALT_DOM_EVENT_TARGET_H_

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_vector.h"
#include "base/memory/weak_ptr.h"
#include "base/tracked_objects.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/base/token.h"
#include "cobalt/base/tokens.h"
#include "cobalt/dom/event.h"
#include "cobalt/dom/event_listener.h"
#include "cobalt/dom/generic_event_handler_reference.h"
#include "cobalt/dom/on_error_event_listener.h"
#include "cobalt/script/exception_state.h"
#include "cobalt/script/script_value.h"
#include "cobalt/script/wrappable.h"

namespace cobalt {
namespace dom {

// The EventTarget interface represents an object that holds event listeners
// and possibly generates events.
// This interface describes methods and properties common to all kinds of
// EventTarget.
//   https://www.w3.org/TR/2014/WD-dom-20140710/#eventtarget
class EventTarget : public script::Wrappable,
                    public base::SupportsWeakPtr<EventTarget> {
 public:
  // EventHandlers are implemented as EventListener?, so use this to
  // differentiate between the two.
  enum Type {
    kAttribute,
    kNotAttribute,
  };

  // Helper enum to decide whether or not onerror event parameters should be
  // unpacked or not (e.g. in the special case of the |window| object).
  // This special handling is described in:
  //   https://html.spec.whatwg.org/#event-handler-attributes
  // (search for "onerror")
  enum UnpackOnErrorEventsBool {
    kUnpackOnErrorEvents,
    kDoNotUnpackOnErrorEvents,
  };

  // The parameter |unpack_onerror_events| can be set to true (e.g. for the
  // |window| object) in order to indicate that the ErrorEvent should have
  // its members unpacked before calling its event handler.  This is to
  // accommodate for a special case in the window.onerror handling.  This
  // special handling
  explicit EventTarget(
      UnpackOnErrorEventsBool onerror_event_parameter_handling =
          kDoNotUnpackOnErrorEvents)
      : unpack_onerror_events_(onerror_event_parameter_handling ==
                               kUnpackOnErrorEvents) {}

  typedef script::ScriptValue<EventListener> EventListenerScriptValue;
  typedef script::ScriptValue<OnErrorEventListener>
      OnErrorEventListenerScriptValue;

  // Web API: EventTarget
  //
  void AddEventListener(const std::string& type,
                        const EventListenerScriptValue& listener,
                        bool use_capture);
  void RemoveEventListener(const std::string& type,
                           const EventListenerScriptValue& listener,
                           bool use_capture);
  bool DispatchEvent(const scoped_refptr<Event>& event,
                     script::ExceptionState* exception_state);

  // Custom, not in any spec.
  //
  // This version of DispatchEvent is intended to be called inside C++ code.  It
  // won't raise any exception.  Any error will be silently ignored.
  virtual bool DispatchEvent(const scoped_refptr<Event>& event);

  // This version of DispatchEvent is intended to be called inside C++ code.  It
  // won't raise any exception.  Any error will be silently ignored.
  void DispatchEventAndRunCallback(const scoped_refptr<Event>& event,
                                   const base::Closure& dispatched_callback);

  // Creates a new event with the given name and calls DispatchEvent with it,
  // and runs dispatched_callback after finish.
  void DispatchEventNameAndRunCallback(
      base::Token event_name, const base::Closure& dispatched_callback);

  // Posts a task on the current message loop to dispatch event by name. It
  // does nothing if there is no current message loop.
  void PostToDispatchEventName(const tracked_objects::Location& location,
                               base::Token event_name);

  // Posts a task on the current message loop to dispatch event. It does nothing
  // if there is no current message loop.
  void PostToDispatchEvent(const tracked_objects::Location& location,
                           const scoped_refptr<Event>& event);

  // Posts a task on the current message loop to dispatch event by name, and
  // runs dispatched_callback after finish. It does nothing if there is no
  // current message loop.
  void PostToDispatchEventNameAndRunCallback(
      const tracked_objects::Location& location, base::Token event_name,
      const base::Closure& dispatched_callback);

  // Posts a task on the current message loop to dispatch event, and runs
  // dispatched_callback after finish.  It does nothing if there is no current
  // message loop.
  void PostToDispatchEventAndRunCallback(
      const tracked_objects::Location& location,
      const scoped_refptr<Event>& event,
      const base::Closure& dispatched_callback);

  // Check if target has event listener (atrtibute or not attribute).
  bool HasEventListener(base::Token type);

  // Web API: GlobalEventHandlers (implements)
  // Many objects can have event handlers specified. These act as non-capture
  // event listeners for the object on which they are specified.
  //   https://www.w3.org/TR/html5/webappapis.html#globaleventhandlers
  //
  const EventListenerScriptValue* onblur() {
    return GetAttributeEventListener(base::Tokens::blur());
  }
  void set_onblur(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::blur(), event_listener);
  }

  const EventListenerScriptValue* onclick() {
    return GetAttributeEventListener(base::Tokens::click());
  }
  void set_onclick(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::click(), event_listener);
  }

  const OnErrorEventListenerScriptValue* onerror() {
    return GetAttributeOnErrorEventListener(base::Tokens::error());
  }
  void set_onerror(const OnErrorEventListenerScriptValue& event_listener) {
    SetAttributeOnErrorEventListener(base::Tokens::error(), event_listener);
  }

  const EventListenerScriptValue* onfocus() {
    return GetAttributeEventListener(base::Tokens::focus());
  }
  void set_onfocus(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::focus(), event_listener);
  }

  const EventListenerScriptValue* onkeydown() {
    return GetAttributeEventListener(base::Tokens::keydown());
  }
  void set_onkeydown(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::keydown(), event_listener);
  }

  const EventListenerScriptValue* onkeypress() {
    return GetAttributeEventListener(base::Tokens::keypress());
  }
  void set_onkeypress(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::keypress(), event_listener);
  }

  const EventListenerScriptValue* onkeyup() {
    return GetAttributeEventListener(base::Tokens::keyup());
  }
  void set_onkeyup(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::keyup(), event_listener);
  }

  const EventListenerScriptValue* onload() {
    return GetAttributeEventListener(base::Tokens::load());
  }
  void set_onload(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::load(), event_listener);
  }

  const EventListenerScriptValue* onloadeddata() {
    return GetAttributeEventListener(base::Tokens::loadeddata());
  }
  void set_onloadeddata(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::loadeddata(), event_listener);
  }

  const EventListenerScriptValue* onloadedmetadata() {
    return GetAttributeEventListener(base::Tokens::loadedmetadata());
  }
  void set_onloadedmetadata(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::loadedmetadata(), event_listener);
  }

  const EventListenerScriptValue* onloadstart() {
    return GetAttributeEventListener(base::Tokens::loadstart());
  }
  void set_onloadstart(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::loadstart(), event_listener);
  }

  const EventListenerScriptValue* onmousedown() {
    return GetAttributeEventListener(base::Tokens::mousedown());
  }
  void set_onmousedown(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::mousedown(), event_listener);
  }

  const EventListenerScriptValue* onmouseenter() {
    return GetAttributeEventListener(base::Tokens::mouseenter());
  }
  void set_onmouseenter(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::mouseenter(), event_listener);
  }

  const EventListenerScriptValue* onmouseleave() {
    return GetAttributeEventListener(base::Tokens::mouseleave());
  }
  void set_onmouseleave(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::mouseleave(), event_listener);
  }

  const EventListenerScriptValue* onmousemove() {
    return GetAttributeEventListener(base::Tokens::mousemove());
  }
  void set_onmousemove(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::mousemove(), event_listener);
  }

  const EventListenerScriptValue* onmouseout() {
    return GetAttributeEventListener(base::Tokens::mouseout());
  }
  void set_onmouseout(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::mouseout(), event_listener);
  }

  const EventListenerScriptValue* onmouseover() {
    return GetAttributeEventListener(base::Tokens::mouseover());
  }
  void set_onmouseover(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::mouseover(), event_listener);
  }

  const EventListenerScriptValue* onmouseup() {
    return GetAttributeEventListener(base::Tokens::mouseup());
  }
  void set_onmouseup(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::mouseup(), event_listener);
  }

  const EventListenerScriptValue* onpause() {
    return GetAttributeEventListener(base::Tokens::pause());
  }
  void set_onpause(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pause(), event_listener);
  }

  const EventListenerScriptValue* onplay() {
    return GetAttributeEventListener(base::Tokens::play());
  }
  void set_onplay(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::play(), event_listener);
  }

  const EventListenerScriptValue* onplaying() {
    return GetAttributeEventListener(base::Tokens::playing());
  }
  void set_onplaying(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::playing(), event_listener);
  }

  const EventListenerScriptValue* onresize() {
    return GetAttributeEventListener(base::Tokens::resize());
  }
  void set_onresize(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::resize(), event_listener);
  }

  const EventListenerScriptValue* onscroll() {
    return GetAttributeEventListener(base::Tokens::scroll());
  }
  void set_onscroll(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::scroll(), event_listener);
  }

  const EventListenerScriptValue* ongotpointercapture() {
    return GetAttributeEventListener(base::Tokens::gotpointercapture());
  }
  void set_ongotpointercapture(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::gotpointercapture(),
                              event_listener);
  }

  const EventListenerScriptValue* onlostpointercapture() {
    return GetAttributeEventListener(base::Tokens::lostpointercapture());
  }
  void set_onlostpointercapture(
      const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::lostpointercapture(),
                              event_listener);
  }

  const EventListenerScriptValue* onpointerdown() {
    return GetAttributeEventListener(base::Tokens::pointerdown());
  }
  void set_onpointerdown(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pointerdown(), event_listener);
  }

  const EventListenerScriptValue* onpointerenter() {
    return GetAttributeEventListener(base::Tokens::pointerenter());
  }
  void set_onpointerenter(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pointerenter(), event_listener);
  }

  const EventListenerScriptValue* onpointerleave() {
    return GetAttributeEventListener(base::Tokens::pointerleave());
  }
  void set_onpointerleave(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pointerleave(), event_listener);
  }

  const EventListenerScriptValue* onpointermove() {
    return GetAttributeEventListener(base::Tokens::pointermove());
  }
  void set_onpointermove(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pointermove(), event_listener);
  }

  const EventListenerScriptValue* onpointerout() {
    return GetAttributeEventListener(base::Tokens::pointerout());
  }
  void set_onpointerout(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pointerout(), event_listener);
  }

  const EventListenerScriptValue* onpointerover() {
    return GetAttributeEventListener(base::Tokens::pointerover());
  }
  void set_onpointerover(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pointerover(), event_listener);
  }

  const EventListenerScriptValue* onpointerup() {
    return GetAttributeEventListener(base::Tokens::pointerup());
  }
  void set_onpointerup(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::pointerup(), event_listener);
  }

  const EventListenerScriptValue* onprogress() {
    return GetAttributeEventListener(base::Tokens::progress());
  }
  void set_onprogress(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::progress(), event_listener);
  }

  const EventListenerScriptValue* onratechange() {
    return GetAttributeEventListener(base::Tokens::ratechange());
  }
  void set_onratechange(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::ratechange(), event_listener);
  }

  const EventListenerScriptValue* onseeked() {
    return GetAttributeEventListener(base::Tokens::seeked());
  }
  void set_onseeked(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::seeked(), event_listener);
  }

  const EventListenerScriptValue* onseeking() {
    return GetAttributeEventListener(base::Tokens::seeking());
  }
  void set_onseeking(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::seeking(), event_listener);
  }

  const EventListenerScriptValue* ontimeupdate() {
    return GetAttributeEventListener(base::Tokens::timeupdate());
  }
  void set_ontimeupdate(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::timeupdate(), event_listener);
  }

  const EventListenerScriptValue* onbeforeunload() {
    return GetAttributeEventListener(base::Tokens::beforeunload());
  }
  void set_onbeforeunload(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::beforeunload(), event_listener);
  }

  const EventListenerScriptValue* ontransitionend() {
    return GetAttributeEventListener(base::Tokens::transitionend());
  }
  void set_ontransitionend(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::transitionend(), event_listener);
  }

  const EventListenerScriptValue* onunload() {
    return GetAttributeEventListener(base::Tokens::unload());
  }
  void set_onunload(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::unload(), event_listener);
  }

  const EventListenerScriptValue* onvolumechange() {
    return GetAttributeEventListener(base::Tokens::volumechange());
  }
  void set_onvolumechange(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::volumechange(), event_listener);
  }

  const EventListenerScriptValue* onwaiting() {
    return GetAttributeEventListener(base::Tokens::waiting());
  }
  void set_onwaiting(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::waiting(), event_listener);
  }

  const EventListenerScriptValue* onwheel() {
    return GetAttributeEventListener(base::Tokens::wheel());
  }
  void set_onwheel(const EventListenerScriptValue& event_listener) {
    SetAttributeEventListener(base::Tokens::wheel(), event_listener);
  }

  // Set an event listener assigned as an attribute. Overwrite the existing one
  // if there is any.
  void SetAttributeEventListener(base::Token type,
                                 const EventListenerScriptValue& listener);

  // Get the event listener currently assigned to an attribute, or NULL if
  // there is none.
  const EventListenerScriptValue* GetAttributeEventListener(
      base::Token type) const;

  // Similar to SetAttributeEventListener(), but this function should only
  // be called with type == base::Tokens::error().
  void SetAttributeOnErrorEventListener(
      base::Token type, const OnErrorEventListenerScriptValue& listener);

  // Similar to GetAttributeEventListener(), but this function should only
  // be called with type == base::Tokens::error().
  const OnErrorEventListenerScriptValue* GetAttributeOnErrorEventListener(
      base::Token type) const;

  // Return true if one or more event listeners are registered
  bool HasOneOrMoreAttributeEventListener() const;

  // Returns a string that represents the target for debug purpose.
  virtual std::string GetDebugName() { return ""; }

  // This function sends the event to the event listeners attached to the
  // current event target. It takes stop immediate propagation flag into
  // account. The caller should set the phase and target.
  void FireEventOnListeners(const scoped_refptr<Event>& event);

  DEFINE_WRAPPABLE_TYPE(EventTarget);
  void TraceMembers(script::Tracer* tracer) override;

 private:
  struct EventListenerInfo {
    EventListenerInfo(base::Token type,
                      scoped_ptr<GenericEventHandlerReference> listener,
                      bool use_capture, Type listener_type);
    ~EventListenerInfo();

    base::Token type;
    scoped_ptr<GenericEventHandlerReference> listener;
    bool use_capture;
    Type listener_type;
  };
  typedef ScopedVector<EventListenerInfo> EventListenerInfos;

  void SetAttributeEventListenerInternal(
      base::Token type, scoped_ptr<GenericEventHandlerReference> event_handler);
  GenericEventHandlerReference* GetAttributeEventListenerInternal(
      base::Token type) const;

  void AddEventListenerInternal(
      base::Token type, scoped_ptr<GenericEventHandlerReference> listener,
      bool use_capture, Type listener_type);

  EventListenerInfos event_listener_infos_;

  // Tracks whether this current event listener should unpack the onerror
  // event object when calling its callback.  This is needed to implement
  // the special case of window.onerror handling.
  bool unpack_onerror_events_;
};

}  // namespace dom
}  // namespace cobalt

#endif  // COBALT_DOM_EVENT_TARGET_H_
