/*
 * Copyright (C) 2004, 2006, 2008 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 EditingUtilities_h
#define EditingUtilities_h

#include "core/CoreExport.h"
#include "core/editing/EditingBoundary.h"
#include "core/editing/EphemeralRange.h"
#include "core/editing/Position.h"
#include "core/editing/PositionWithAffinity.h"
#include "core/editing/VisiblePosition.h"
#include "core/editing/VisibleSelection.h"
#include "core/events/InputEvent.h"
#include "platform/text/TextDirection.h"
#include "wtf/Forward.h"
#include "wtf/text/CharacterNames.h"

namespace blink {

enum class PositionMoveType {
  // Move by a single code unit. |PositionMoveType::CodeUnit| is used for
  // implementing other |PositionMoveType|. You should not use this.
  CodeUnit,
  // Move to the next Unicode code point. At most two code unit when we are
  // at surrogate pair. Please consider using |GraphemeCluster|.
  BackwardDeletion,
  // Move by a grapheme cluster for user-perceived character in Unicode
  // Standard Annex #29, Unicode text segmentation[1].
  // [1] http://www.unicode.org/reports/tr29/
  GraphemeCluster,
};

enum class DeleteDirection {
  Forward,
  Backward,
};

class Document;
class Element;
class HTMLBRElement;
class HTMLElement;
class HTMLLIElement;
class HTMLSpanElement;
class HTMLUListElement;
class Node;
class Range;

// This file contains a set of helper functions used by the editing commands

CORE_EXPORT bool needsLayoutTreeUpdate(const Node&);
CORE_EXPORT bool needsLayoutTreeUpdate(const Position&);
CORE_EXPORT bool needsLayoutTreeUpdate(const PositionInFlatTree&);

// -------------------------------------------------------------------------
// Node
// -------------------------------------------------------------------------

CORE_EXPORT bool hasEditableStyle(const Node&);
CORE_EXPORT bool hasRichlyEditableStyle(const Node&);
CORE_EXPORT bool isRootEditableElement(const Node&);
CORE_EXPORT Element* rootEditableElement(const Node&);
Element* rootEditableElementOf(const Position&);
Element* rootEditableElementOf(const PositionInFlatTree&);
Element* rootEditableElementOf(const VisiblePosition&);
// highestEditableRoot returns the highest editable node. If the
// rootEditableElement of the speicified Position is <body>, this returns the
// <body>. Otherwise, this searches ancestors for the highest editable node in
// defiance of editing boundaries. This returns a Document if designMode="on"
// and the specified Position is not in the <body>.
CORE_EXPORT ContainerNode* highestEditableRoot(
    const Position&,
    Element* (*)(const Position&) = rootEditableElementOf,
    bool (*)(const Node&) = hasEditableStyle);
ContainerNode* highestEditableRoot(const PositionInFlatTree&);

Node* highestEnclosingNodeOfType(
    const Position&,
    bool (*nodeIsOfType)(const Node*),
    EditingBoundaryCrossingRule = CannotCrossEditingBoundary,
    Node* stayWithin = nullptr);
Node* highestNodeToRemoveInPruning(Node*, Node* excludeNode = nullptr);

Element* enclosingBlock(
    Node*,
    EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
CORE_EXPORT Element* enclosingBlock(const Position&,
                                    EditingBoundaryCrossingRule);
CORE_EXPORT Element* enclosingBlock(const PositionInFlatTree&,
                                    EditingBoundaryCrossingRule);
Element* enclosingBlockFlowElement(
    const Node&);  // Deprecated, use enclosingBlock instead.
Element* enclosingTableCell(const Position&);
Element* associatedElementOf(const Position&);
Node* enclosingEmptyListItem(const VisiblePosition&);
Element* enclosingAnchorElement(const Position&);
// Returns the lowest ancestor with the specified QualifiedName. If the
// specified Position is editable, this function returns an editable
// Element. Otherwise, editability doesn't matter.
Element* enclosingElementWithTag(const Position&, const QualifiedName&);
CORE_EXPORT Node* enclosingNodeOfType(
    const Position&,
    bool (*nodeIsOfType)(const Node*),
    EditingBoundaryCrossingRule = CannotCrossEditingBoundary);
CORE_EXPORT Node* enclosingNodeOfType(
    const PositionInFlatTree&,
    bool (*nodeIsOfType)(const Node*),
    EditingBoundaryCrossingRule = CannotCrossEditingBoundary);

HTMLSpanElement* tabSpanElement(const Node*);
Element* tableElementJustAfter(const VisiblePosition&);
CORE_EXPORT Element* tableElementJustBefore(const VisiblePosition&);
CORE_EXPORT Element* tableElementJustBefore(const VisiblePositionInFlatTree&);

// Returns the next leaf node or nullptr if there are no more. Delivers leaf
// nodes as if the whole DOM tree were a linear chain of its leaf nodes.
Node* nextAtomicLeafNode(const Node& start);

// Returns the previous leaf node or nullptr if there are no more. Delivers leaf
// nodes as if the whole DOM tree were a linear chain of its leaf nodes.
Node* previousAtomicLeafNode(const Node& start);

template <typename Strategy>
ContainerNode* parentCrossingShadowBoundaries(const Node&);
template <>
inline ContainerNode* parentCrossingShadowBoundaries<EditingStrategy>(
    const Node& node) {
  return NodeTraversal::parentOrShadowHostNode(node);
}
template <>
inline ContainerNode* parentCrossingShadowBoundaries<EditingInFlatTreeStrategy>(
    const Node& node) {
  return FlatTreeTraversal::parent(node);
}

// boolean functions on Node

// FIXME: editingIgnoresContent, canHaveChildrenForEditing, and isAtomicNode
// should be renamed to reflect its usage.

// Returns true for nodes that either have no content, or have content that is
// ignored (skipped over) while editing. There are no VisiblePositions inside
// these nodes.
inline bool editingIgnoresContent(const Node* node) {
  return EditingStrategy::editingIgnoresContent(node);
}

inline bool canHaveChildrenForEditing(const Node* node) {
  return !node->isTextNode() && node->canContainRangeEndPoint();
}

bool isAtomicNode(const Node*);
CORE_EXPORT bool isEnclosingBlock(const Node*);
bool isTabHTMLSpanElement(const Node*);
bool isTabHTMLSpanElementTextNode(const Node*);
bool isMailHTMLBlockquoteElement(const Node*);
bool isDisplayInsideTable(const Node*);
bool isInline(const Node*);
bool isTableCell(const Node*);
bool isEmptyTableCell(const Node*);
bool isTableStructureNode(const Node*);
bool isHTMLListElement(Node*);
bool isListItem(const Node*);
bool isPresentationalHTMLElement(const Node*);
bool isNodeRendered(const Node&);
bool isNodeVisiblyContainedWithin(Node&, const Range&);
bool isRenderedAsNonInlineTableImageOrHR(const Node*);
// Returns true if specified nodes are elements, have identical tag names,
// have identical attributes, and are editable.
CORE_EXPORT bool areIdenticalElements(const Node&, const Node&);
bool isNonTableCellHTMLBlockElement(const Node*);
bool isBlockFlowElement(const Node&);
bool nodeIsUserSelectAll(const Node*);
EUserSelect usedValueOfUserSelect(const Node&);
bool isTextSecurityNode(const Node*);
CORE_EXPORT TextDirection directionOfEnclosingBlock(const Position&);
CORE_EXPORT TextDirection directionOfEnclosingBlock(const PositionInFlatTree&);
CORE_EXPORT TextDirection primaryDirectionOf(const Node&);

// -------------------------------------------------------------------------
// Position
// -------------------------------------------------------------------------

// Functions returning Position

Position nextCandidate(const Position&);
PositionInFlatTree nextCandidate(const PositionInFlatTree&);
Position previousCandidate(const Position&);
PositionInFlatTree previousCandidate(const PositionInFlatTree&);

CORE_EXPORT Position nextVisuallyDistinctCandidate(const Position&);
CORE_EXPORT PositionInFlatTree
nextVisuallyDistinctCandidate(const PositionInFlatTree&);
Position previousVisuallyDistinctCandidate(const Position&);
PositionInFlatTree previousVisuallyDistinctCandidate(const PositionInFlatTree&);

Position positionBeforeContainingSpecialElement(
    const Position&,
    HTMLElement** containingSpecialElement = nullptr);
Position positionAfterContainingSpecialElement(
    const Position&,
    HTMLElement** containingSpecialElement = nullptr);

inline Position firstPositionInOrBeforeNode(Node* node) {
  return Position::firstPositionInOrBeforeNode(node);
}

inline Position lastPositionInOrAfterNode(Node* node) {
  return Position::lastPositionInOrAfterNode(node);
}

CORE_EXPORT Position firstEditablePositionAfterPositionInRoot(const Position&,
                                                              Node&);
CORE_EXPORT Position lastEditablePositionBeforePositionInRoot(const Position&,
                                                              Node&);
CORE_EXPORT PositionInFlatTree
firstEditablePositionAfterPositionInRoot(const PositionInFlatTree&, Node&);
CORE_EXPORT PositionInFlatTree
lastEditablePositionBeforePositionInRoot(const PositionInFlatTree&, Node&);

// Move up or down the DOM by one position.
// Offsets are computed using layout text for nodes that have layoutObjects -
// but note that even when using composed characters, the result may be inside
// a single user-visible character if a ligature is formed.
CORE_EXPORT Position previousPositionOf(const Position&, PositionMoveType);
CORE_EXPORT Position nextPositionOf(const Position&, PositionMoveType);
CORE_EXPORT PositionInFlatTree previousPositionOf(const PositionInFlatTree&,
                                                  PositionMoveType);
CORE_EXPORT PositionInFlatTree nextPositionOf(const PositionInFlatTree&,
                                              PositionMoveType);

CORE_EXPORT int previousGraphemeBoundaryOf(const Node*, int current);
CORE_EXPORT int nextGraphemeBoundaryOf(const Node*, int current);

// comparision functions on Position

// |disconnected| is optional output parameter having true if specified
// positions don't have common ancestor.
int comparePositionsInDOMTree(Node* containerA,
                              int offsetA,
                              Node* containerB,
                              int offsetB,
                              bool* disconnected = nullptr);
int comparePositionsInFlatTree(Node* containerA,
                               int offsetA,
                               Node* containerB,
                               int offsetB,
                               bool* disconnected = nullptr);
// TODO(yosin): We replace |comparePositions()| by |Position::opeator<()| to
// utilize |DCHECK_XX()|.
int comparePositions(const Position&, const Position&);
int comparePositions(const PositionWithAffinity&, const PositionWithAffinity&);

// boolean functions on Position

// FIXME: Both isEditablePosition and isRichlyEditablePosition rely on
// up-to-date style to give proper results. They shouldn't update style by
// default, but should make it clear that that is the contract.
CORE_EXPORT bool isEditablePosition(const Position&);
bool isEditablePosition(const PositionInFlatTree&);
bool isRichlyEditablePosition(const Position&);
bool lineBreakExistsAtPosition(const Position&);

// miscellaneous functions on Position

enum WhitespacePositionOption {
  NotConsiderNonCollapsibleWhitespace,
  ConsiderNonCollapsibleWhitespace
};

// |leadingWhitespacePosition(position)| returns a previous position of
// |position| if it is at collapsible whitespace, otherwise it returns null
// position. When it is called with |NotConsiderNonCollapsibleWhitespace| and
// a previous position in a element which has CSS property "white-space:pre",
// or its variant, |leadingWhitespacePosition()| returns null position.
// TODO(yosin) We should rename |leadingWhitespacePosition()| to
// |leadingCollapsibleWhitespacePosition()| as this function really returns.
Position leadingWhitespacePosition(
    const Position&,
    TextAffinity,
    WhitespacePositionOption = NotConsiderNonCollapsibleWhitespace);
Position trailingWhitespacePosition(
    const Position&,
    TextAffinity,
    WhitespacePositionOption = NotConsiderNonCollapsibleWhitespace);
unsigned numEnclosingMailBlockquotes(const Position&);
PositionWithAffinity positionRespectingEditingBoundary(
    const Position&,
    const LayoutPoint& localPoint,
    Node* targetNode);
void updatePositionForNodeRemoval(Position&, Node&);

// -------------------------------------------------------------------------
// VisiblePosition
// -------------------------------------------------------------------------

// Functions returning VisiblePosition

// TODO(yosin) We should rename
// |firstEditableVisiblePositionAfterPositionInRoot()| to a better name which
// describes what this function returns, since it returns a position before
// specified position due by canonicalization.
CORE_EXPORT VisiblePosition
firstEditableVisiblePositionAfterPositionInRoot(const Position&,
                                                ContainerNode&);
CORE_EXPORT VisiblePositionInFlatTree
firstEditableVisiblePositionAfterPositionInRoot(const PositionInFlatTree&,
                                                ContainerNode&);
// TODO(yosin) We should rename
// |lastEditableVisiblePositionBeforePositionInRoot()| to a better name which
// describes what this function returns, since it returns a position after
// specified position due by canonicalization.
CORE_EXPORT VisiblePosition
lastEditableVisiblePositionBeforePositionInRoot(const Position&,
                                                ContainerNode&);
CORE_EXPORT VisiblePositionInFlatTree
lastEditableVisiblePositionBeforePositionInRoot(const PositionInFlatTree&,
                                                ContainerNode&);
CORE_EXPORT VisiblePosition visiblePositionBeforeNode(Node&);
VisiblePosition visiblePositionAfterNode(Node&);

bool lineBreakExistsAtVisiblePosition(const VisiblePosition&);

int comparePositions(const VisiblePosition&, const VisiblePosition&);

CORE_EXPORT int indexForVisiblePosition(const VisiblePosition&,
                                        ContainerNode*& scope);
EphemeralRange makeRange(const VisiblePosition&, const VisiblePosition&);
EphemeralRange normalizeRange(const EphemeralRange&);
EphemeralRangeInFlatTree normalizeRange(const EphemeralRangeInFlatTree&);
CORE_EXPORT VisiblePosition visiblePositionForIndex(int index,
                                                    ContainerNode* scope);

// -------------------------------------------------------------------------
// HTMLElement
// -------------------------------------------------------------------------

// Functions returning HTMLElement

HTMLElement* createDefaultParagraphElement(Document&);
HTMLElement* createHTMLElement(Document&, const QualifiedName&);

HTMLElement* enclosingList(Node*);
HTMLElement* outermostEnclosingList(Node*, HTMLElement* rootList = nullptr);
Node* enclosingListChild(Node*);

// -------------------------------------------------------------------------
// Element
// -------------------------------------------------------------------------

// Functions returning Element

HTMLSpanElement* createTabSpanElement(Document&);
HTMLSpanElement* createTabSpanElement(Document&, const String& tabText);

// Boolean functions on Element

bool canMergeLists(Element* firstList, Element* secondList);

// -------------------------------------------------------------------------
// VisibleSelection
// -------------------------------------------------------------------------

// Functions returning VisibleSelection
VisibleSelection selectionForParagraphIteration(const VisibleSelection&);

Position adjustedSelectionStartForStyleComputation(const VisibleSelection&);

// Miscellaneous functions on Text
inline bool isWhitespace(UChar c) {
  return c == noBreakSpaceCharacter || c == ' ' || c == '\n' || c == '\t';
}

// FIXME: Can't really answer this question correctly without knowing the
// white-space mode.
inline bool isCollapsibleWhitespace(UChar c) {
  return c == ' ' || c == '\n';
}

inline bool isAmbiguousBoundaryCharacter(UChar character) {
  // These are characters that can behave as word boundaries, but can appear
  // within words. If they are just typed, i.e. if they are immediately followed
  // by a caret, we want to delay text checking until the next character has
  // been typed.
  // FIXME: this is required until 6853027 is fixed and text checking can do
  // this for us.
  return character == '\'' || character == rightSingleQuotationMarkCharacter ||
         character == hebrewPunctuationGershayimCharacter;
}

String stringWithRebalancedWhitespace(const String&,
                                      bool startIsStartOfParagraph,
                                      bool shouldEmitNBSPbeforeEnd);
const String& nonBreakingSpaceString();

// -------------------------------------------------------------------------
// Events
// -------------------------------------------------------------------------

// Functions dispatch InputEvent
DispatchEventResult dispatchBeforeInputInsertText(EventTarget*,
                                                  const String& data);
DispatchEventResult dispatchBeforeInputFromComposition(
    EventTarget*,
    InputEvent::InputType,
    const String& data,
    InputEvent::EventCancelable);
DispatchEventResult dispatchBeforeInputEditorCommand(EventTarget*,
                                                     InputEvent::InputType,
                                                     const RangeVector*);
DispatchEventResult dispatchBeforeInputDataTransfer(EventTarget*,
                                                    InputEvent::InputType,
                                                    DataTransfer*,
                                                    const RangeVector*);

InputEvent::InputType deletionInputTypeFromTextGranularity(DeleteDirection,
                                                           TextGranularity);

}  // namespace blink

#endif
