/*
 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
 *           (C) 1999 Antti Koivisto (koivisto@kde.org)
 *           (C) 2001 Dirk Mueller (mueller@kde.org)
 * Copyright (C) 2004, 2005, 2006, 2007, 2009, 2010, 2011, 2013 Apple Inc. All
 * rights reserved.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
 *
 */

#ifndef ContainerNode_h
#define ContainerNode_h

#include "bindings/core/v8/ExceptionState.h"
#include "bindings/core/v8/ScriptWrappableVisitor.h"
#include "core/CoreExport.h"
#include "core/dom/Node.h"
#include "core/html/CollectionType.h"
#include "wtf/Vector.h"

namespace blink {

class ClassCollection;
class ExceptionState;
class FloatPoint;
class HTMLCollection;
class NameNodeList;
using StaticElementList = StaticNodeTypeList<Element>;
class RadioNodeList;
class TagCollection;

enum DynamicRestyleFlags {
  ChildrenOrSiblingsAffectedByFocus = 1 << 0,
  ChildrenOrSiblingsAffectedByHover = 1 << 1,
  ChildrenOrSiblingsAffectedByActive = 1 << 2,
  ChildrenOrSiblingsAffectedByDrag = 1 << 3,
  ChildrenAffectedByFirstChildRules = 1 << 4,
  ChildrenAffectedByLastChildRules = 1 << 5,
  ChildrenAffectedByDirectAdjacentRules = 1 << 6,
  ChildrenAffectedByIndirectAdjacentRules = 1 << 7,
  ChildrenAffectedByForwardPositionalRules = 1 << 8,
  ChildrenAffectedByBackwardPositionalRules = 1 << 9,
  AffectedByFirstChildRules = 1 << 10,
  AffectedByLastChildRules = 1 << 11,

  NumberOfDynamicRestyleFlags = 12,

  ChildrenAffectedByStructuralRules = ChildrenAffectedByFirstChildRules |
                                      ChildrenAffectedByLastChildRules |
                                      ChildrenAffectedByDirectAdjacentRules |
                                      ChildrenAffectedByIndirectAdjacentRules |
                                      ChildrenAffectedByForwardPositionalRules |
                                      ChildrenAffectedByBackwardPositionalRules
};

enum SubtreeModificationAction {
  DispatchSubtreeModifiedEvent,
  OmitSubtreeModifiedEvent
};

// This constant controls how much buffer is initially allocated
// for a Node Vector that is used to store child Nodes of a given Node.
// FIXME: Optimize the value.
const int initialNodeVectorSize = 11;
using NodeVector = HeapVector<Member<Node>, initialNodeVectorSize>;

class CORE_EXPORT ContainerNode : public Node {
 public:
  ~ContainerNode() override;

  Node* firstChild() const { return m_firstChild; }
  Node* lastChild() const { return m_lastChild; }
  bool hasChildren() const { return m_firstChild; }

  bool hasOneChild() const {
    return m_firstChild && !m_firstChild->nextSibling();
  }
  bool hasOneTextChild() const {
    return hasOneChild() && m_firstChild->isTextNode();
  }
  bool hasChildCount(unsigned) const;

  HTMLCollection* children();

  unsigned countChildren() const;

  Element* querySelector(const AtomicString& selectors,
                         ExceptionState& = ASSERT_NO_EXCEPTION);
  StaticElementList* querySelectorAll(const AtomicString& selectors,
                                      ExceptionState&);

  Node* insertBefore(Node* newChild,
                     Node* refChild,
                     ExceptionState& = ASSERT_NO_EXCEPTION);
  Node* replaceChild(Node* newChild,
                     Node* oldChild,
                     ExceptionState& = ASSERT_NO_EXCEPTION);
  Node* removeChild(Node* child, ExceptionState& = ASSERT_NO_EXCEPTION);
  Node* appendChild(Node* newChild, ExceptionState& = ASSERT_NO_EXCEPTION);

  Element* getElementById(const AtomicString& id) const;
  TagCollection* getElementsByTagName(const AtomicString&);
  TagCollection* getElementsByTagNameNS(const AtomicString& namespaceURI,
                                        const AtomicString& localName);
  NameNodeList* getElementsByName(const AtomicString& elementName);
  ClassCollection* getElementsByClassName(const AtomicString& classNames);
  RadioNodeList* radioNodeList(const AtomicString&,
                               bool onlyMatchImgElements = false);

  // These methods are only used during parsing.
  // They don't send DOM mutation events or accept DocumentFragments.
  void parserAppendChild(Node*);
  void parserRemoveChild(Node&);
  void parserInsertBefore(Node* newChild, Node& refChild);
  void parserTakeAllChildrenFrom(ContainerNode&);

  void removeChildren(SubtreeModificationAction = DispatchSubtreeModifiedEvent);

  void cloneChildNodes(ContainerNode* clone);

  void attachLayoutTree(const AttachContext& = AttachContext()) override;
  void detachLayoutTree(const AttachContext& = AttachContext()) override;
  LayoutRect boundingBox() const final;
  void setFocused(bool) override;
  void focusStateChanged();
  void setActive(bool = true) override;
  void setDragged(bool) override;
  void setHovered(bool = true) override;

  bool childrenOrSiblingsAffectedByFocus() const {
    return hasRestyleFlag(ChildrenOrSiblingsAffectedByFocus);
  }
  void setChildrenOrSiblingsAffectedByFocus() {
    setRestyleFlag(ChildrenOrSiblingsAffectedByFocus);
  }

  bool childrenOrSiblingsAffectedByHover() const {
    return hasRestyleFlag(ChildrenOrSiblingsAffectedByHover);
  }
  void setChildrenOrSiblingsAffectedByHover() {
    setRestyleFlag(ChildrenOrSiblingsAffectedByHover);
  }

  bool childrenOrSiblingsAffectedByActive() const {
    return hasRestyleFlag(ChildrenOrSiblingsAffectedByActive);
  }
  void setChildrenOrSiblingsAffectedByActive() {
    setRestyleFlag(ChildrenOrSiblingsAffectedByActive);
  }

  bool childrenOrSiblingsAffectedByDrag() const {
    return hasRestyleFlag(ChildrenOrSiblingsAffectedByDrag);
  }
  void setChildrenOrSiblingsAffectedByDrag() {
    setRestyleFlag(ChildrenOrSiblingsAffectedByDrag);
  }

  bool childrenAffectedByFirstChildRules() const {
    return hasRestyleFlag(ChildrenAffectedByFirstChildRules);
  }
  void setChildrenAffectedByFirstChildRules() {
    setRestyleFlag(ChildrenAffectedByFirstChildRules);
  }

  bool childrenAffectedByLastChildRules() const {
    return hasRestyleFlag(ChildrenAffectedByLastChildRules);
  }
  void setChildrenAffectedByLastChildRules() {
    setRestyleFlag(ChildrenAffectedByLastChildRules);
  }

  bool childrenAffectedByDirectAdjacentRules() const {
    return hasRestyleFlag(ChildrenAffectedByDirectAdjacentRules);
  }
  void setChildrenAffectedByDirectAdjacentRules() {
    setRestyleFlag(ChildrenAffectedByDirectAdjacentRules);
  }

  bool childrenAffectedByIndirectAdjacentRules() const {
    return hasRestyleFlag(ChildrenAffectedByIndirectAdjacentRules);
  }
  void setChildrenAffectedByIndirectAdjacentRules() {
    setRestyleFlag(ChildrenAffectedByIndirectAdjacentRules);
  }

  bool childrenAffectedByForwardPositionalRules() const {
    return hasRestyleFlag(ChildrenAffectedByForwardPositionalRules);
  }
  void setChildrenAffectedByForwardPositionalRules() {
    setRestyleFlag(ChildrenAffectedByForwardPositionalRules);
  }

  bool childrenAffectedByBackwardPositionalRules() const {
    return hasRestyleFlag(ChildrenAffectedByBackwardPositionalRules);
  }
  void setChildrenAffectedByBackwardPositionalRules() {
    setRestyleFlag(ChildrenAffectedByBackwardPositionalRules);
  }

  bool affectedByFirstChildRules() const {
    return hasRestyleFlag(AffectedByFirstChildRules);
  }
  void setAffectedByFirstChildRules() {
    setRestyleFlag(AffectedByFirstChildRules);
  }

  bool affectedByLastChildRules() const {
    return hasRestyleFlag(AffectedByLastChildRules);
  }
  void setAffectedByLastChildRules() {
    setRestyleFlag(AffectedByLastChildRules);
  }

  bool needsAdjacentStyleRecalc() const;

  // FIXME: These methods should all be renamed to something better than
  // "check", since it's not clear that they alter the style bits of siblings
  // and children.
  enum SiblingCheckType {
    FinishedParsingChildren,
    SiblingElementInserted,
    SiblingElementRemoved
  };
  void checkForSiblingStyleChanges(SiblingCheckType,
                                   Element* changedElement,
                                   Node* nodeBeforeChange,
                                   Node* nodeAfterChange);
  void recalcDescendantStyles(StyleRecalcChange);

  bool childrenSupportStyleSharing() const { return !hasRestyleFlags(); }

  // -----------------------------------------------------------------------------
  // Notification of document structure changes (see core/dom/Node.h for more
  // notification methods)

  enum ChildrenChangeType {
    ElementInserted,
    NonElementInserted,
    ElementRemoved,
    NonElementRemoved,
    AllChildrenRemoved,
    TextChanged
  };
  enum ChildrenChangeSource {
    ChildrenChangeSourceAPI,
    ChildrenChangeSourceParser
  };
  struct ChildrenChange {
    STACK_ALLOCATED();

   public:
    static ChildrenChange forInsertion(Node& node,
                                       ChildrenChangeSource byParser) {
      ChildrenChange change = {
          node.isElementNode() ? ElementInserted : NonElementInserted, &node,
          node.previousSibling(), node.nextSibling(), byParser};
      return change;
    }

    static ChildrenChange forRemoval(Node& node,
                                     Node* previousSibling,
                                     Node* nextSibling,
                                     ChildrenChangeSource byParser) {
      ChildrenChange change = {
          node.isElementNode() ? ElementRemoved : NonElementRemoved, &node,
          previousSibling, nextSibling, byParser};
      return change;
    }

    bool isChildInsertion() const {
      return type == ElementInserted || type == NonElementInserted;
    }
    bool isChildRemoval() const {
      return type == ElementRemoved || type == NonElementRemoved;
    }
    bool isChildElementChange() const {
      return type == ElementInserted || type == ElementRemoved;
    }

    ChildrenChangeType type;
    Member<Node> siblingChanged;
    Member<Node> siblingBeforeChange;
    Member<Node> siblingAfterChange;
    ChildrenChangeSource byParser;
  };

  // Notifies the node that it's list of children have changed (either by adding
  // or removing child nodes), or a child node that is of the type
  // CDATA_SECTION_NODE, TEXT_NODE or COMMENT_NODE has changed its value.
  virtual void childrenChanged(const ChildrenChange&);

  DECLARE_VIRTUAL_TRACE();

  DECLARE_VIRTUAL_TRACE_WRAPPERS();

 protected:
  ContainerNode(TreeScope*, ConstructionType = CreateContainer);

  void invalidateNodeListCachesInAncestors(
      const QualifiedName* attrName = nullptr,
      Element* attributeOwnerElement = nullptr);

  void setFirstChild(Node* child) {
    m_firstChild = child;
    ScriptWrappableVisitor::writeBarrier(this, m_firstChild);
  }
  void setLastChild(Node* child) {
    m_lastChild = child;
    ScriptWrappableVisitor::writeBarrier(this, m_lastChild);
  }

  // Utility functions for NodeListsNodeData API.
  template <typename Collection>
  Collection* ensureCachedCollection(CollectionType);
  template <typename Collection>
  Collection* ensureCachedCollection(CollectionType, const AtomicString& name);
  template <typename Collection>
  Collection* ensureCachedCollection(CollectionType,
                                     const AtomicString& namespaceURI,
                                     const AtomicString& localName);
  template <typename Collection>
  Collection* cachedCollection(CollectionType);

 private:
  bool isContainerNode() const =
      delete;  // This will catch anyone doing an unnecessary check.
  bool isTextNode() const =
      delete;  // This will catch anyone doing an unnecessary check.

  NodeListsNodeData& ensureNodeLists();
  void removeBetween(Node* previousChild, Node* nextChild, Node& oldChild);
  template <typename Functor>
  void insertNodeVector(const NodeVector&, Node* next, const Functor&);
  class AdoptAndInsertBefore;
  class AdoptAndAppendChild;
  friend class AdoptAndInsertBefore;
  friend class AdoptAndAppendChild;
  void insertBeforeCommon(Node& nextChild, Node& newChild);
  void appendChildCommon(Node& child);
  void willRemoveChildren();
  void willRemoveChild(Node& child);
  void removeDetachedChildrenInContainer(ContainerNode&);
  void addChildNodesToDeletionQueue(Node*&, Node*&, ContainerNode&);

  void notifyNodeInserted(Node&,
                          ChildrenChangeSource = ChildrenChangeSourceAPI);
  void notifyNodeInsertedInternal(Node&,
                                  NodeVector& postInsertionNotificationTargets);
  void notifyNodeRemoved(Node&);

  bool hasRestyleFlag(DynamicRestyleFlags mask) const {
    return hasRareData() && hasRestyleFlagInternal(mask);
  }
  bool hasRestyleFlags() const {
    return hasRareData() && hasRestyleFlagsInternal();
  }
  void setRestyleFlag(DynamicRestyleFlags);
  bool hasRestyleFlagInternal(DynamicRestyleFlags) const;
  bool hasRestyleFlagsInternal() const;

  bool collectChildrenAndRemoveFromOldParentWithCheck(const Node* next,
                                                      const Node* oldChild,
                                                      Node& newChild,
                                                      NodeVector&,
                                                      ExceptionState&) const;
  inline bool checkAcceptChildGuaranteedNodeTypes(const Node& newChild,
                                                  const Node* oldChild,
                                                  ExceptionState&) const;
  inline bool checkAcceptChild(const Node* newChild,
                               const Node* oldChild,
                               ExceptionState&) const;
  inline bool checkParserAcceptChild(const Node& newChild) const;
  inline bool containsConsideringHostElements(const Node&) const;
  inline bool isChildTypeAllowed(const Node& child) const;

  bool getUpperLeftCorner(FloatPoint&) const;
  bool getLowerRightCorner(FloatPoint&) const;

  Member<Node> m_firstChild;
  Member<Node> m_lastChild;
};

#if DCHECK_IS_ON()
bool childAttachedAllowedWhenAttachingChildren(ContainerNode*);
#endif

WILL_NOT_BE_EAGERLY_TRACED_CLASS(ContainerNode);

DEFINE_NODE_TYPE_CASTS(ContainerNode, isContainerNode());

inline bool ContainerNode::hasChildCount(unsigned count) const {
  Node* child = m_firstChild;
  while (count && child) {
    child = child->nextSibling();
    --count;
  }
  return !count && !child;
}

inline ContainerNode::ContainerNode(TreeScope* treeScope, ConstructionType type)
    : Node(treeScope, type), m_firstChild(nullptr), m_lastChild(nullptr) {}

inline bool ContainerNode::needsAdjacentStyleRecalc() const {
  if (!childrenAffectedByDirectAdjacentRules() &&
      !childrenAffectedByIndirectAdjacentRules())
    return false;
  return childNeedsStyleRecalc() || childNeedsStyleInvalidation();
}

inline unsigned Node::countChildren() const {
  if (!isContainerNode())
    return 0;
  return toContainerNode(this)->countChildren();
}

inline Node* Node::firstChild() const {
  if (!isContainerNode())
    return nullptr;
  return toContainerNode(this)->firstChild();
}

inline Node* Node::lastChild() const {
  if (!isContainerNode())
    return nullptr;
  return toContainerNode(this)->lastChild();
}

inline ContainerNode* Node::parentElementOrShadowRoot() const {
  ContainerNode* parent = parentNode();
  return parent && (parent->isElementNode() || parent->isShadowRoot())
             ? parent
             : nullptr;
}

inline ContainerNode* Node::parentElementOrDocumentFragment() const {
  ContainerNode* parent = parentNode();
  return parent && (parent->isElementNode() || parent->isDocumentFragment())
             ? parent
             : nullptr;
}

inline bool Node::isTreeScope() const {
  return &treeScope().rootNode() == this;
}

inline void getChildNodes(ContainerNode& node, NodeVector& nodes) {
  DCHECK(!nodes.size());
  for (Node* child = node.firstChild(); child; child = child->nextSibling())
    nodes.push_back(child);
}

}  // namespace blink

#endif  // ContainerNode_h
