// Copyright 2014 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_ELEMENT_H_
#define COBALT_DOM_ELEMENT_H_

#include <string>

#include "base/containers/hash_tables.h"
#include "base/containers/small_map.h"
#include "base/memory/weak_ptr.h"
#include "base/optional.h"
#include "base/strings/string_piece.h"
#include "cobalt/base/token.h"
#include "cobalt/cssom/style_sheet_list.h"
#include "cobalt/dom/dom_exception.h"
#include "cobalt/dom/element_intersection_observer_module.h"
#include "cobalt/dom/intersection_observer.h"
#include "cobalt/dom/node.h"
#include "cobalt/script/exception_state.h"
#include "cobalt/web_animations/animation_set.h"

namespace cobalt {
namespace dom {

class DOMRect;
class DOMRectList;
class DOMTokenList;
class HTMLCollection;
class HTMLElement;
class HTMLElementContext;
class NamedNodeMap;

// The Element interface represents an object of a Document. This interface
// describes methods and properties common to all kinds of elements.
//   https://www.w3.org/TR/2014/WD-dom-20140710/#interface-element
class Element : public Node {
 public:
  // NOTE1: The array size of base::small_map and the decision to use
  // base::hash_map as the underlying container type are based on extensive
  // performance testing. Do not change these unless additional profiling data
  // justifies it.
  // NOTE2: Using base::small_map rather than base::hash_map also results in
  // substantial memory gains when live videos are played. These videos trigger
  // the creation of XML documents with over 20k elements, of which over 99%
  // contain a single attribute. By using base::small_map, these single
  // attribute elements are contained within arrays rather than hash_maps.
  typedef base::small_map<std::unordered_map<std::string, std::string>, 1>
      AttributeMap;

  explicit Element(Document* document);
  Element(Document* document, base::Token local_name);

  // Web API: Node
  //
  base::Token node_name() const override { return tag_name(); }
  NodeType node_type() const override { return Node::kElementNode; }

  base::Optional<std::string> text_content() const override;
  void set_text_content(
      const base::Optional<std::string>& text_content) override;

  bool HasAttributes() const override;

  // Web API: Element
  //
  base::Token local_name() const { return local_name_; }

  base::Token tag_name() const;

  base::Token id() const { return id_attribute_; }
  void set_id(const std::string& value) { SetAttribute("id", value); }

  std::string class_name() const { return GetAttribute("class").value_or(""); }
  void set_class_name(const std::string& value) {
    SetAttribute("class", value);
  }

  const scoped_refptr<DOMTokenList>& class_list();
  scoped_refptr<NamedNodeMap> attributes();

  base::Optional<std::string> GetAttribute(const std::string& name) const;
  void SetAttribute(const std::string& name, const std::string& value);
  void RemoveAttribute(const std::string& name);
  bool HasAttribute(const std::string& name) const;

  base::Optional<std::string> GetAttributeNS(const std::string& namespace_uri,
                                             const std::string& name) const;
  bool HasAttributeNS(const std::string& namespace_uri,
                      const std::string& name) const;
  bool Matches(const std::string& selectors,script::ExceptionState* exception_state);

  scoped_refptr<HTMLCollection> GetElementsByTagName(
      const std::string& local_name) const;
  scoped_refptr<HTMLCollection> GetElementsByClassName(
      const std::string& class_name) const;

  // Web API: CSSOM View Module: Extensions to the Element Interface (partial
  // interface)
  //   https://www.w3.org/TR/2013/WD-cssom-view-20131217/#extensions-to-the-element-interface
  scoped_refptr<DOMRect> GetBoundingClientRect();
  virtual scoped_refptr<DOMRectList> GetClientRects();
  virtual float client_top();
  virtual float client_left();
  virtual float client_width();
  virtual float client_height();

  // Updated version of the CSSOM View Module extensions:
  //   https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface
  // If the element does not have any associated CSS layout box return zero.
  virtual int32 scroll_width() { return 0; }
  virtual int32 scroll_height() { return 0; }
  virtual float scroll_left() { return 0.0f; }
  virtual float scroll_top() { return 0.0f; }

  // If the element does not have any associated CSS layout box, the element
  // has no associated scrolling box, or the element has no overflow, terminate
  // these steps.
  virtual void set_scroll_left(float /* x */) {}
  virtual void set_scroll_top(float /* y */) {}

  // Web API: DOM Parsing and Serialization (partial interface)
  //   https://www.w3.org/TR/DOM-Parsing/#extensions-to-the-element-interface
  //
  std::string inner_html() const;
  void set_inner_html(const std::string& inner_html);
  std::string outer_html(script::ExceptionState* exception_state) const;
  void set_outer_html(const std::string& outer_html,
                      script::ExceptionState* exception_state);

  // Web API: Pointer Events: Extensions to the Element Interface (partial
  // interface)
  //   https://www.w3.org/TR/2015/REC-pointerevents-20150224/#extensions-to-the-element-interface
  void SetPointerCapture(int32_t pointer_id,
                         script::ExceptionState* exception_state);
  void ReleasePointerCapture(int32_t pointer_id,
                             script::ExceptionState* exception_state);
  bool HasPointerCapture(int32_t pointer_id);

  // Custom, not in any spec: Node.
  //
  Element* AsElement() override { return this; }

  void Accept(NodeVisitor* visitor) override;
  void Accept(ConstNodeVisitor* visitor) const override;

  scoped_refptr<Node> Duplicate() const override;

  // Custom, not in any spec.
  //

  // Returns whether the element has no children at all except comments or
  // processing instructions.
  //   https://www.w3.org/TR/selectors4/#empty-pseudo
  bool IsEmpty();

  // Returns whether the element has focus.
  //   https://www.w3.org/TR/selectors4/#focus-pseudo
  bool HasFocus();

  // Returns a map that holds the actual attributes of the element.
  const AttributeMap& attribute_map() const { return attribute_map_; }

  // These are called when the element is generated by the parser, rather than
  // by javascript.
  // opening_tag_location points to ">" of opening tag.
  virtual void OnParserStartTag(
      const base::SourceLocation& opening_tag_location) {
    SB_UNREFERENCED_PARAMETER(opening_tag_location);
  }
  virtual void OnParserEndTag() {}

  // Used to ensure that the style attribute value reflects the style
  // declaration.
  //   https://www.w3.org/TR/html50/dom.html#the-style-attribute
  virtual base::Optional<std::string> GetStyleAttribute() const;
  virtual void SetStyleAttribute(const std::string& value);
  virtual void RemoveStyleAttribute();

  // Adds all style sheets contained within the this element and its descendants
  // to the style sheet vector. The style sheets are added in depth-first
  // pre-order.
  void CollectStyleSheetsOfElementAndDescendants(
      cssom::StyleSheetVector* style_sheets) const;

  virtual scoped_refptr<HTMLElement> AsHTMLElement();

  const scoped_refptr<web_animations::AnimationSet>& animations() {
    return animations_;
  }

  void RegisterIntersectionObserverRoot(IntersectionObserver* observer);
  void UnregisterIntersectionObserverRoot(IntersectionObserver* observer);
  void RegisterIntersectionObserverTarget(IntersectionObserver* observer);
  void UnregisterIntersectionObserverTarget(IntersectionObserver* observer);
  ElementIntersectionObserverModule::LayoutIntersectionObserverRootVector
  GetLayoutIntersectionObserverRoots();
  ElementIntersectionObserverModule::LayoutIntersectionObserverTargetVector
  GetLayoutIntersectionObserverTargets();

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

 protected:
  ~Element() override;

  // Getting and setting boolean attribute.
  //   https://www.w3.org/TR/html50/infrastructure.html#boolean-attribute
  bool GetBooleanAttribute(const std::string& name) const;
  void SetBooleanAttribute(const std::string& name, bool value);

  void CopyAttributes(const Element& other);

  HTMLElementContext* html_element_context();

 private:
  // From EventTarget.
  std::string GetDebugName() override;

  virtual void OnSetAttribute(const std::string& /* name */,
                              const std::string& /* value */) {}
  virtual void OnRemoveAttribute(const std::string& /* name */) {}

  // Adds this element's style sheet to the style sheet vector. By default, this
  // function does nothing, but is implemented by element subclasses that
  // generate style sheets (HTMLStyleElement and HTMLLinkElement).
  virtual void CollectStyleSheet(
      cssom::StyleSheetVector* /*style_sheets*/) const {}

  // Callback for error when parsing inner / outer HTML.
  void HTMLParseError(const std::string& error);

  void EnsureIntersectionObserverModuleInitialized();

  // Local name of the element.
  base::Token local_name_;
  // A map that holds the actual element attributes.
  AttributeMap attribute_map_;
  // The "id" attribute for this element. Stored here in addition to being
  // stored in |attribute_map_| as an optimization for id().
  base::Token id_attribute_;
  // A weak pointer to a NamedNodeMap that proxies the actual attributes.
  // This heavy weight object is kept in memory only when needed by the user.
  base::WeakPtr<NamedNodeMap> named_node_map_;
  // Lazily created list of CSS classes.
  // After creation this is kept in memory because of the significant negative
  // performance impact of repeatedly recreating it.
  scoped_refptr<DOMTokenList> class_list_;

  // A set of all animations currently applied to this element.
  scoped_refptr<web_animations::AnimationSet> animations_;

  std::unique_ptr<ElementIntersectionObserverModule>
      element_intersection_observer_module_;
};

}  // namespace dom
}  // namespace cobalt

#endif  // COBALT_DOM_ELEMENT_H_
