/*
 * Copyright (C) 2004, 2006, 2009 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_TEXT_ITERATOR_H_
#define THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_TEXT_ITERATOR_H_

#include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/range.h"
#include "third_party/blink/renderer/core/editing/finder/find_options.h"
#include "third_party/blink/renderer/core/editing/forward.h"
#include "third_party/blink/renderer/core/editing/iterators/fully_clipped_state_stack.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator_behavior.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator_text_node_handler.h"
#include "third_party/blink/renderer/core/editing/iterators/text_iterator_text_state.h"
#include "third_party/blink/renderer/platform/heap/handle.h"

namespace blink {

CORE_EXPORT String
PlainText(const EphemeralRange&,
          const TextIteratorBehavior& = TextIteratorBehavior());

CORE_EXPORT String
PlainText(const EphemeralRangeInFlatTree&,
          const TextIteratorBehavior& = TextIteratorBehavior());

// Iterates through the DOM range, returning all the text, and 0-length
// boundaries at points where replaced elements break up the text flow.  The
// text comes back in chunks so as to optimize for performance of the iteration.

template <typename Strategy>
class TextIteratorAlgorithm {
  STACK_ALLOCATED();

 public:
  // [start, end] indicates the document range that the iteration should take
  // place within (both ends inclusive).
  TextIteratorAlgorithm(const PositionTemplate<Strategy>& start,
                        const PositionTemplate<Strategy>& end,
                        const TextIteratorBehavior& = TextIteratorBehavior());

  // Same behavior as previous constructor but takes an EphemeralRange instead
  // of two Positions
  TextIteratorAlgorithm(const EphemeralRangeTemplate<Strategy>&,
                        const TextIteratorBehavior& = TextIteratorBehavior());

  ~TextIteratorAlgorithm();

  bool AtEnd() const { return !text_state_.PositionNode() || should_stop_; }
  void Advance();
  bool IsInsideAtomicInlineElement() const;

  EphemeralRangeTemplate<Strategy> Range() const;
  const Node* GetNode() const;

  const Document& OwnerDocument() const;
  const Node& CurrentContainer() const;
  int StartOffsetInCurrentContainer() const;
  int EndOffsetInCurrentContainer() const;
  PositionTemplate<Strategy> StartPositionInCurrentContainer() const;
  PositionTemplate<Strategy> EndPositionInCurrentContainer() const;

  // Returns the position before |char16_offset| in current text run.
  PositionTemplate<Strategy> GetPositionBefore(int char16_offset) const;

  // Returns the position after |char16_offset| in current text run.
  PositionTemplate<Strategy> GetPositionAfter(int char16_offset) const;

  const TextIteratorTextState& GetTextState() const { return text_state_; }
  int length() const { return text_state_.length(); }
  UChar CharacterAt(unsigned index) const {
    return text_state_.CharacterAt(index);
  }

  bool BreaksAtReplacedElement() {
    return !behavior_.DoesNotBreakAtReplacedElement();
  }

  // Computes the length of the given range using a text iterator according to
  // the specified iteration behavior. The default iteration behavior is to
  // always emit object replacement characters for replaced elements.
  // TODO(editing-dev): We should remove start/end version of |RangeLength()|.
  static int RangeLength(
      const PositionTemplate<Strategy>& start,
      const PositionTemplate<Strategy>& end,
      const TextIteratorBehavior& =
          TextIteratorBehavior::DefaultRangeLengthBehavior());

  static int RangeLength(
      const EphemeralRangeTemplate<Strategy>&,
      const TextIteratorBehavior& =
          TextIteratorBehavior::DefaultRangeLengthBehavior());

  static bool ShouldEmitTabBeforeNode(const Node&);
  static bool ShouldEmitNewlineBeforeNode(const Node&);
  static bool ShouldEmitNewlineAfterNode(const Node&);
  static bool ShouldEmitNewlineForNode(const Node&, bool emits_original_text);

  static bool SupportsAltText(const Node&);

 private:
  enum IterationProgress {
    kHandledNone,
    kHandledOpenShadowRoots,
    kHandledUserAgentShadowRoot,
    kHandledNode,
    kHandledChildren
  };

  void EmitChar16AfterNode(UChar code_unit, const Node& node);
  void EmitChar16AsNode(UChar code_unit, const Node& node);
  void EmitChar16BeforeNode(UChar code_unit, const Node& node);

  void ExitNode();
  bool ShouldRepresentNodeOffsetZero();
  bool ShouldEmitSpaceBeforeAndAfterNode(const Node&);
  void RepresentNodeOffsetZero();

  // Returns true if text is emitted from the remembered progress (if any).
  bool HandleRememberedProgress();

  void HandleTextNode();
  void HandleReplacedElement();
  void HandleNonTextNode();

  // Used by selection preservation code. There should be one character emitted
  // between every VisiblePosition in the Range used to create the TextIterator.
  // FIXME <rdar://problem/6028818>: This functionality should eventually be
  // phased out when we rewrite moveParagraphs to not clone/destroy moved
  // content.
  bool EmitsCharactersBetweenAllVisiblePositions() const {
    return behavior_.EmitsCharactersBetweenAllVisiblePositions();
  }

  bool EntersTextControls() const { return behavior_.EntersTextControls(); }

  // Used in pasting inside password field.
  bool EmitsOriginalText() const { return behavior_.EmitsOriginalText(); }

  // Used when the visibility of the style should not affect text gathering.
  bool IgnoresStyleVisibility() const {
    return behavior_.IgnoresStyleVisibility();
  }

  // Used when the iteration should stop if form controls are reached.
  bool StopsOnFormControls() const { return behavior_.StopsOnFormControls(); }

  bool EmitsImageAltText() const { return behavior_.EmitsImageAltText(); }

  bool EntersOpenShadowRoots() const {
    return behavior_.EntersOpenShadowRoots();
  }

  bool EmitsObjectReplacementCharacter() const {
    return behavior_.EmitsObjectReplacementCharacter();
  }

  bool ExcludesAutofilledValue() const {
    return behavior_.ExcludeAutofilledValue();
  }

  bool DoesNotBreakAtReplacedElement() const {
    return behavior_.DoesNotBreakAtReplacedElement();
  }

  // Clipboard should respect user-select style attribute
  bool SkipsUnselectableContent() const {
    return behavior_.SkipsUnselectableContent();
  }

  bool ForInnerText() const { return behavior_.ForInnerText(); }

  bool IsBetweenSurrogatePair(unsigned position) const;

  // Ensure container node of current text run for computing position.
  void EnsurePositionContainer() const;

  // The range.
  const Node* const start_container_;
  const unsigned start_offset_;
  const Node* const end_container_;
  const unsigned end_offset_;
  // |end_node_| stores |Strategy::ChildAt(*end_container_, end_offfset_ - 1)|,
  // if it exists, or |nullptr| otherwise.
  const Node* const end_node_;
  const Node* const past_end_node_;

  // Current position, not necessarily of the text being returned, but position
  // as we walk through the DOM tree.
  const Node* node_;
  IterationProgress iteration_progress_;
  FullyClippedStateStackAlgorithm<Strategy> fully_clipped_stack_;
  unsigned shadow_depth_;

  // Used when there is still some pending text from the current node; when
  // these are false, we go back to normal iterating.
  bool needs_another_newline_ = false;
  bool needs_handle_replaced_element_ = false;

  const Text* last_text_node_ = nullptr;

  const TextIteratorBehavior behavior_;

  // Used when stopsOnFormControls() is true to determine if the iterator should
  // keep advancing.
  bool should_stop_ = false;
  // Used for use counter |InnerTextWithShadowTree| and
  // |SelectionToStringWithShadowTree|, we should not use other purpose.
  bool handle_shadow_root_ = false;

  // Contains state of emitted text.
  TextIteratorTextState text_state_;

  // Helper for extracting text content from text nodes.
  TextIteratorTextNodeHandler text_node_handler_;
};

extern template class CORE_EXTERN_TEMPLATE_EXPORT
    TextIteratorAlgorithm<EditingStrategy>;
extern template class CORE_EXTERN_TEMPLATE_EXPORT
    TextIteratorAlgorithm<EditingInFlatTreeStrategy>;

using TextIterator = TextIteratorAlgorithm<EditingStrategy>;
using TextIteratorInFlatTree = TextIteratorAlgorithm<EditingInFlatTreeStrategy>;

}  // namespace blink

#endif  // THIRD_PARTY_BLINK_RENDERER_CORE_EDITING_ITERATORS_TEXT_ITERATOR_H_
