/*
 * Copyright (C) 2011, 2013 Google Inc.  All rights reserved.
 * Copyright (C) 2011-2019 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "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 THE COPYRIGHT
 * OWNER 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.
 */

#include "config.h"
#include "VTTCue.h"

#if ENABLE(VIDEO)

#include "CSSPropertyNames.h"
#include "CSSValueKeywords.h"
#include "DocumentFragment.h"
#include "Event.h"
#include "HTMLDivElement.h"
#include "HTMLSpanElement.h"
#include "HTMLStyleElement.h"
#include "Logging.h"
#include "NodeTraversal.h"
#include "RenderVTTCue.h"
#include "ScriptDisallowedScope.h"
#include "ShadowPseudoIds.h"
#include "Text.h"
#include "TextTrack.h"
#include "TextTrackCueGeneric.h"
#include "TextTrackCueList.h"
#include "VTTRegionList.h"
#include "VTTScanner.h"
#include "WebVTTElement.h"
#include "WebVTTParser.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/MathExtras.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/StringConcatenateNumbers.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(VTTCue);
WTF_MAKE_ISO_ALLOCATED_IMPL(VTTCueBox);

// This constant should correspond with the percentage returned by CaptionUserPreferences::captionFontSizeScaleAndImportance.
constexpr double DEFAULTCAPTIONFONTSIZEPERCENTAGE = 5;

static const CSSValueID displayWritingModeMap[] = {
    CSSValueHorizontalTb, CSSValueVerticalRl, CSSValueVerticalLr
};
COMPILE_ASSERT(WTF_ARRAY_LENGTH(displayWritingModeMap) == VTTCue::NumberOfWritingDirections, displayWritingModeMap_has_wrong_size);

static const CSSValueID displayAlignmentMap[] = {
    CSSValueStart, CSSValueCenter, CSSValueEnd, CSSValueLeft, CSSValueRight
};
COMPILE_ASSERT(WTF_ARRAY_LENGTH(displayAlignmentMap) == VTTCue::NumberOfAlignments, displayAlignmentMap_has_wrong_size);

static const String& startKeyword()
{
    static NeverDestroyed<const String> start(MAKE_STATIC_STRING_IMPL("start"));
    return start;
}

static const String& centerKeyword()
{
    static NeverDestroyed<const String> center(MAKE_STATIC_STRING_IMPL("center"));
    return center;
}

static const String& endKeyword()
{
    static NeverDestroyed<const String> end(MAKE_STATIC_STRING_IMPL("end"));
    return end;
}

static const String& leftKeyword()
{
    static NeverDestroyed<const String> left(MAKE_STATIC_STRING_IMPL("left"));
    return left;
}

static const String& rightKeyword()
{
    static NeverDestroyed<const String> right(MAKE_STATIC_STRING_IMPL("right"));
    return right;
}

static const String& horizontalKeyword()
{
    return emptyString();
}

static const String& verticalGrowingLeftKeyword()
{
    static NeverDestroyed<const String> verticalrl(MAKE_STATIC_STRING_IMPL("rl"));
    return verticalrl;
}

static const String& verticalGrowingRightKeyword()
{
    static NeverDestroyed<const String> verticallr(MAKE_STATIC_STRING_IMPL("lr"));
    return verticallr;
}

static const String& lineLeftKeyword()
{
    static NeverDestroyed<const String> lineLeft(MAKE_STATIC_STRING_IMPL("line-left"));
    return lineLeft;
}

static const String& lineRightKeyword()
{
    static NeverDestroyed<const String> lineRight(MAKE_STATIC_STRING_IMPL("line-right"));
    return lineRight;
}

static const String& autoKeyword()
{
    static NeverDestroyed<const String> autoX(MAKE_STATIC_STRING_IMPL("auto"));
    return autoX;
}

// ----------------------------

Ref<VTTCueBox> VTTCueBox::create(Document& document, VTTCue& cue)
{
    auto box = adoptRef(*new VTTCueBox(document, cue));
    box->initialize();
    return box;
}

VTTCueBox::VTTCueBox(Document& document, VTTCue& cue)
    : TextTrackCueBox(document, cue)
{
}

void VTTCueBox::applyCSSProperties(const IntSize& videoSize)
{
    auto textTrackCue = getCue();
    ASSERT(!textTrackCue || is<VTTCue>(textTrackCue));
    if (!is<VTTCue>(textTrackCue))
        return;

    Ref cue = downcast<VTTCue>(*textTrackCue);

    // FIXME: Apply all the initial CSS positioning properties. http://wkb.ug/79916
    if (!cue->regionId().isEmpty()) {
        setInlineStyleProperty(CSSPropertyPosition, CSSValueRelative);
        return;
    }

    // 3.5.1 On the (root) List of WebVTT Node Objects:

    // the 'position' property must be set to 'absolute'
    setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute);

    //  the 'unicode-bidi' property must be set to 'plaintext'
    setInlineStyleProperty(CSSPropertyUnicodeBidi, CSSValuePlaintext);

    // the 'direction' property must be set to direction
    setInlineStyleProperty(CSSPropertyDirection, cue->getCSSWritingDirection());

    // the 'writing-mode' property must be set to writing-mode
    setInlineStyleProperty(CSSPropertyWritingMode, cue->getCSSWritingMode(), false);

    auto position = cue->getCSSPosition();

    // the 'top' property must be set to top,
    setInlineStyleProperty(CSSPropertyTop, position.second, CSSUnitType::CSS_PERCENTAGE);

    // the 'left' property must be set to left
    if (cue->vertical() == horizontalKeyword())
        setInlineStyleProperty(CSSPropertyLeft, position.first, CSSUnitType::CSS_PERCENTAGE);
    else if (cue->vertical() == verticalGrowingRightKeyword()) {
        // FIXME: Why use calc to do the math instead of doing the subtraction here?
        setInlineStyleProperty(CSSPropertyLeft, makeString("calc(-", videoSize.width(), "px - ", cue->getCSSSize(), "px)"));
    }

    double authorFontSize = std::min(videoSize.width(), videoSize.height()) * DEFAULTCAPTIONFONTSIZEPERCENTAGE / 100.0;
    double multiplier = 1.0;
    if (authorFontSize)
        multiplier = m_fontSizeFromCaptionUserPrefs / authorFontSize;

    double textPosition = cue->calculateComputedTextPosition();
    double maxSize = 100.0;
    CSSValueID alignment = cue->getCSSAlignment();
    if (alignment == CSSValueEnd || alignment == CSSValueRight)
        maxSize = textPosition;
    else if (alignment == CSSValueStart || alignment == CSSValueLeft)
        maxSize = 100.0 - textPosition;

    double newCueSize = std::min(cue->getCSSSize() * multiplier, 100.0);
    // the 'width' property must be set to width, and the 'height' property  must be set to height
    if (cue->vertical() == horizontalKeyword()) {
        setInlineStyleProperty(CSSPropertyWidth, newCueSize, CSSUnitType::CSS_PERCENTAGE);
        setInlineStyleProperty(CSSPropertyHeight, CSSValueAuto);
        setInlineStyleProperty(CSSPropertyMinWidth, "min-content");
        setInlineStyleProperty(CSSPropertyMaxWidth, maxSize, CSSUnitType::CSS_PERCENTAGE);
        if ((alignment == CSSValueMiddle || alignment == CSSValueCenter) && multiplier != 1.0)
            setInlineStyleProperty(CSSPropertyLeft, static_cast<double>(position.first - (newCueSize - cue->getCSSSize()) / 2), CSSUnitType::CSS_PERCENTAGE);
    } else {
        setInlineStyleProperty(CSSPropertyWidth, CSSValueAuto);
        setInlineStyleProperty(CSSPropertyHeight, newCueSize, CSSUnitType::CSS_PERCENTAGE);
        setInlineStyleProperty(CSSPropertyMinHeight, "min-content");
        setInlineStyleProperty(CSSPropertyMaxHeight, maxSize, CSSUnitType::CSS_PERCENTAGE);
        if ((alignment == CSSValueMiddle || alignment == CSSValueCenter) && multiplier != 1.0)
            setInlineStyleProperty(CSSPropertyTop, static_cast<double>(position.second - (newCueSize - cue->getCSSSize()) / 2), CSSUnitType::CSS_PERCENTAGE);
    }

    // The 'text-align' property on the (root) List of WebVTT Node Objects must
    // be set to the value in the second cell of the row of the table below
    // whose first cell is the value of the corresponding cue's text track cue
    // alignment:
    setInlineStyleProperty(CSSPropertyTextAlign, cue->getCSSAlignment());
    
    if (!cue->snapToLines()) {
        // 10.13.1 Set up x and y:
        // Note: x and y are set through the CSS left and top above.

        // 10.13.2 Position the boxes in boxes such that the point x% along the
        // width of the bounding box of the boxes in boxes is x% of the way
        // across the width of the video's rendering area, and the point y%
        // along the height of the bounding box of the boxes in boxes is y%
        // of the way across the height of the video's rendering area, while
        // maintaining the relative positions of the boxes in boxes to each
        // other.
        setInlineStyleProperty(CSSPropertyTransform, makeString("translate(", -position.first, "%, ", -position.second, "%)"));

        setInlineStyleProperty(CSSPropertyWhiteSpace, CSSValuePre);
    }

    // Make sure shadow or stroke is not clipped.
    setInlineStyleProperty(CSSPropertyOverflow, CSSValueVisible);
    cue->element().setInlineStyleProperty(CSSPropertyOverflow, CSSValueVisible);
}

RenderPtr<RenderElement> VTTCueBox::createElementRenderer(RenderStyle&& style, const RenderTreePosition&)
{
    return createRenderer<RenderVTTCue>(*this, WTFMove(style));
}

// ----------------------------

Ref<VTTCue> VTTCue::create(Document& document, double start, double end, String&& content)
{
    auto cue = adoptRef(*new VTTCue(document, MediaTime::createWithDouble(start), MediaTime::createWithDouble(end), WTFMove(content)));
    cue->suspendIfNeeded();
    return cue;
}

Ref<VTTCue> VTTCue::create(Document& document, const WebVTTCueData& data)
{
    auto cue = adoptRef(*new VTTCue(document, data));
    cue->suspendIfNeeded();
    return cue;
}

VTTCue::VTTCue(Document& document, const MediaTime& start, const MediaTime& end, String&& content)
    : TextTrackCue(document, start, end)
    , m_content(WTFMove(content))
    , m_originalStartTime(MediaTime::zeroTime())
{
    initialize();
}

VTTCue::VTTCue(Document& document, const WebVTTCueData& cueData)
    : TextTrackCue(document, MediaTime::zeroTime(), MediaTime::zeroTime())
    , m_originalStartTime(cueData.originalStartTime())
{
    initialize();
    setText(cueData.content());
    setStartTime(cueData.startTime());
    setEndTime(cueData.endTime());
    setId(cueData.id());
    setCueSettings(cueData.settings());
}

VTTCue::~VTTCue()
{
}

void VTTCue::initialize()
{
    m_cueBackdropBox = HTMLDivElement::create(ownerDocument());
    m_cueHighlightBox = HTMLSpanElement::create(spanTag, ownerDocument());
    m_snapToLines = true;
    m_displayTreeShouldChange = true;
    m_notifyRegion = true;
}

Ref<VTTCueBox> VTTCue::createDisplayTree()
{
    return VTTCueBox::create(ownerDocument(), *this);
}

VTTCueBox& VTTCue::displayTreeInternal()
{
    if (!m_displayTree)
        m_displayTree = createDisplayTree();
    return *m_displayTree;
}

void VTTCue::didChange()
{
    TextTrackCue::didChange();
    m_displayTreeShouldChange = true;
}

const String& VTTCue::vertical() const
{
    switch (m_writingDirection) {
    case Horizontal: 
        return horizontalKeyword();
    case VerticalGrowingLeft:
        return verticalGrowingLeftKeyword();
    case VerticalGrowingRight:
        return verticalGrowingRightKeyword();
    default:
        ASSERT_NOT_REACHED();
        return emptyString();
    }
}

ExceptionOr<void> VTTCue::setVertical(const String& value)
{
    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-vertical
    // On setting, the text track cue writing direction must be set to the value given 
    // in the first cell of the row in the table above whose second cell is a 
    // case-sensitive match for the new value, if any. If none of the values match, then
    // the user agent must instead throw a SyntaxError exception.
    
    WritingDirection direction = m_writingDirection;
    if (value == horizontalKeyword())
        direction = Horizontal;
    else if (value == verticalGrowingLeftKeyword())
        direction = VerticalGrowingLeft;
    else if (value == verticalGrowingRightKeyword())
        direction = VerticalGrowingRight;
    else
        return { };

    if (direction == m_writingDirection)
        return { };

    willChange();
    m_writingDirection = direction;
    didChange();

    return { };
}

void VTTCue::setSnapToLines(bool value)
{
    if (m_snapToLines == value)
        return;
    
    willChange();
    m_snapToLines = value;
    didChange();
}

VTTCue::LineAndPositionSetting VTTCue::line() const
{
    if (std::isnan(m_linePosition))
        return Auto;

    return m_linePosition;
}

ExceptionOr<void> VTTCue::setLine(const LineAndPositionSetting& position)
{
    double linePosition = 0;

    if (std::holds_alternative<AutoKeyword>(position)) {
        if (std::isnan(m_linePosition))
            return { };
        linePosition = std::numeric_limits<double>::quiet_NaN();
    } else {
        linePosition = std::get<double>(position);

        if (m_linePosition == linePosition)
            return { };
    }

    willChange();
    m_linePosition = linePosition;
    m_computedLinePosition = calculateComputedLinePosition();
    didChange();

    return { };
}

const String& VTTCue::lineAlign() const
{
    switch (m_lineAlignment) {
    case LignAlignmentStart:
        return startKeyword();
    case LignAlignmentCenter:
        return centerKeyword();
    case LignAlignmentEnd:
        return endKeyword();
    default:
        ASSERT_NOT_REACHED();
        return emptyString();
    }
}

ExceptionOr<void> VTTCue::setLineAlign(const String& value)
{
    CueLignAlignment lineAlignment;
    if (value == startKeyword())
        lineAlignment = LignAlignmentStart;
    else if (value == centerKeyword())
        lineAlignment = LignAlignmentCenter;
    else if (value == endKeyword())
        lineAlignment = LignAlignmentEnd;
    else
        return { };

    if (lineAlignment == m_lineAlignment)
        return { };

    willChange();
    m_lineAlignment = lineAlignment;
    didChange();

    return { };
}


VTTCue::LineAndPositionSetting VTTCue::position() const
{
    if (textPositionIsAuto())
        return Auto;
    return m_textPosition;
}

ExceptionOr<void> VTTCue::setPosition(const LineAndPositionSetting& position)
{
    // http://dev.w3.org/html5/webvtt/#dfn-vttcue-position
    // On setting, if the new value is negative or greater than 100, then an
    // IndexSizeError exception must be thrown. Otherwise, the WebVTT cue
    // position must be set to the new value; if the new value is the string
    // "auto", then it must be interpreted as the special value auto.
    double textPosition = 0;
    if (std::holds_alternative<AutoKeyword>(position)) {
        if (textPositionIsAuto())
            return { };
        textPosition = std::numeric_limits<double>::quiet_NaN();
    } else {
        textPosition = std::get<double>(position);
        if (!(textPosition >= 0 && textPosition <= 100))
            return Exception { IndexSizeError };

        // Otherwise, set the text track cue line position to the new value.
        if (m_textPosition == textPosition)
            return { };
    }

    willChange();
    m_textPosition = textPosition;
    didChange();

    return { };
}

const String& VTTCue::positionAlign() const
{
    switch (m_positionAlignment) {
    case PositionAlignmentLignLeft:
        return lineLeftKeyword();
    case PositionAlignmentLignCenter:
        return centerKeyword();
    case PositionAlignmentLignRight:
        return lineRightKeyword();
    case PositionAlignmentLignAuto:
        return autoKeyword();
    default:
        ASSERT_NOT_REACHED();
        return emptyString();
    }
}

ExceptionOr<void> VTTCue::setPositionAlign(const String& value)
{
    CuePositionAlignment positionAlignment;
    if (value == lineLeftKeyword())
        positionAlignment = PositionAlignmentLignLeft;
    else if (value == centerKeyword())
        positionAlignment = PositionAlignmentLignCenter;
    else if (value == lineRightKeyword())
        positionAlignment = PositionAlignmentLignRight;
    else if (value == autoKeyword())
        positionAlignment = PositionAlignmentLignAuto;
    else
        return { };

    if (positionAlignment == m_positionAlignment)
        return { };

    willChange();
    m_positionAlignment = positionAlignment;
    didChange();

    return { };
}

ExceptionOr<void> VTTCue::setSize(int size)
{
    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-size
    // On setting, if the new value is negative or greater than 100, then throw an IndexSizeError
    // exception. Otherwise, set the text track cue size to the new value.
    if (!(size >= 0 && size <= 100))
        return Exception { IndexSizeError };

    // Otherwise, set the text track cue line position to the new value.
    if (m_cueSize == size)
        return { };
    
    willChange();
    m_cueSize = size;
    didChange();

    return { };
}

const String& VTTCue::align() const
{
    switch (m_cueAlignment) {
    case Start:
        return startKeyword();
    case Center:
        return centerKeyword();
    case End:
        return endKeyword();
    case Left:
        return leftKeyword();
    case Right:
        return rightKeyword();
    default:
        ASSERT_NOT_REACHED();
        return emptyString();
    }
}

ExceptionOr<void> VTTCue::setAlign(const String& value)
{
    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#dom-texttrackcue-align
    // On setting, the text track cue alignment must be set to the value given in the 
    // first cell of the row in the table above whose second cell is a case-sensitive
    // match for the new value, if any. If none of the values match, then the user
    // agent must instead throw a SyntaxError exception.
    
    CueAlignment alignment;
    if (value == startKeyword())
        alignment = Start;
    else if (value == centerKeyword())
        alignment = Center;
    else if (value == endKeyword())
        alignment = End;
    else if (value == leftKeyword())
        alignment = Left;
    else if (value == rightKeyword())
        alignment = Right;
    else
        return { };

    if (alignment == m_cueAlignment)
        return { };

    willChange();
    m_cueAlignment = alignment;
    didChange();

    return { };
}
    
void VTTCue::setText(const String& text)
{
    if (m_content == text)
        return;
    
    willChange();
    // Clear the document fragment but don't bother to create it again just yet as we can do that
    // when it is requested.
    m_webVTTNodeTree = nullptr;
    m_content = text;
    didChange();
}

void VTTCue::createWebVTTNodeTree()
{
    if (!m_webVTTNodeTree)
        m_webVTTNodeTree = WebVTTParser::createDocumentFragmentFromCueText(ownerDocument(), m_content);
}

static void copyWebVTTNodeToDOMTree(ContainerNode& webVTTNode, Node& parent)
{
    for (RefPtr<Node> node = webVTTNode.firstChild(); node; node = node->nextSibling()) {
        RefPtr<Node> clonedNode;
        if (is<WebVTTElement>(*node))
            clonedNode = downcast<WebVTTElement>(*node).createEquivalentHTMLElement(parent.document());
        else
            clonedNode = node->cloneNode(false);
        parent.appendChild(*clonedNode);
        if (is<ContainerNode>(*node))
            copyWebVTTNodeToDOMTree(downcast<ContainerNode>(*node), *clonedNode);
    }
}

RefPtr<DocumentFragment> VTTCue::getCueAsHTML()
{
    createWebVTTNodeTree();
    if (!m_webVTTNodeTree)
        return nullptr;

    auto clonedFragment = DocumentFragment::create(ownerDocument());
    copyWebVTTNodeToDOMTree(*m_webVTTNodeTree, clonedFragment);
    return clonedFragment;
}

RefPtr<DocumentFragment> VTTCue::createCueRenderingTree()
{
    createWebVTTNodeTree();
    if (!m_webVTTNodeTree)
        return nullptr;

    auto clonedFragment = DocumentFragment::create(ownerDocument());

    // The cloned fragment is never exposed to author scripts so it's safe to dispatch events here.
    ScriptDisallowedScope::EventAllowedScope allowedScope(clonedFragment);

    m_webVTTNodeTree->cloneChildNodes(clonedFragment);
    return clonedFragment;
}

void VTTCue::notifyRegionWhenRemovingDisplayTree(bool notifyRegion)
{
    m_notifyRegion = notifyRegion;
}

void VTTCue::setIsActive(bool active)
{
    TextTrackCue::setIsActive(active);

    if (!active) {
        if (!hasDisplayTree())
            return;

        // Remove the display tree as soon as the cue becomes inactive.
        removeDisplayTree();
    }
}

void VTTCue::setTrack(TextTrack* track)
{
    LOG(Media, "VTTCue::setTrack");
    TextTrackCue::setTrack(track);
    if (!m_parsedRegionId.isEmpty()) {
        if (track != nullptr) {
            if (auto* regions = track->regions()) {
                if (auto region = regions->getRegionById(m_parsedRegionId))
                    m_region = RefPtr<VTTRegion>(region);
            }
        }
    }
}

void VTTCue::setRegion(VTTRegion* region)
{
    if (m_region != region) {
        willChange();
        m_region = region;
        didChange();
    }
}

VTTRegion* VTTCue::region()
{
    if (!m_region)
        return nullptr;

    return &*m_region;
}

const String& VTTCue::regionId()
{
    if (!m_region)
        return emptyString();

    return m_region->id();
}

int VTTCue::calculateComputedLinePosition()
{
    // http://www.whatwg.org/specs/web-apps/current-work/multipage/the-video-element.html#text-track-cue-computed-line-position

    // If the text track cue line position is numeric, then that is the text
    // track cue computed line position.
    if (!std::isnan(m_linePosition))
        return m_linePosition;

    // If the text track cue snap-to-lines flag of the text track cue is not
    // set, the text track cue computed line position is the value 100;
    if (!m_snapToLines)
        return 100;

    // Otherwise, it is the value returned by the following algorithm:

    // If cue is not associated with a text track, return -1 and abort these
    // steps.
    if (!track())
        return -1;

    // Let n be the number of text tracks whose text track mode is showing or
    // showing by default and that are in the media element's list of text
    // tracks before track.
    int n = track()->trackIndexRelativeToRenderedTracks();

    // Increment n by one.
    n++;

    // Negate n.
    n = -n;

    return n;
}

static bool isCueParagraphSeparator(UChar character)
{
    // Within a cue, paragraph boundaries are only denoted by Type B characters,
    // such as U+000A LINE FEED (LF), U+0085 NEXT LINE (NEL), and U+2029 PARAGRAPH SEPARATOR.
    return u_charType(character) == U_PARAGRAPH_SEPARATOR;
}

bool VTTCue::textPositionIsAuto() const
{
    return std::isnan(m_textPosition);
}

void VTTCue::determineTextDirection()
{
    static NeverDestroyed<const String> rtTag(MAKE_STATIC_STRING_IMPL("rt"));
    createWebVTTNodeTree();
    if (!m_webVTTNodeTree)
        return;

    // Apply the Unicode Bidirectional Algorithm's Paragraph Level steps to the
    // concatenation of the values of each WebVTT Text Object in nodes, in a
    // pre-order, depth-first traversal, excluding WebVTT Ruby Text Objects and
    // their descendants.
    StringBuilder paragraphBuilder;
    for (RefPtr<Node> node = m_webVTTNodeTree->firstChild(); node; node = NodeTraversal::next(*node, m_webVTTNodeTree.get())) {
        // FIXME: The code does not match the comment above. This does not actually exclude Ruby Text Object descendant.
        if (!node->isTextNode() || node->localName() == rtTag)
            continue;

        paragraphBuilder.append(node->nodeValue());
    }

    String paragraph = paragraphBuilder.toString();
    if (!paragraph.length())
        return;

    for (size_t i = 0; i < paragraph.length(); ++i) {
        UChar current = paragraph[i];
        if (!current || isCueParagraphSeparator(current))
            return;

        if (UChar current = paragraph[i]) {
            UCharDirection charDirection = u_charDirection(current);
            if (charDirection == U_LEFT_TO_RIGHT) {
                m_displayDirection = CSSValueLtr;
                return;
            }
            if (charDirection == U_RIGHT_TO_LEFT || charDirection == U_RIGHT_TO_LEFT_ARABIC) {
                m_displayDirection = CSSValueRtl;
                return;
            }
        }
    }
}

double VTTCue::calculateComputedTextPosition() const
{
    // http://dev.w3.org/html5/webvtt/#dfn-cue-computed-position
    
    // 1. If the position is numeric, then return the value of the position and
    // abort these steps. (Otherwise, the position is the special value auto.)
    if (!textPositionIsAuto())
        return m_textPosition;
    
    switch (m_cueAlignment) {
    case Start:
    case Left:
        // 2. If the cue text alignment is start or left, return 0 and abort these
        // steps.
        return 0;
    case End:
    case Right:
        // 3. If the cue text alignment is end or right, return 100 and abort these
        // steps.
        return 100;
    case Center:
        // 4. If the cue text alignment is center, return 50 and abort these steps.
        return 50;
    default:
        ASSERT_NOT_REACHED();
        return 0;
    }
}

void VTTCue::calculateDisplayParameters()
{
    // Steps 10.2, 10.3
    determineTextDirection();

    // 10.4 If the text track cue writing direction is horizontal, then let
    // block-flow be 'tb'. Otherwise, if the text track cue writing direction is
    // vertical growing left, then let block-flow be 'lr'. Otherwise, the text
    // track cue writing direction is vertical growing right; let block-flow be
    // 'rl'.

    // The above step is done through the writing direction static map.

    // 10.5 Determine the value of maximum size for cue as per the appropriate
    // rules from the following list:
    double computedTextPosition = calculateComputedTextPosition();
    int maximumSize = computedTextPosition;
    if ((m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueLtr)
        || (m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueRtl)
        || (m_writingDirection == Horizontal && m_cueAlignment == Left)
        || (m_writingDirection == VerticalGrowingLeft && (m_cueAlignment == Start || m_cueAlignment == Left))
        || (m_writingDirection == VerticalGrowingRight && (m_cueAlignment == Start || m_cueAlignment == Left))) {
        maximumSize = 100 - computedTextPosition;
    } else if ((m_writingDirection == Horizontal && m_cueAlignment == End && m_displayDirection == CSSValueLtr)
        || (m_writingDirection == Horizontal && m_cueAlignment == Start && m_displayDirection == CSSValueRtl)
        || (m_writingDirection == Horizontal && m_cueAlignment == Right)
        || (m_writingDirection == VerticalGrowingLeft && (m_cueAlignment == End || m_cueAlignment == Right))
        || (m_writingDirection == VerticalGrowingRight && (m_cueAlignment == End || m_cueAlignment == Right))) {
        maximumSize = computedTextPosition;
    } else if (m_cueAlignment == Center) {
        maximumSize = computedTextPosition <= 50 ? computedTextPosition : (100 - computedTextPosition);
        maximumSize = maximumSize * 2;
    } else
        ASSERT_NOT_REACHED();

    // 10.6 If the text track cue size is less than maximum size, then let size
    // be text track cue size. Otherwise, let size be maximum size.
    m_displaySize = std::min(m_cueSize, maximumSize);

    // FIXME: Understand why step 10.7 is missing (just a copy/paste error?)
    // Could be done within a spec implementation check - http://crbug.com/301580

    // 10.8 Determine the value of x-position or y-position for cue as per the
    // appropriate rules from the following list:
    if (m_writingDirection == Horizontal) {
        switch (m_cueAlignment) {
        case Start:
            if (m_displayDirection == CSSValueLtr)
                m_displayPosition.first = computedTextPosition;
            else
                m_displayPosition.first = 100 - computedTextPosition - m_displaySize;
            break;
        case End:
            if (m_displayDirection == CSSValueRtl)
                m_displayPosition.first = 100 - computedTextPosition;
            else
                m_displayPosition.first = computedTextPosition - m_displaySize;
            break;
        case Left:
            if (m_displayDirection == CSSValueLtr)
                m_displayPosition.first = computedTextPosition;
            else
                m_displayPosition.first = 100 - computedTextPosition;
            break;
        case Right:
            if (m_displayDirection == CSSValueLtr)
                m_displayPosition.first = computedTextPosition - m_displaySize;
            else
                m_displayPosition.first = 100 - computedTextPosition - m_displaySize;
            break;
        case Center:
            if (m_displayDirection == CSSValueLtr)
                m_displayPosition.first = computedTextPosition - m_displaySize / 2;
            else
                m_displayPosition.first = 100 - computedTextPosition - m_displaySize / 2;
            break;
        case NumberOfAlignments:
            ASSERT_NOT_REACHED();
        }
    }

    // A text track cue has a text track cue computed line position whose value
    // is defined in terms of the other aspects of the cue.
    m_computedLinePosition = calculateComputedLinePosition();

    // 10.9 Determine the value of whichever of x-position or y-position is not
    // yet calculated for cue as per the appropriate rules from the following
    // list:
    if (m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal)
        m_displayPosition.second = 0;

    if (!m_snapToLines && m_displayPosition.second == undefinedPosition && m_writingDirection == Horizontal)
        m_displayPosition.second = m_computedLinePosition;

    if (m_snapToLines && m_displayPosition.first == undefinedPosition
        && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight))
        m_displayPosition.first = 0;

    if (!m_snapToLines && (m_writingDirection == VerticalGrowingLeft || m_writingDirection == VerticalGrowingRight))
        m_displayPosition.first = m_computedLinePosition;
}
    
void VTTCue::markFutureAndPastNodes(ContainerNode* root, const MediaTime& previousTimestamp, const MediaTime& movieTime)
{
    static NeverDestroyed<const String> timestampTag(MAKE_STATIC_STRING_IMPL("timestamp"));
    
    bool isPastNode = true;
    MediaTime currentTimestamp = previousTimestamp;
    if (currentTimestamp > movieTime)
        isPastNode = false;
    
    for (RefPtr<Node> child = root->firstChild(); child; child = NodeTraversal::next(*child, root)) {
        if (child->nodeName() == timestampTag) {
            MediaTime currentTimestamp;
            bool check = WebVTTParser::collectTimeStamp(child->nodeValue(), currentTimestamp);
            ASSERT_UNUSED(check, check);
            
            currentTimestamp += m_originalStartTime;
            if (currentTimestamp > movieTime)
                isPastNode = false;
        }
        
        if (is<WebVTTElement>(*child)) {
            downcast<WebVTTElement>(*child).setIsPastNode(isPastNode);
            // Make an elemenet id match a cue id for style matching purposes.
            if (!id().isEmpty())
                downcast<WebVTTElement>(*child).setIdAttribute(id());
        }
    }
}

void VTTCue::updateDisplayTree(const MediaTime& movieTime)
{
    // The display tree may contain WebVTT timestamp objects representing
    // timestamps (processing instructions), along with displayable nodes.

    if (!track()->isRendered())
        return;

    // Mutating the VTT contents is safe because it's never exposed to author scripts.
    ScriptDisallowedScope::EventAllowedScope allowedScopeForCueHighlightBox(*m_cueHighlightBox);

    // Clear the contents of the set.
    m_cueHighlightBox->removeChildren();

    // Update the two sets containing past and future WebVTT objects.
    RefPtr<DocumentFragment> referenceTree = createCueRenderingTree();
    if (!referenceTree)
        return;

    ScriptDisallowedScope::EventAllowedScope allowedScopeForReferenceTree(*referenceTree);

    markFutureAndPastNodes(referenceTree.get(), startMediaTime(), movieTime);
    m_cueHighlightBox->appendChild(*referenceTree);
}

RefPtr<TextTrackCueBox> VTTCue::getDisplayTree(const IntSize& videoSize, int fontSize)
{
    Ref<VTTCueBox> displayTree = displayTreeInternal();
    if (!m_displayTreeShouldChange || !track()->isRendered())
        return displayTree;

    // 10.1 - 10.10
    calculateDisplayParameters();

    // 10.11. Apply the terms of the CSS specifications to nodes within the
    // following constraints, thus obtaining a set of CSS boxes positioned
    // relative to an initial containing block:
    displayTree->removeChildren();

    // The document tree is the tree of WebVTT Node Objects rooted at nodes.

    // The children of the nodes must be wrapped in an anonymous box whose
    // 'display' property has the value 'inline'. This is the WebVTT cue
    // background box.

    // Note: This is contained by default in m_cueHighlightBox.
    m_cueHighlightBox->setPseudo(ShadowPseudoIds::cue());

    m_cueBackdropBox->setPseudo(ShadowPseudoIds::webkitMediaTextTrackDisplayBackdrop());
    m_cueBackdropBox->appendChild(*m_cueHighlightBox);
    displayTree->appendChild(*m_cueBackdropBox);

    // FIXME(BUG 79916): Runs of children of WebVTT Ruby Objects that are not
    // WebVTT Ruby Text Objects must be wrapped in anonymous boxes whose
    // 'display' property has the value 'ruby-base'.

    displayTree->setFontSizeFromCaptionUserPrefs(fontSize);
    displayTree->applyCSSProperties(videoSize);

    if (displayTree->document().page()) {
        auto cssString = displayTree->document().page()->captionUserPreferencesStyleSheet();
        auto style = HTMLStyleElement::create(HTMLNames::styleTag, displayTree->document(), false);
        style->setTextContent(cssString);
        displayTree->appendChild(style);
    }

    const auto& styleSheets = track()->styleSheets();
    if (styleSheets) {
        for (const auto& cssString : *styleSheets) {
            auto style = HTMLStyleElement::create(HTMLNames::styleTag, displayTree->document(), false);
            style->setTextContent(cssString);
            displayTree->appendChild(style);
        }
    }

    if (m_fontSize)
        displayTree->setInlineStyleProperty(CSSPropertyFontSize, m_fontSize, CSSUnitType::CSS_PX, m_fontSizeIsImportant);

    m_displayTreeShouldChange = false;

    if (track()) {
        if (m_region)
            m_region->cueStyleChanged();
    }

    // 10.15. Let cue's text track cue display state have the CSS boxes in
    // boxes.
    return displayTree;
}

void VTTCue::removeDisplayTree()
{
    if (!hasDisplayTree())
        return;

    // The region needs to be informed about the cue removal.
    if (m_notifyRegion && track()) {
        if (m_region && m_displayTree)
            m_region->willRemoveTextTrackCueBox(m_displayTree.get());
    }

    // The display tree is never exposed to author scripts so it's safe to dispatch events here.
    ScriptDisallowedScope::EventAllowedScope allowedScope(displayTreeInternal());
    displayTreeInternal().remove();
}

std::pair<double, double> VTTCue::getPositionCoordinates() const
{
    // This method is used for setting x and y when snap to lines is not set.
    std::pair<double, double> coordinates;

    auto textPosition = calculateComputedTextPosition();
    
    if (m_writingDirection == Horizontal && m_displayDirection == CSSValueLtr) {
        coordinates.first = textPosition;
        coordinates.second = m_computedLinePosition;

        return coordinates;
    }

    if (m_writingDirection == Horizontal && m_displayDirection == CSSValueRtl) {
        coordinates.first = 100 - textPosition;
        coordinates.second = m_computedLinePosition;

        return coordinates;
    }

    if (m_writingDirection == VerticalGrowingLeft) {
        coordinates.first = 100 - m_computedLinePosition;
        coordinates.second = textPosition;

        return coordinates;
    }

    if (m_writingDirection == VerticalGrowingRight) {
        coordinates.first = m_computedLinePosition;
        coordinates.second = textPosition;

        return coordinates;
    }

    ASSERT_NOT_REACHED();

    return coordinates;
}

VTTCue::CueSetting VTTCue::settingName(VTTScanner& input)
{
    CueSetting parsedSetting = None;
    if (input.scan("vertical"))
        parsedSetting = Vertical;
    else if (input.scan("line"))
        parsedSetting = Line;
    else if (input.scan("position"))
        parsedSetting = Position;
    else if (input.scan("size"))
        parsedSetting = Size;
    else if (input.scan("align"))
        parsedSetting = Align;
    else if (input.scan("region"))
        parsedSetting = Region;

    // Verify that a ':' follows.
    if (parsedSetting != None && input.scan(':'))
        return parsedSetting;

    return None;
}

void VTTCue::setCueSettings(const String& inputString)
{
    if (inputString.isEmpty())
        return;

    VTTScanner input(inputString);

    while (!input.isAtEnd()) {

        // The WebVTT cue settings part of a WebVTT cue consists of zero or more of the following components, in any order, 
        // separated from each other by one or more U+0020 SPACE characters or U+0009 CHARACTER TABULATION (tab) characters.
        input.skipWhile<WebVTTParser::isValidSettingDelimiter>();
        if (input.isAtEnd())
            break;

        // When the user agent is to parse the WebVTT settings given by a string input for a text track cue cue, 
        // the user agent must run the following steps:
        // 1. Let settings be the result of splitting input on spaces.
        // 2. For each token setting in the list settings, run the following substeps:
        //    1. If setting does not contain a U+003A COLON character (:), or if the first U+003A COLON character (:) 
        //       in setting is either the first or last character of setting, then jump to the step labeled next setting.
        //    2. Let name be the leading substring of setting up to and excluding the first U+003A COLON character (:) in that string.
        CueSetting name = settingName(input);

        // 3. Let value be the trailing substring of setting starting from the character immediately after the first U+003A COLON character (:) in that string.
        VTTScanner::Run valueRun = input.collectUntil<WebVTTParser::isValidSettingDelimiter>();

        // 4. Run the appropriate substeps that apply for the value of name, as follows:
        switch (name) {
        case Vertical: {
            // If name is a case-sensitive match for "vertical"
            // 1. If value is a case-sensitive match for the string "rl", then let cue's text track cue writing direction 
            //    be vertical growing left.
            if (input.scanRun(valueRun, verticalGrowingLeftKeyword()))
                m_writingDirection = VerticalGrowingLeft;
            
            // 2. Otherwise, if value is a case-sensitive match for the string "lr", then let cue's text track cue writing 
            //    direction be vertical growing right.
            else if (input.scanRun(valueRun, verticalGrowingRightKeyword()))
                m_writingDirection = VerticalGrowingRight;

            else
                LOG(Media, "VTTCue::setCueSettings, invalid Vertical");
            break;
        }
        case Line: {
            bool isValid = false;
            do {
                // 1-2 - Collect chars that are either '-', '%', or a digit.
                // 1. If value contains any characters other than U+002D HYPHEN-MINUS characters (-), U+0025 PERCENT SIGN
                //    characters (%), and characters in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT NINE (9), then jump
                //    to the step labeled next setting.
                float linePosition;
                bool isNegative;
                if (!input.scanFloat(linePosition, &isNegative))
                    break;

                bool isPercentage = input.scan('%');
                if (!input.isAt(valueRun.end())) {
                    if (!input.scan(','))
                        break;
                    // FIXME: implement handling of line setting alignment.
                    if (!input.scan(startKeyword().characters8(), startKeyword().length())
                        && !input.scan(centerKeyword().characters8(), centerKeyword().length())
                        && !input.scan(endKeyword().characters8(), endKeyword().length())) {
                        LOG(Media, "VTTCue::setCueSettings, invalid line setting alignment");
                        break;
                    }
                }

                // 2. If value does not contain at least one character in the range U+0030 DIGIT ZERO (0) to U+0039 DIGIT
                //    NINE (9), then jump to the step labeled next setting.
                // 3. If any character in value other than the first character is a U+002D HYPHEN-MINUS character (-), then
                //    jump to the step labeled next setting.
                // 4. If any character in value other than the last character is a U+0025 PERCENT SIGN character (%), then
                //    jump to the step labeled next setting.
                // 5. If the first character in value is a U+002D HYPHEN-MINUS character (-) and the last character in value is a
                //    U+0025 PERCENT SIGN character (%), then jump to the step labeled next setting.
                if (isPercentage && isNegative)
                    break;

                // 6. Ignoring the trailing percent sign, if any, interpret value as a (potentially signed) integer, and
                //    let number be that number.
                // 7. If the last character in value is a U+0025 PERCENT SIGN character (%), but number is not in the range
                //    0 ≤ number ≤ 100, then jump to the step labeled next setting.
                // 8. Let cue's text track cue line position be number.
                // 9. If the last character in value is a U+0025 PERCENT SIGN character (%), then let cue's text track cue
                //    snap-to-lines flag be false. Otherwise, let it be true.
                if (isPercentage) {
                    if (linePosition < 0 || linePosition > 100)
                        break;

                    // 10 - If '%' then set snap-to-lines flag to false.
                    m_snapToLines = false;
                } else {
                    if (linePosition - static_cast<int>(linePosition))
                        break;

                    m_snapToLines = true;
                }
                
                m_linePosition = linePosition;
                isValid = true;
            } while (0);

            if (!isValid)
                LOG(Media, "VTTCue::setCueSettings, invalid Line");

            break;
        }
        case Position: {
            float position;
            if (WebVTTParser::parseFloatPercentageValue(input, position) && input.isAt(valueRun.end()))
                m_textPosition = position;
            else
                LOG(Media, "VTTCue::setCueSettings, invalid Position");
            break;
        }
        case Size: {
            float cueSize;
            if (WebVTTParser::parseFloatPercentageValue(input, cueSize) && input.isAt(valueRun.end()))
                m_cueSize = cueSize;
            else
                LOG(Media, "VTTCue::setCueSettings, invalid Size");
            break;
        }
        case Align: {
            // 1. If value is a case-sensitive match for the string "start", then let cue's text track cue alignment be start alignment.
            if (input.scanRun(valueRun, startKeyword()))
                m_cueAlignment = Start;

            // 2. If value is a case-sensitive match for the string "center", then let cue's text track cue alignment be center alignment.
            else if (input.scanRun(valueRun, centerKeyword()))
                m_cueAlignment = Center;

            // 3. If value is a case-sensitive match for the string "end", then let cue's text track cue alignment be end alignment.
            else if (input.scanRun(valueRun, endKeyword()))
                m_cueAlignment = End;

            // 4. If value is a case-sensitive match for the string "left", then let cue's text track cue alignment be left alignment.
            else if (input.scanRun(valueRun, leftKeyword()))
                m_cueAlignment = Left;

            // 5. If value is a case-sensitive match for the string "right", then let cue's text track cue alignment be right alignment.
            else if (input.scanRun(valueRun, rightKeyword()))
                m_cueAlignment = Right;

            else
                LOG(Media, "VTTCue::setCueSettings, invalid Align");

            break;
        }
        case Region: {
            m_parsedRegionId = input.extractString(valueRun);
            break;
        }
        case None:
            break;
        }

        // Make sure the entire run is consumed.
        input.skipRun(valueRun);
    }

}

CSSValueID VTTCue::getCSSAlignment() const
{
    return displayAlignmentMap[m_cueAlignment];
}

CSSValueID VTTCue::getCSSWritingDirection() const
{
    return m_displayDirection;
}

CSSValueID VTTCue::getCSSWritingMode() const
{
    return displayWritingModeMap[m_writingDirection];
}

int VTTCue::getCSSSize() const
{
    return m_displaySize;
}

std::pair<double, double> VTTCue::getCSSPosition() const
{
    if (!m_snapToLines)
        return getPositionCoordinates();

    return m_displayPosition;
}

bool VTTCue::cueContentsMatch(const TextTrackCue& otherTextTrackCue) const
{
    auto& other = downcast<VTTCue>(otherTextTrackCue);
    return TextTrackCue::cueContentsMatch(other)
        && text() == other.text()
        && cueSettings() == other.cueSettings()
        && position() == other.position()
        && line() == other.line()
        && size() == other.size()
        && align() == other.align();
}

void VTTCue::setFontSize(int fontSize, const IntSize&, bool important)
{
    if (fontSize == m_fontSize && important == m_fontSizeIsImportant)
        return;

    m_displayTreeShouldChange = true;
    m_fontSizeIsImportant = important;
    m_fontSize = fontSize;
}

void VTTCue::toJSON(JSON::Object& object) const
{
    TextTrackCue::toJSON(object);

    // FIXME: Seems dangerous to include this based on LOG_DISABLED. Can we just include it unconditionally?
#if !LOG_DISABLED
    object.setString("text"_s, text());
#endif

    object.setString("vertical"_s, vertical());
    object.setBoolean("snapToLines"_s, snapToLines());
    object.setDouble("line"_s, m_linePosition);
    if (textPositionIsAuto())
        object.setString("position"_s, "auto"_s);
    else
        object.setDouble("position"_s, m_textPosition);
    object.setInteger("size"_s, m_cueSize);
    object.setString("align"_s, align());
}

} // namespace WebCore

#endif
