// 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"
#include "starboard/time.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();

  // 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);

  // Update cached UI navigation focus duration.
  void SetUiNavFocusDuration(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(SbTimeMonotonic time);
  void OnUiNavFocus(SbTimeMonotonic time);
  void OnUiNavScroll(SbTimeMonotonic time);

  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_;

  // Specify how long focus should remain on this navigation item once it
  // becomes focused.
  base::Optional<float> ui_nav_focus_duration_;

  // 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_
