// 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_HTML_ELEMENT_H_
#define COBALT_DOM_HTML_ELEMENT_H_

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/compiler_specific.h"
#include "base/memory/ref_counted.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/animation_set.h"
#include "cobalt/cssom/css_computed_style_declaration.h"
#include "cobalt/cssom/css_declared_style_declaration.h"
#include "cobalt/cssom/css_style_declaration.h"
#include "cobalt/cssom/css_style_rule.h"
#include "cobalt/cssom/css_transition_set.h"
#include "cobalt/cssom/mutation_observer.h"
#include "cobalt/cssom/selector_tree.h"
#include "cobalt/cssom/style_sheet_list.h"
#include "cobalt/dom/css_animations_adapter.h"
#include "cobalt/dom/css_transitions_adapter.h"
#include "cobalt/dom/directionality.h"
#include "cobalt/dom/dom_rect_list.h"
#include "cobalt/dom/dom_stat_tracker.h"
#include "cobalt/dom/element.h"
#include "cobalt/dom/layout_boxes.h"
#include "cobalt/dom/pseudo_element.h"
#include "cobalt/loader/image/image_cache.h"
#include "cobalt/ui_navigation/nav_item.h"

namespace cobalt {
namespace dom {

class DOMStringMap;
class HTMLAnchorElement;
class HTMLAudioElement;
class HTMLBodyElement;
class HTMLBRElement;
class HTMLDivElement;
class HTMLElementContext;
class HTMLHeadElement;
class HTMLHeadingElement;
class HTMLHtmlElement;
class HTMLImageElement;
class HTMLLinkElement;
class HTMLMediaElement;
class HTMLMetaElement;
class HTMLParagraphElement;
class HTMLScriptElement;
class HTMLSpanElement;
class HTMLStyleElement;
class HTMLTitleElement;
class HTMLUnknownElement;
class HTMLVideoElement;
class LottiePlayer;

// The enum PseudoElementType is used to track the type of pseudo element
enum PseudoElementType {
  kAfterPseudoElementType,
  kBeforePseudoElementType,
  kMaxPseudoElementType,
  kNotPseudoElementType = kMaxPseudoElementType,
  kMaxAnyElementType,
};

// The basic interface, from which all the HTML elements' interfaces inherit,
// and which must be used by elements that have no additional requirements.
//   https://www.w3.org/TR/html50/dom.html#htmlelement
class HTMLElement : public Element, public cssom::MutationObserver {
 public:
  typedef cssom::SelectorTree::Nodes SelectorTreeNodes;

  // Cached state used with rule matching to minimize the amount of work that
  // must occur during UpdateMatchingRules() when little has changed.
  struct RuleMatchingState {
    RuleMatchingState()
        : is_set(false),
          are_descendant_nodes_dirty(true),
          are_following_sibling_nodes_dirty(true) {}

    // Fully clears the state but does not deallocate the vectors. This allows
    // the vectors to be reused without additional allocations the next time
    // they are needed and speeds up rule matching.
    void Clear();

    // Whether or not the rule matching state is set. When it is not set, the
    // next call to UpdateMatchingRules() always generates new matching rules
    // from the rule matching state.
    bool is_set;

    // The cached node state of the parent and previous sibling. Caching these
    // allows the element to know the exact nodes that have changed and
    // resultantly need to be checked during calls to UpdateMatchingRules().
    SelectorTreeNodes parent_matching_nodes;
    SelectorTreeNodes parent_descendant_nodes;

    SelectorTreeNodes previous_sibling_matching_nodes;
    SelectorTreeNodes previous_sibling_following_sibling_nodes;

    // The element's current matching nodes, along with their parent nodes.
    // These are kept in sync. This allows matching nodes to be removed when
    // their parent nodes are no longer available to the element.
    SelectorTreeNodes matching_nodes_parent_nodes;
    SelectorTreeNodes matching_nodes;

    // The nodes that are to be used by the element's descendants and following
    // siblings during their own rule matching. These are generated by combining
    // the nodes from the element's parent and previous sibling with the
    // element's own matching nodes that contain the required combinator.
    bool are_descendant_nodes_dirty;
    SelectorTreeNodes descendant_nodes;

    bool are_following_sibling_nodes_dirty;
    SelectorTreeNodes following_sibling_nodes;
  };

  enum AncestorsAreDisplayed {
    kAncestorsAreDisplayed,
    kAncestorsAreNotDisplayed,
  };

  // https://html.spec.whatwg.org/commit-snapshots/ebcac971c2add28a911283899da84ec509876c44/#the-dir-attribute
  enum DirState {
    kDirAuto,
    kDirLeftToRight,
    kDirRightToLeft,
    kDirNotDefined,
  };

  // Web API: HTMLElement
  //
  std::string dir() const;
  void set_dir(const std::string& value);

  scoped_refptr<DOMStringMap> dataset();

  int32 tab_index() const;
  void set_tab_index(int32 tab_index);

  void Focus();
  void Blur();

  // Web API: ElementCSSInlineStyle (implements)
  //   https://www.w3.org/TR/2013/WD-cssom-20131205/#elementcssinlinestyle
  const scoped_refptr<cssom::CSSDeclaredStyleDeclaration>& style() {
    return style_;
  }

  // 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<DOMRectList> GetClientRects() override;
  float client_top() override;
  float client_left() override;
  float client_width() override;
  float client_height() override;

  // Updated version of the CSSOM View Module extensions:
  //   https://www.w3.org/TR/cssom-view-1/#extension-to-the-element-interface
  int32 scroll_width() override;
  int32 scroll_height() override;

  // These attributes are only partially implemented. They will only work with
  // elements associated with UI navigation containers.
  float scroll_left() override;
  float scroll_top() override;
  void set_scroll_left(float x) override;
  void set_scroll_top(float y) override;

  // Web API: CSSOM View Module: Extensions to the HTMLElement Interface
  // (partial interface)
  //   https://www.w3.org/TR/2013/WD-cssom-view-20131217/#extensions-to-the-htmlelement-interface
  Element* offset_parent();
  float offset_top();
  float offset_left();
  float offset_width();
  float offset_height();

  // Custom, not in any spec: Node.
  scoped_refptr<Node> Duplicate() const override;

  // Custom, not in any spec: Element.
  scoped_refptr<HTMLElement> AsHTMLElement() override { return this; }

  base::Optional<std::string> GetStyleAttribute() const override;
  void SetStyleAttribute(const std::string& value) override;
  void RemoveStyleAttribute() override;

  // Custom, not in any spec.
  //
  // From cssom::CSSStyleDeclaration::MutationObserver.
  void OnCSSMutation() override;

  // Safe type conversion methods that will downcast to the required type if
  // possible or return NULL otherwise.
  virtual scoped_refptr<HTMLAnchorElement> AsHTMLAnchorElement();
  virtual scoped_refptr<HTMLAudioElement> AsHTMLAudioElement();
  virtual scoped_refptr<HTMLBodyElement> AsHTMLBodyElement();
  virtual scoped_refptr<HTMLBRElement> AsHTMLBRElement();
  virtual scoped_refptr<HTMLDivElement> AsHTMLDivElement();
  virtual scoped_refptr<HTMLHeadElement> AsHTMLHeadElement();
  virtual scoped_refptr<HTMLHeadingElement> AsHTMLHeadingElement();
  virtual scoped_refptr<HTMLHtmlElement> AsHTMLHtmlElement();
  virtual scoped_refptr<HTMLImageElement> AsHTMLImageElement();
  virtual scoped_refptr<HTMLLinkElement> AsHTMLLinkElement();
  virtual scoped_refptr<HTMLMetaElement> AsHTMLMetaElement();
  virtual scoped_refptr<HTMLMediaElement> AsHTMLMediaElement();
  virtual scoped_refptr<HTMLParagraphElement> AsHTMLParagraphElement();
  virtual scoped_refptr<HTMLScriptElement> AsHTMLScriptElement();
  virtual scoped_refptr<HTMLSpanElement> AsHTMLSpanElement();
  virtual scoped_refptr<HTMLStyleElement> AsHTMLStyleElement();
  virtual scoped_refptr<HTMLTitleElement> AsHTMLTitleElement();
  virtual scoped_refptr<HTMLUnknownElement> AsHTMLUnknownElement();
  virtual scoped_refptr<HTMLVideoElement> AsHTMLVideoElement();
  virtual scoped_refptr<LottiePlayer> AsLottiePlayer();

  // Returns the directionality of the element, which is based upon the
  // element's "dir" attribute if it was set, or that of the parent's if not
  // set.
  //   https://html.spec.whatwg.org/commit-snapshots/ebcac971c2add28a911283899da84ec509876c44/#the-directionality
  Directionality directionality();

  // Retrieve the dir attribute state. This is similar to dir() but returns the
  // enumerated state rather than string.
  DirState dir_state() const { return dir_; }

  // This is similar to dir_state() except it will resolve kDirAuto to
  // kDirLeftToRight or kDirRightToLeft according to the spec:
  //   https://html.spec.whatwg.org/commit-snapshots/ebcac971c2add28a911283899da84ec509876c44/#the-directionality
  // If "dir" was not defined for this element, then this function will return
  // kDirNotDefined.
  virtual DirState GetUsedDirState();

  // Rule matching related methods.
  //
  // Returns the rule matching state of this element.
  RuleMatchingState* rule_matching_state() { return &rule_matching_state_; }

  void ClearRuleMatchingState();
  void ClearRuleMatchingStateOnElementAndAncestors(
      bool invalidate_tree_matching_rules);
  void ClearRuleMatchingStateOnElementAndDescendants();
  void ClearRuleMatchingStateOnElementAndSiblingsAndDescendants();

  // Returns the cached matching rules of this element.
  cssom::RulesWithCascadePrecedence* matching_rules() {
    return &matching_rules_;
  }

  void InvalidateMatchingRulesRecursively();
  void UpdateMatchingRules();
  void UpdateMatchingRulesRecursively();

  void OnMatchingRulesModified();
  void OnPseudoElementMatchingRulesModified();

  // Computed style related methods.
  //
  // Used by layout engine to cache the computed values.
  // See https://www.w3.org/TR/css-cascade-3/#computed for the definition of
  // computed value.
  scoped_refptr<cssom::CSSComputedStyleDeclaration>&
  css_computed_style_declaration() {
    return css_computed_style_declaration_;
  }
  const scoped_refptr<const cssom::CSSComputedStyleData>& computed_style()
      const {
    return css_computed_style_declaration_->data();
  }

  // Updates the cached computed style of this element and its descendants.
  void UpdateComputedStyleRecursively(
      const scoped_refptr<cssom::CSSComputedStyleDeclaration>&
          parent_computed_style,
      const scoped_refptr<const cssom::CSSComputedStyleData>&
          root_computed_style,
      const base::TimeDelta& style_change_event_time, bool ancestors_were_valid,
      int current_element_depth);

  // Updates the cached computed style of this element.
  void UpdateComputedStyle(
      const scoped_refptr<cssom::CSSComputedStyleDeclaration>&
          parent_computed_style_declaration,
      const scoped_refptr<const cssom::CSSComputedStyleData>&
          root_computed_style,
      const base::TimeDelta& style_change_event_time,
      AncestorsAreDisplayed ancestor_is_displayed);

  // Collecting HTML media element.
  void CollectHTMLMediaElementsRecursively(
      std::vector<HTMLMediaElement*>* html_media_elements,
      int current_element_depth);

  void MarkNotDisplayedOnNodeAndDescendants() override;
  void PurgeCachedBackgroundImagesOfNodeAndDescendants() override;
  void InvalidateComputedStylesOfNodeAndDescendants() override;
  void InvalidateLayoutBoxesOfNodeAndAncestors() override;
  void InvalidateLayoutBoxesOfNodeAndDescendants() override;
  void InvalidateLayoutBoxSizes() override;
  void InvalidateLayoutBoxCrossReferences() override;
  void InvalidateLayoutBoxRenderTreeNodes() override;

  // Layout box related methods.
  //
  // The LayoutContainerBox gives the HTML Element an interface to the container
  // box that result from it. The BoxList is set when layout is performed for a
  // node.
  void set_layout_boxes(std::unique_ptr<LayoutBoxes> layout_boxes) {
    layout_boxes_ = std::move(layout_boxes);
  }

  LayoutBoxes* layout_boxes() const { return layout_boxes_.get(); }

  PseudoElement* pseudo_element(PseudoElementType type) const {
    DCHECK(type < kMaxPseudoElementType);
    return pseudo_elements_[type].get();
  }

  void SetPseudoElement(PseudoElementType type,
                        std::unique_ptr<PseudoElement> pseudo_element);

  // Returns true if the element's computed style and all of its pseudo
  // element's computed styles are valid.
  bool AreComputedStylesValid() const;
  bool descendant_computed_styles_valid() const {
    return descendant_computed_styles_valid_;
  }

  bool matching_rules_valid() const { return matching_rules_valid_; }
  void set_matching_rules_valid() { matching_rules_valid_ = true; }

  // Returns whether the element has been designated.
  //   https://www.w3.org/TR/selectors4/#hover-pseudo
  bool IsDesignated() const;

  // Returns whether the element can be designated by a pointer.
  //   https://www.w3.org/TR/SVG11/interact.html#PointerEventsProperty
  bool CanbeDesignatedByPointerIfDisplayed() const;

  // Returns true if this node and all of its ancestors do NOT have display set
  // to 'none'.
  bool IsDisplayed() const;

  // Get the UI navigation item (if any) representing this HTML element.
  const scoped_refptr<ui_navigation::NavItem>& GetUiNavItem() const {
    return ui_nav_item_;
  }

  // Update the UI navigation system to focus on the relevant navigation item
  // for this HTML element (if any).
  void UpdateUiNavigationFocus(bool force_focus);

  // Returns true if the element is the root element as defined in
  // https://www.w3.org/TR/html50/semantics.html#the-root-element.
  bool IsRootElement();

  // Returns true if this is a document element.
  // https://dom.spec.whatwg.org/#document-element
  bool IsDocumentElement() const {
    return parent_node() && parent_node()->IsDocument();
  }

  DEFINE_WRAPPABLE_TYPE(HTMLElement);

 protected:
  HTMLElement(Document* document, base::Token local_name);
  ~HTMLElement() override;

  void OnInsertedIntoDocument() override;
  void OnRemovedFromDocument() override;

  // From Element.
  void OnSetAttribute(const std::string& name,
                      const std::string& value) override;
  void OnRemoveAttribute(const std::string& name) override;

  // HTMLElement keeps a pointer to the dom stat tracker to ensure that it can
  // make stat updates even after its weak pointer to its document has been
  // deleted. This is protected because some derived classes need access to it.
  DomStatTracker* const dom_stat_tracker_;

 private:
  // From Node.
  void OnMutation() override;

  bool IsFocusable();
  bool HasTabindexFocusFlag() const;
  bool IsBeingRendered();

  void RunFocusingSteps();
  void RunUnFocusingSteps();

  // This both updates the 'dir' attribute based upon the string value and
  // invalidates layout box caching if the value has changed.
  void SetDir(const std::string& value);

  // Update the cached value of tabindex.
  void SetTabIndex(const std::string& value);

  // Invalidate the matching rules and rule matching state in this element and
  // its descendants. In the case where this is the the initial invalidation,
  // it will also invalidate the rule matching state of its siblings.
  void InvalidateMatchingRulesRecursivelyInternal(bool is_initial_element);
  // Fully clear the rule matching state of this element and optionally
  // invalidate all of its descendants matching rules.
  void ClearRuleMatchingStateInternal(bool invalidate_descendants);

  // Update the UI navigation item type for this element.
  void UpdateUiNavigation();
  void ReleaseUiNavigationItem();

  // Clear the list of active background images, and notify the animated image
  // tracker to stop the animations.
  void ClearActiveBackgroundImages();

  void UpdateCachedBackgroundImagesFromComputedStyle();

  // This will be called when the image data associated with this element's
  // computed style's background-image property is loaded.
  void OnBackgroundImageLoaded();

  // Purge the cached background images on only this node.
  void PurgeCachedBackgroundImages();

  // Helper function that hosts the shared code between
  // InvalidateLayoutBoxesOfNodeAndAncestors() and
  // InvalidateLayoutBoxesOfNodeAndDescendants().
  void InvalidateLayoutBoxes();

  // Handle UI navigation events.
  void OnUiNavBlur();
  void OnUiNavFocus();
  void OnUiNavScroll();

  bool locked_for_focus_;

  // This represents the enumerated value of the 'dir' attribute.
  //   https://html.spec.whatwg.org/commit-snapshots/ebcac971c2add28a911283899da84ec509876c44/#the-dir-attribute
  DirState dir_;

  // This represents the computed directionality for this element.
  //   https://html.spec.whatwg.org/commit-snapshots/ebcac971c2add28a911283899da84ec509876c44/#the-directionality
  // NOTE: Cobalt does not support either the CSS 'direction' or 'unicode-bidi'
  // properties, and instead relies entirely upon the 'dir' attribute for
  // determining directionality. Inheritance of directionality occurs via the
  // base direction of the parent element's paragraph.
  base::Optional<Directionality> directionality_;

  // Cache the tabindex value.
  base::Optional<int32> tabindex_;

  // The inline style specified via attribute's in the element's HTML tag, or
  // through JavaScript (accessed via style() defined above).
  scoped_refptr<cssom::CSSDeclaredStyleDeclaration> style_;

  // Keeps track of whether the HTML element's current computed style is out
  // of date or not.
  bool computed_style_valid_;
  // Keeps track of whether the HTML element's pseudo element's computed styles
  // are out of date or not.
  bool pseudo_elements_computed_styles_valid_;
  // Keeps track of whether the HTML element's descendants' computed styles are
  // out of date or not.
  bool descendant_computed_styles_valid_;

  // Indicates whether this node has an ancestor which has display set to none
  // or not. This value gets updated when computed style is updated.
  AncestorsAreDisplayed ancestors_are_displayed_;

  scoped_refptr<cssom::CSSComputedStyleDeclaration>
      css_computed_style_declaration_;

  dom::CSSTransitionsAdapter transitions_adapter_;
  cssom::TransitionSet css_transitions_;

  dom::CSSAnimationsAdapter animations_adapter_;
  cssom::AnimationSet css_animations_;

  // The following fields are used in rule matching.
  RuleMatchingState rule_matching_state_;
  bool matching_rules_valid_;
  cssom::RulesWithCascadePrecedence matching_rules_;

  // This contains information about the boxes generated from the element.
  std::unique_ptr<LayoutBoxes> layout_boxes_;

  std::unique_ptr<PseudoElement> pseudo_elements_[kMaxPseudoElementType];
  base::WeakPtr<DOMStringMap> dataset_;

  std::vector<GURL> active_background_images_;

  // |cached_background_images_| contains a list of CachedImage references for
  // all images referenced by the computed value for the background_image CSS
  // property and a image loaded handle to add and remove image loaded callback.
  // We maintain it here to indicate to the resource caching system
  // that the images are currently in-use, and should not be purged.
  loader::image::CachedImageReferenceVector cached_background_images_;

  // Elements with specific styles or attributes can be animated by the
  // platform's UI engine. This is done by attaching special animation nodes to
  // the boxes generated for the relevant elements; the rendering pipeline will
  // then query starboard for position data each frame, thus animating the
  // boxes without requiring a new layout.
  scoped_refptr<ui_navigation::NavItem> ui_nav_item_;

  // Signal whether the UI navigation item may need to be updated.
  bool ui_nav_needs_update_ = false;

  // HTMLElement is a friend of Animatable so that animatable can insert and
  // remove animations into HTMLElement's set of animations.
  friend class DOMAnimatable;
};

}  // namespace dom
}  // namespace cobalt

#endif  // COBALT_DOM_HTML_ELEMENT_H_
