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

  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_
