/*
 * Copyright (C) 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
 * Copyright (C) 2012 Google 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.
 * 3.  Neither the name of Apple Inc. ("Apple") 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 APPLE AND ITS 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 APPLE OR ITS 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 "MediaControlElements.h"

#if ENABLE(VIDEO)

#include "DOMTokenList.h"
#include "ElementChildIterator.h"
#include "EventHandler.h"
#include "EventNames.h"
#include "Frame.h"
#include "GraphicsContext.h"
#include "HTMLHeadingElement.h"
#include "HTMLLIElement.h"
#include "HTMLUListElement.h"
#include "HTMLVideoElement.h"
#include "ImageBuffer.h"
#include "LocalizedStrings.h"
#include "Logging.h"
#include "MediaControls.h"
#include "MouseEvent.h"
#include "Page.h"
#include "PageGroup.h"
#include "RenderLayer.h"
#include "RenderMediaControlElements.h"
#include "RenderSlider.h"
#include "RenderTheme.h"
#include "RenderVideo.h"
#include "RenderView.h"
#include "Settings.h"
#include "ShadowRoot.h"
#include "TextTrackList.h"
#include "VTTRegionList.h"
#include <wtf/IsoMallocInlines.h>
#include <wtf/Language.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlPanelElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlPanelEnclosureElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlOverlayEnclosureElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlTimelineContainerElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlVolumeSliderContainerElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlStatusDisplayElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlPanelMuteButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlVolumeSliderMuteButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlPlayButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlOverlayPlayButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlSeekForwardButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlSeekBackButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlRewindButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlReturnToRealtimeButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlToggleClosedCaptionsButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlClosedCaptionsContainerElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlClosedCaptionsTrackListElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlTimelineElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlFullscreenButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlPanelVolumeSliderElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlFullscreenVolumeSliderElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlFullscreenVolumeMinButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlFullscreenVolumeMaxButtonElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlTimeRemainingDisplayElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlCurrentTimeDisplayElement);
WTF_MAKE_ISO_ALLOCATED_IMPL(MediaControlTextTrackContainerElement);

using namespace HTMLNames;

static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId();
static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId();

MediaControlPanelElement::MediaControlPanelElement(Document& document)
    : MediaControlDivElement(document, MediaControlsPanel)
    , m_canBeDragged(false)
    , m_isBeingDragged(false)
    , m_isDisplayed(false)
    , m_opaque(true)
    , m_transitionTimer(*this, &MediaControlPanelElement::transitionTimerFired)
{
    setPseudo(AtomicString("-webkit-media-controls-panel", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlPanelElement> MediaControlPanelElement::create(Document& document)
{
    return adoptRef(*new MediaControlPanelElement(document));
}

void MediaControlPanelElement::startDrag(const LayoutPoint& eventLocation)
{
    if (!m_canBeDragged)
        return;

    if (m_isBeingDragged)
        return;

    auto renderer = this->renderer();
    if (!renderer || !renderer->isBox())
        return;

    RefPtr<Frame> frame = document().frame();
    if (!frame)
        return;

    m_lastDragEventLocation = eventLocation;

    frame->eventHandler().setCapturingMouseEventsElement(this);

    m_isBeingDragged = true;
}

void MediaControlPanelElement::continueDrag(const LayoutPoint& eventLocation)
{
    if (!m_isBeingDragged)
        return;

    LayoutSize distanceDragged = eventLocation - m_lastDragEventLocation;
    m_cumulativeDragOffset.move(distanceDragged);
    m_lastDragEventLocation = eventLocation;
    setPosition(m_cumulativeDragOffset);
}

void MediaControlPanelElement::endDrag()
{
    if (!m_isBeingDragged)
        return;

    m_isBeingDragged = false;

    RefPtr<Frame> frame = document().frame();
    if (!frame)
        return;

    frame->eventHandler().setCapturingMouseEventsElement(nullptr);
}

void MediaControlPanelElement::startTimer()
{
    stopTimer();

    // The timer is required to set the property display:'none' on the panel,
    // such that captions are correctly displayed at the bottom of the video
    // at the end of the fadeout transition.
    Seconds duration = RenderTheme::singleton().mediaControlsFadeOutDuration();
    m_transitionTimer.startOneShot(duration);
}

void MediaControlPanelElement::stopTimer()
{
    if (m_transitionTimer.isActive())
        m_transitionTimer.stop();
}

void MediaControlPanelElement::transitionTimerFired()
{
    if (!m_opaque)
        hide();

    stopTimer();
}

void MediaControlPanelElement::setPosition(const LayoutPoint& position)
{
    double left = position.x();
    double top = position.y();

    // Set the left and top to control the panel's position; this depends on it being absolute positioned.
    // Set the margin to zero since the position passed in will already include the effect of the margin.
    setInlineStyleProperty(CSSPropertyLeft, left, CSSPrimitiveValue::CSS_PX);
    setInlineStyleProperty(CSSPropertyTop, top, CSSPrimitiveValue::CSS_PX);
    setInlineStyleProperty(CSSPropertyMarginLeft, 0.0, CSSPrimitiveValue::CSS_PX);
    setInlineStyleProperty(CSSPropertyMarginTop, 0.0, CSSPrimitiveValue::CSS_PX);

    classList().add("dragged");
}

void MediaControlPanelElement::resetPosition()
{
    removeInlineStyleProperty(CSSPropertyLeft);
    removeInlineStyleProperty(CSSPropertyTop);
    removeInlineStyleProperty(CSSPropertyMarginLeft);
    removeInlineStyleProperty(CSSPropertyMarginTop);

    classList().remove("dragged");

    m_cumulativeDragOffset.setX(0);
    m_cumulativeDragOffset.setY(0);
}

void MediaControlPanelElement::makeOpaque()
{
    if (m_opaque)
        return;

    double duration = RenderTheme::singleton().mediaControlsFadeInDuration();

    setInlineStyleProperty(CSSPropertyTransitionProperty, CSSPropertyOpacity);
    setInlineStyleProperty(CSSPropertyTransitionDuration, duration, CSSPrimitiveValue::CSS_S);
    setInlineStyleProperty(CSSPropertyOpacity, 1.0, CSSPrimitiveValue::CSS_NUMBER);

    m_opaque = true;

    if (m_isDisplayed)
        show();
}

void MediaControlPanelElement::makeTransparent()
{
    if (!m_opaque)
        return;

    Seconds duration = RenderTheme::singleton().mediaControlsFadeOutDuration();

    setInlineStyleProperty(CSSPropertyTransitionProperty, CSSPropertyOpacity);
    setInlineStyleProperty(CSSPropertyTransitionDuration, duration.value(), CSSPrimitiveValue::CSS_S);
    setInlineStyleProperty(CSSPropertyOpacity, 0.0, CSSPrimitiveValue::CSS_NUMBER);

    m_opaque = false;
    startTimer();
}

void MediaControlPanelElement::defaultEventHandler(Event& event)
{
    MediaControlDivElement::defaultEventHandler(event);

    if (is<MouseEvent>(event)) {
        LayoutPoint location = downcast<MouseEvent>(event).absoluteLocation();
        if (event.type() == eventNames().mousedownEvent && event.target() == this) {
            startDrag(location);
            event.setDefaultHandled();
        } else if (event.type() == eventNames().mousemoveEvent && m_isBeingDragged)
            continueDrag(location);
        else if (event.type() == eventNames().mouseupEvent && m_isBeingDragged) {
            continueDrag(location);
            endDrag();
            event.setDefaultHandled();
        }
    }
}

void MediaControlPanelElement::setCanBeDragged(bool canBeDragged)
{
    if (m_canBeDragged == canBeDragged)
        return;

    m_canBeDragged = canBeDragged;

    if (!canBeDragged)
        endDrag();
}

void MediaControlPanelElement::setIsDisplayed(bool isDisplayed)
{
    m_isDisplayed = isDisplayed;
}

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

MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(Document& document)
    // Mapping onto same MediaControlElementType as panel element, since it has similar properties.
    : MediaControlDivElement(document, MediaControlsPanel)
{
    setPseudo(AtomicString("-webkit-media-controls-enclosure", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(Document& document)
{
    return adoptRef(*new MediaControlPanelEnclosureElement(document));
}

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

MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(Document& document)
    // Mapping onto same MediaControlElementType as panel element, since it has similar properties.
    : MediaControlDivElement(document, MediaControlsPanel)
{
    setPseudo(AtomicString("-webkit-media-controls-overlay-enclosure", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(Document& document)
{
    return adoptRef(*new MediaControlOverlayEnclosureElement(document));
}

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

MediaControlTimelineContainerElement::MediaControlTimelineContainerElement(Document& document)
    : MediaControlDivElement(document, MediaTimelineContainer)
{
    setPseudo(AtomicString("-webkit-media-controls-timeline-container", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlTimelineContainerElement> MediaControlTimelineContainerElement::create(Document& document)
{
    Ref<MediaControlTimelineContainerElement> element = adoptRef(*new MediaControlTimelineContainerElement(document));
    element->hide();
    return element;
}

void MediaControlTimelineContainerElement::setTimeDisplaysHidden(bool hidden)
{
    for (auto& element : childrenOfType<Element>(*this)) {
        if (element.shadowPseudoId() != getMediaControlTimeRemainingDisplayElementShadowPseudoId()
            && element.shadowPseudoId() != getMediaControlCurrentTimeDisplayElementShadowPseudoId())
            continue;

        MediaControlTimeDisplayElement& timeDisplay = static_cast<MediaControlTimeDisplayElement&>(element);
        if (hidden)
            timeDisplay.hide();
        else
            timeDisplay.show();
    }
}

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

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

MediaControlVolumeSliderContainerElement::MediaControlVolumeSliderContainerElement(Document& document)
    : MediaControlDivElement(document, MediaVolumeSliderContainer)
{
    setPseudo(AtomicString("-webkit-media-controls-volume-slider-container", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlVolumeSliderContainerElement> MediaControlVolumeSliderContainerElement::create(Document& document)
{
    Ref<MediaControlVolumeSliderContainerElement> element = adoptRef(*new MediaControlVolumeSliderContainerElement(document));
    element->hide();
    return element;
}

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

void MediaControlVolumeSliderContainerElement::defaultEventHandler(Event& event)
{
    // Poor man's mouseleave event detection.

    if (!is<MouseEvent>(event) || event.type() != eventNames().mouseoutEvent)
        return;

    if (!is<Node>(downcast<MouseEvent>(event).relatedTarget()))
        return;

    if (containsIncludingShadowDOM(&downcast<Node>(*downcast<MouseEvent>(event).relatedTarget())))
        return;

    hide();
}

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

MediaControlStatusDisplayElement::MediaControlStatusDisplayElement(Document& document)
    : MediaControlDivElement(document, MediaStatusDisplay)
    , m_stateBeingDisplayed(Nothing)
{
    setPseudo(AtomicString("-webkit-media-controls-status-display", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlStatusDisplayElement> MediaControlStatusDisplayElement::create(Document& document)
{
    Ref<MediaControlStatusDisplayElement> element = adoptRef(*new MediaControlStatusDisplayElement(document));
    element->hide();
    return element;
}

void MediaControlStatusDisplayElement::update()
{
    // Get the new state that we'll have to display.
    StateBeingDisplayed newStateToDisplay = Nothing;

    if (mediaController()->readyState() <= MediaControllerInterface::HAVE_METADATA && mediaController()->hasCurrentSrc())
        newStateToDisplay = Loading;
    else if (mediaController()->isLiveStream())
        newStateToDisplay = LiveBroadcast;

    if (newStateToDisplay == m_stateBeingDisplayed)
        return;

    if (m_stateBeingDisplayed == Nothing)
        show();
    else if (newStateToDisplay == Nothing)
        hide();

    m_stateBeingDisplayed = newStateToDisplay;

    switch (m_stateBeingDisplayed) {
    case Nothing:
        setInnerText(emptyString());
        break;
    case Loading:
        setInnerText(mediaElementLoadingStateText());
        break;
    case LiveBroadcast:
        setInnerText(mediaElementLiveBroadcastStateText());
        break;
    }
}

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

MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(Document& document, MediaControls* controls)
    : MediaControlMuteButtonElement(document, MediaMuteButton)
    , m_controls(controls)
{
    setPseudo(AtomicString("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls)
{
    ASSERT(controls);

    Ref<MediaControlPanelMuteButtonElement> button = adoptRef(*new MediaControlPanelMuteButtonElement(document, controls));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

void MediaControlPanelMuteButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().mouseoverEvent)
        m_controls->showVolumeSlider();

    MediaControlMuteButtonElement::defaultEventHandler(event);
}

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

MediaControlVolumeSliderMuteButtonElement::MediaControlVolumeSliderMuteButtonElement(Document& document)
    : MediaControlMuteButtonElement(document, MediaMuteButton)
{
    setPseudo(AtomicString("-webkit-media-controls-volume-slider-mute-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlVolumeSliderMuteButtonElement> MediaControlVolumeSliderMuteButtonElement::create(Document& document)
{
    Ref<MediaControlVolumeSliderMuteButtonElement> button = adoptRef(*new MediaControlVolumeSliderMuteButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

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

MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document& document)
    : MediaControlInputElement(document, MediaPlayButton)
{
    setPseudo(AtomicString("-webkit-media-controls-play-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document& document)
{
    Ref<MediaControlPlayButtonElement> button = adoptRef(*new MediaControlPlayButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

void MediaControlPlayButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().clickEvent) {
        if (mediaController()->canPlay())
            mediaController()->play();
        else
            mediaController()->pause();
        updateDisplayType();
        event.setDefaultHandled();
    }
    HTMLInputElement::defaultEventHandler(event);
}

void MediaControlPlayButtonElement::updateDisplayType()
{
    setDisplayType(mediaController()->canPlay() ? MediaPlayButton : MediaPauseButton);
}

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

MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(Document& document)
    : MediaControlInputElement(document, MediaOverlayPlayButton)
{
    setPseudo(AtomicString("-webkit-media-controls-overlay-play-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document& document)
{
    Ref<MediaControlOverlayPlayButtonElement> button = adoptRef(*new MediaControlOverlayPlayButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

void MediaControlOverlayPlayButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().clickEvent && mediaController()->canPlay()) {
        mediaController()->play();
        updateDisplayType();
        event.setDefaultHandled();
    }
    HTMLInputElement::defaultEventHandler(event);
}

void MediaControlOverlayPlayButtonElement::updateDisplayType()
{
    if (mediaController()->canPlay()) {
        show();
    } else
        hide();
}

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

MediaControlSeekForwardButtonElement::MediaControlSeekForwardButtonElement(Document& document)
    : MediaControlSeekButtonElement(document, MediaSeekForwardButton)
{
    setPseudo(AtomicString("-webkit-media-controls-seek-forward-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlSeekForwardButtonElement> MediaControlSeekForwardButtonElement::create(Document& document)
{
    Ref<MediaControlSeekForwardButtonElement> button = adoptRef(*new MediaControlSeekForwardButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

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

MediaControlSeekBackButtonElement::MediaControlSeekBackButtonElement(Document& document)
    : MediaControlSeekButtonElement(document, MediaSeekBackButton)
{
    setPseudo(AtomicString("-webkit-media-controls-seek-back-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlSeekBackButtonElement> MediaControlSeekBackButtonElement::create(Document& document)
{
    Ref<MediaControlSeekBackButtonElement> button = adoptRef(*new MediaControlSeekBackButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

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

MediaControlRewindButtonElement::MediaControlRewindButtonElement(Document& document)
    : MediaControlInputElement(document, MediaRewindButton)
{
    setPseudo(AtomicString("-webkit-media-controls-rewind-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlRewindButtonElement> MediaControlRewindButtonElement::create(Document& document)
{
    Ref<MediaControlRewindButtonElement> button = adoptRef(*new MediaControlRewindButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

void MediaControlRewindButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().clickEvent) {
        mediaController()->setCurrentTime(std::max<double>(0, mediaController()->currentTime() - 30));
        event.setDefaultHandled();
    }
    HTMLInputElement::defaultEventHandler(event);
}

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

MediaControlReturnToRealtimeButtonElement::MediaControlReturnToRealtimeButtonElement(Document& document)
    : MediaControlInputElement(document, MediaReturnToRealtimeButton)
{
    setPseudo(AtomicString("-webkit-media-controls-return-to-realtime-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlReturnToRealtimeButtonElement> MediaControlReturnToRealtimeButtonElement::create(Document& document)
{
    Ref<MediaControlReturnToRealtimeButtonElement> button = adoptRef(*new MediaControlReturnToRealtimeButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    button->hide();
    return button;
}

void MediaControlReturnToRealtimeButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().clickEvent) {
        mediaController()->returnToRealtime();
        event.setDefaultHandled();
    }
    HTMLInputElement::defaultEventHandler(event);
}

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

MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document& document, MediaControls* controls)
    : MediaControlInputElement(document, MediaShowClosedCaptionsButton)
#if PLATFORM(COCOA) || PLATFORM(WIN) || PLATFORM(GTK)
    , m_controls(controls)
#endif
{
#if !PLATFORM(COCOA) && !PLATFORM(WIN) || !PLATFORM(GTK)
    UNUSED_PARAM(controls);
#endif
    setPseudo(AtomicString("-webkit-media-controls-toggle-closed-captions-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls)
{
    ASSERT(controls);

    Ref<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(*new MediaControlToggleClosedCaptionsButtonElement(document, controls));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    button->hide();
    return button;
}

void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
{
    bool captionsVisible = mediaController()->closedCaptionsVisible();
    setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
    setChecked(captionsVisible);
}

void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().clickEvent) {
        // FIXME: It's not great that the shared code is dictating behavior of platform-specific
        // UI. Not all ports may want the closed captions button to toggle a list of tracks, so
        // we have to use #if.
        // https://bugs.webkit.org/show_bug.cgi?id=101877
#if !PLATFORM(COCOA) && !PLATFORM(WIN) && !PLATFORM(GTK)
        mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible());
        setChecked(mediaController()->closedCaptionsVisible());
        updateDisplayType();
#else
        m_controls->toggleClosedCaptionTrackList();
#endif
        event.setDefaultHandled();
    }

    HTMLInputElement::defaultEventHandler(event);
}

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

MediaControlClosedCaptionsContainerElement::MediaControlClosedCaptionsContainerElement(Document& document)
    : MediaControlDivElement(document, MediaClosedCaptionsContainer)
{
    setPseudo(AtomicString("-webkit-media-controls-closed-captions-container", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlClosedCaptionsContainerElement> MediaControlClosedCaptionsContainerElement::create(Document& document)
{
    Ref<MediaControlClosedCaptionsContainerElement> element = adoptRef(*new MediaControlClosedCaptionsContainerElement(document));
    element->setAttributeWithoutSynchronization(dirAttr, AtomicString("auto", AtomicString::ConstructFromLiteral));
    element->hide();
    return element;
}

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

MediaControlClosedCaptionsTrackListElement::MediaControlClosedCaptionsTrackListElement(Document& document, MediaControls* controls)
    : MediaControlDivElement(document, MediaClosedCaptionsTrackList)
#if ENABLE(VIDEO_TRACK)
    , m_controls(controls)
#endif
{
#if !ENABLE(VIDEO_TRACK)
    UNUSED_PARAM(controls);
#endif
    setPseudo(AtomicString("-webkit-media-controls-closed-captions-track-list", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlClosedCaptionsTrackListElement> MediaControlClosedCaptionsTrackListElement::create(Document& document, MediaControls* controls)
{
    ASSERT(controls);
    Ref<MediaControlClosedCaptionsTrackListElement> element = adoptRef(*new MediaControlClosedCaptionsTrackListElement(document, controls));
    return element;
}

void MediaControlClosedCaptionsTrackListElement::defaultEventHandler(Event& event)
{
#if ENABLE(VIDEO_TRACK)
    if (event.type() == eventNames().clickEvent) {
        if (!is<Element>(event.target()))
            return;

        // When we created the elements in the track list, we gave them a custom
        // attribute representing the index in the HTMLMediaElement's list of tracks.
        // Check if the event target has such a custom element and, if so,
        // tell the HTMLMediaElement to enable that track.

        auto textTrack = makeRefPtr(m_menuToTrackMap.get(&downcast<Element>(*event.target())));
        m_menuToTrackMap.clear();
        m_controls->toggleClosedCaptionTrackList();
        if (!textTrack)
            return;

        auto mediaElement = parentMediaElement(this);
        if (!mediaElement)
            return;

        mediaElement->setSelectedTextTrack(textTrack.get());

        updateDisplay();
    }

    MediaControlDivElement::defaultEventHandler(event);
#else
    UNUSED_PARAM(event);
#endif
}

void MediaControlClosedCaptionsTrackListElement::updateDisplay()
{
#if ENABLE(VIDEO_TRACK)
    static NeverDestroyed<AtomicString> selectedClassValue("selected", AtomicString::ConstructFromLiteral);

    if (!mediaController()->hasClosedCaptions())
        return;

    if (!document().page())
        return;
    CaptionUserPreferences::CaptionDisplayMode displayMode = document().page()->group().captionPreferences().captionDisplayMode();

    auto mediaElement = parentMediaElement(this);
    if (!mediaElement)
        return;

    if (!mediaElement->textTracks().length())
        return;

    rebuildTrackListMenu();

    RefPtr<Element> offMenuItem;
    bool trackMenuItemSelected = false;

    for (auto& trackItem : m_menuItems) {
        RefPtr<TextTrack> textTrack;
        MenuItemToTrackMap::iterator iter = m_menuToTrackMap.find(trackItem.get());
        if (iter == m_menuToTrackMap.end())
            continue;
        textTrack = iter->value;
        if (!textTrack)
            continue;

        if (textTrack == TextTrack::captionMenuOffItem()) {
            offMenuItem = trackItem;
            continue;
        }

        if (textTrack == TextTrack::captionMenuAutomaticItem()) {
            if (displayMode == CaptionUserPreferences::Automatic)
                trackItem->classList().add(selectedClassValue);
            else
                trackItem->classList().remove(selectedClassValue);
            continue;
        }

        if (displayMode != CaptionUserPreferences::Automatic && textTrack->mode() == TextTrack::Mode::Showing) {
            trackMenuItemSelected = true;
            trackItem->classList().add(selectedClassValue);
        } else
            trackItem->classList().remove(selectedClassValue);
    }

    if (offMenuItem) {
        if (displayMode == CaptionUserPreferences::ForcedOnly && !trackMenuItemSelected)
            offMenuItem->classList().add(selectedClassValue);
        else
            offMenuItem->classList().remove(selectedClassValue);
    }
#endif
}

void MediaControlClosedCaptionsTrackListElement::rebuildTrackListMenu()
{
#if ENABLE(VIDEO_TRACK)
    // Remove any existing content.
    removeChildren();
    m_menuItems.clear();
    m_menuToTrackMap.clear();

    if (!mediaController()->hasClosedCaptions())
        return;

    auto mediaElement = parentMediaElement(this);
    if (!mediaElement)
        return;

    TextTrackList& trackList = mediaElement->textTracks();
    if (!trackList.length())
        return;

    if (!document().page())
        return;
    auto& captionPreferences = document().page()->group().captionPreferences();
    Vector<RefPtr<TextTrack>> tracksForMenu = captionPreferences.sortedTrackListForMenu(&trackList);

    auto captionsHeader = HTMLHeadingElement::create(h3Tag, document());
    captionsHeader->appendChild(document().createTextNode(textTrackSubtitlesText()));
    appendChild(captionsHeader);
    auto captionsMenuList = HTMLUListElement::create(document());

    for (auto& textTrack : tracksForMenu) {
        auto menuItem = HTMLLIElement::create(document());
        menuItem->appendChild(document().createTextNode(captionPreferences.displayNameForTrack(textTrack.get())));
        captionsMenuList->appendChild(menuItem);
        m_menuItems.append(menuItem.ptr());
        m_menuToTrackMap.add(menuItem.ptr(), textTrack);
    }

    appendChild(captionsMenuList);
#endif
}

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

MediaControlTimelineElement::MediaControlTimelineElement(Document& document, MediaControls* controls)
    : MediaControlInputElement(document, MediaSlider)
    , m_controls(controls)
{
    setPseudo(AtomicString("-webkit-media-controls-timeline", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlTimelineElement> MediaControlTimelineElement::create(Document& document, MediaControls* controls)
{
    ASSERT(controls);

    Ref<MediaControlTimelineElement> timeline = adoptRef(*new MediaControlTimelineElement(document, controls));
    timeline->ensureUserAgentShadowRoot();
    timeline->setType("range");
    timeline->setAttributeWithoutSynchronization(precisionAttr, AtomicString("float", AtomicString::ConstructFromLiteral));
    return timeline;
}

void MediaControlTimelineElement::defaultEventHandler(Event& event)
{
    // Left button is 0. Rejects mouse events not from left button.
    if (is<MouseEvent>(event) && downcast<MouseEvent>(event).button())
        return;

    if (!renderer())
        return;

    if (event.type() == eventNames().mousedownEvent)
        mediaController()->beginScrubbing();

    if (event.type() == eventNames().mouseupEvent)
        mediaController()->endScrubbing();

    MediaControlInputElement::defaultEventHandler(event);

    if (event.type() == eventNames().mouseoverEvent || event.type() == eventNames().mouseoutEvent || event.type() == eventNames().mousemoveEvent)
        return;

    double time = value().toDouble();
    if ((event.isInputEvent() || event.type() == eventNames().inputEvent) && time != mediaController()->currentTime())
        mediaController()->setCurrentTime(time);

    RenderSlider& slider = downcast<RenderSlider>(*renderer());
    if (slider.inDragMode())
        m_controls->updateCurrentTimeDisplay();
}

#if !PLATFORM(IOS)
bool MediaControlTimelineElement::willRespondToMouseClickEvents()
{
    if (!renderer())
        return false;

    return true;
}
#endif // !PLATFORM(IOS)

void MediaControlTimelineElement::setPosition(double currentTime)
{
    setValue(String::numberToStringECMAScript(currentTime));
}

void MediaControlTimelineElement::setDuration(double duration)
{
    setAttribute(maxAttr, AtomicString::number(duration));
}

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

MediaControlPanelVolumeSliderElement::MediaControlPanelVolumeSliderElement(Document& document)
    : MediaControlVolumeSliderElement(document)
{
    setPseudo(AtomicString("-webkit-media-controls-volume-slider", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document& document)
{
    Ref<MediaControlPanelVolumeSliderElement> slider = adoptRef(*new MediaControlPanelVolumeSliderElement(document));
    slider->ensureUserAgentShadowRoot();
    slider->setType("range");
    slider->setAttributeWithoutSynchronization(precisionAttr, AtomicString("float", AtomicString::ConstructFromLiteral));
    slider->setAttributeWithoutSynchronization(maxAttr, AtomicString("1", AtomicString::ConstructFromLiteral));
    return slider;
}

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

MediaControlFullscreenVolumeSliderElement::MediaControlFullscreenVolumeSliderElement(Document& document)
    : MediaControlVolumeSliderElement(document)
{
    setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-slider", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlFullscreenVolumeSliderElement> MediaControlFullscreenVolumeSliderElement::create(Document& document)
{
    Ref<MediaControlFullscreenVolumeSliderElement> slider = adoptRef(*new MediaControlFullscreenVolumeSliderElement(document));
    slider->ensureUserAgentShadowRoot();
    slider->setType("range");
    slider->setAttributeWithoutSynchronization(precisionAttr, AtomicString("float", AtomicString::ConstructFromLiteral));
    slider->setAttributeWithoutSynchronization(maxAttr, AtomicString("1", AtomicString::ConstructFromLiteral));
    return slider;
}

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

MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document& document)
    : MediaControlInputElement(document, MediaEnterFullscreenButton)
{
    setPseudo(AtomicString("-webkit-media-controls-fullscreen-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document& document)
{
    Ref<MediaControlFullscreenButtonElement> button = adoptRef(*new MediaControlFullscreenButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    button->hide();
    return button;
}

void MediaControlFullscreenButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().clickEvent) {
#if ENABLE(FULLSCREEN_API)
        // Only use the new full screen API if the fullScreenEnabled setting has
        // been explicitly enabled. Otherwise, use the old fullscreen API. This
        // allows apps which embed a WebView to retain the existing full screen
        // video implementation without requiring them to implement their own full
        // screen behavior.
        if (document().settings().fullScreenEnabled()) {
            if (document().webkitIsFullScreen() && document().webkitCurrentFullScreenElement() == parentMediaElement(this))
                document().webkitCancelFullScreen();
            else
                document().requestFullScreenForElement(parentMediaElement(this).get(), Document::ExemptIFrameAllowFullScreenRequirement);
        } else
#endif
            mediaController()->enterFullscreen();
        event.setDefaultHandled();
    }
    HTMLInputElement::defaultEventHandler(event);
}

void MediaControlFullscreenButtonElement::setIsFullscreen(bool isFullscreen)
{
    setDisplayType(isFullscreen ? MediaExitFullscreenButton : MediaEnterFullscreenButton);
}

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

MediaControlFullscreenVolumeMinButtonElement::MediaControlFullscreenVolumeMinButtonElement(Document& document)
    : MediaControlInputElement(document, MediaUnMuteButton)
{
    setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-min-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlFullscreenVolumeMinButtonElement> MediaControlFullscreenVolumeMinButtonElement::create(Document& document)
{
    Ref<MediaControlFullscreenVolumeMinButtonElement> button = adoptRef(*new MediaControlFullscreenVolumeMinButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

void MediaControlFullscreenVolumeMinButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().clickEvent) {
        mediaController()->setVolume(0);
        event.setDefaultHandled();
    }
    HTMLInputElement::defaultEventHandler(event);
}

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

MediaControlFullscreenVolumeMaxButtonElement::MediaControlFullscreenVolumeMaxButtonElement(Document& document)
: MediaControlInputElement(document, MediaMuteButton)
{
    setPseudo(AtomicString("-webkit-media-controls-fullscreen-volume-max-button", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlFullscreenVolumeMaxButtonElement> MediaControlFullscreenVolumeMaxButtonElement::create(Document& document)
{
    Ref<MediaControlFullscreenVolumeMaxButtonElement> button = adoptRef(*new MediaControlFullscreenVolumeMaxButtonElement(document));
    button->ensureUserAgentShadowRoot();
    button->setType("button");
    return button;
}

void MediaControlFullscreenVolumeMaxButtonElement::defaultEventHandler(Event& event)
{
    if (event.type() == eventNames().clickEvent) {
        mediaController()->setVolume(1);
        event.setDefaultHandled();
    }
    HTMLInputElement::defaultEventHandler(event);
}

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

MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(Document& document)
    : MediaControlTimeDisplayElement(document, MediaTimeRemainingDisplay)
{
    setPseudo(getMediaControlTimeRemainingDisplayElementShadowPseudoId());
}

Ref<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(Document& document)
{
    return adoptRef(*new MediaControlTimeRemainingDisplayElement(document));
}

static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId()
{
    static NeverDestroyed<AtomicString> id("-webkit-media-controls-time-remaining-display", AtomicString::ConstructFromLiteral);
    return id;
}

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

MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(Document& document)
    : MediaControlTimeDisplayElement(document, MediaCurrentTimeDisplay)
{
    setPseudo(getMediaControlCurrentTimeDisplayElementShadowPseudoId());
}

Ref<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(Document& document)
{
    return adoptRef(*new MediaControlCurrentTimeDisplayElement(document));
}

static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId()
{
    static NeverDestroyed<AtomicString> id("-webkit-media-controls-current-time-display", AtomicString::ConstructFromLiteral);
    return id;
}

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

#if ENABLE(VIDEO_TRACK)

MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(Document& document)
    : MediaControlDivElement(document, MediaTextTrackDisplayContainer)
    , m_updateTimer(*this, &MediaControlTextTrackContainerElement::updateTimerFired)
    , m_fontSize(0)
    , m_fontSizeIsImportant(false)
    , m_updateTextTrackRepresentationStyle(false)
{
    setPseudo(AtomicString("-webkit-media-text-track-container", AtomicString::ConstructFromLiteral));
}

Ref<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(Document& document)
{
    auto element = adoptRef(*new MediaControlTextTrackContainerElement(document));
    element->hide();
    return element;
}

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

static bool compareCueIntervalForDisplay(const CueInterval& one, const CueInterval& two)
{
    return one.data()->isPositionedAbove(two.data());
};

void MediaControlTextTrackContainerElement::updateDisplay()
{
    if (!mediaController()->closedCaptionsVisible())
        removeChildren();

    auto mediaElement = parentMediaElement(this);
    // 1. If the media element is an audio element, or is another playback
    // mechanism with no rendering area, abort these steps. There is nothing to
    // render.
    if (!mediaElement || !mediaElement->isVideo())
        return;

    // 2. Let video be the media element or other playback mechanism.
    HTMLVideoElement& video = downcast<HTMLVideoElement>(*mediaElement);

    // 3. Let output be an empty list of absolutely positioned CSS block boxes.
    Vector<RefPtr<HTMLDivElement>> output;

    // 4. If the user agent is exposing a user interface for video, add to
    // output one or more completely transparent positioned CSS block boxes that
    // cover the same region as the user interface.

    // 5. If the last time these rules were run, the user agent was not exposing
    // a user interface for video, but now it is, let reset be true. Otherwise,
    // let reset be false.

    // There is nothing to be done explicitly for 4th and 5th steps, as
    // everything is handled through CSS. The caption box is on top of the
    // controls box, in a container set with the -webkit-box display property.

    // 6. Let tracks be the subset of video's list of text tracks that have as
    // their rules for updating the text track rendering these rules for
    // updating the display of WebVTT text tracks, and whose text track mode is
    // showing or showing by default.
    // 7. Let cues be an empty list of text track cues.
    // 8. For each track track in tracks, append to cues all the cues from
    // track's list of cues that have their text track cue active flag set.
    CueList activeCues = video.currentlyActiveCues();

    // 9. If reset is false, then, for each text track cue cue in cues: if cue's
    // text track cue display state has a set of CSS boxes, then add those boxes
    // to output, and remove cue from cues.

    // There is nothing explicitly to be done here, as all the caching occurs
    // within the TextTrackCue instance itself. If parameters of the cue change,
    // the display tree is cleared.

    // If the number of CSS boxes in the output is less than the number of cues
    // we wish to render (e.g., we are adding another cue in a set of roll-up
    // cues), remove all the existing CSS boxes representing the cues and re-add
    // them so that the new cue is at the bottom.
    // FIXME: Calling countChildNodes() here is inefficient. We don't need to
    // traverse all children just to check if there are less children than cues.
    if (countChildNodes() < activeCues.size())
        removeChildren();

    // Sort the active cues for the appropriate display order. For example, for roll-up
    // or paint-on captions, we need to add the cues in reverse chronological order,
    // so that the newest captions appear at the bottom.
    std::sort(activeCues.begin(), activeCues.end(), &compareCueIntervalForDisplay);

    // 10. For each text track cue cue in cues that has not yet had
    // corresponding CSS boxes added to output, in text track cue order, run the
    // following substeps:
    for (size_t i = 0; i < activeCues.size(); ++i) {
        if (!mediaController()->closedCaptionsVisible())
            continue;

        RefPtr<TextTrackCue> textTrackCue = activeCues[i].data();
        if (!textTrackCue->isRenderable())
            continue;

        RefPtr<VTTCue> cue = toVTTCue(textTrackCue.get());

        ASSERT(cue->isActive());
        if (!cue->track() || !cue->track()->isRendered() || !cue->isActive() || cue->text().isEmpty())
            continue;

        LOG(Media, "MediaControlTextTrackContainerElement::updateDisplay(%p) - adding and positioning cue #%zu: \"%s\", start=%.2f, end=%.2f, line=%.2f", this, i, cue->text().utf8().data(), cue->startTime(), cue->endTime(), cue->line());

        Ref<VTTCueBox> displayBox = cue->getDisplayTree(m_videoDisplaySize.size(), m_fontSize);
        if (cue->track()->mode() == TextTrack::Mode::Disabled)
            continue;

        RefPtr<VTTRegion> region = cue->track()->regions()->getRegionById(cue->regionId());
        if (!region) {
            // If cue has an empty text track cue region identifier or there is no
            // WebVTT region whose region identifier is identical to cue's text
            // track cue region identifier, run the following substeps:
            if (displayBox->hasChildNodes() && !contains(displayBox.ptr())) {
                // Note: the display tree of a cue is removed when the active flag of the cue is unset.
                appendChild(displayBox);
                cue->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant);
            }
        } else {
            // Let region be the WebVTT region whose region identifier
            // matches the text track cue region identifier of cue.
            Ref<HTMLDivElement> regionNode = region->getDisplayTree();

            // Append the region to the viewport, if it was not already.
            if (!contains(regionNode.ptr()))
                appendChild(region->getDisplayTree());

            region->appendTextTrackCueBox(WTFMove(displayBox));
        }
    }

    // 11. Return output.
    if (hasChildNodes()) {
        show();
        updateTextTrackRepresentation();
    } else {
        hide();
        clearTextTrackRepresentation();
    }
}

void MediaControlTextTrackContainerElement::updateActiveCuesFontSize()
{
    if (!document().page())
        return;

    auto mediaElement = parentMediaElement(this);
    if (!mediaElement)
        return;

    float smallestDimension = std::min(m_videoDisplaySize.size().height(), m_videoDisplaySize.size().width());
    float fontScale = document().page()->group().captionPreferences().captionFontSizeScaleAndImportance(m_fontSizeIsImportant);
    m_fontSize = lroundf(smallestDimension * fontScale);

    for (auto& activeCue : mediaElement->currentlyActiveCues()) {
        RefPtr<TextTrackCue> cue = activeCue.data();
        if (!cue->isRenderable())
            continue;

        toVTTCue(cue.get())->setFontSize(m_fontSize, m_videoDisplaySize.size(), m_fontSizeIsImportant);
    }

}

void MediaControlTextTrackContainerElement::updateTextStrokeStyle()
{
    if (!document().page())
        return;

    auto mediaElement = parentMediaElement(this);
    if (!mediaElement)
        return;
    
    String language;

    // FIXME: Since it is possible to have more than one text track enabled, the following code may not find the correct language.
    // The default UI only allows a user to enable one track at a time, so it should be OK for now, but we should consider doing
    // this differently, see <https://bugs.webkit.org/show_bug.cgi?id=169875>.
    auto& tracks = mediaElement->textTracks();
    for (unsigned i = 0; i < tracks.length(); ++i) {
        auto track = tracks.item(i);
        if (track && track->mode() == TextTrack::Mode::Showing) {
            language = track->validBCP47Language();
            break;
        }
    }

    float strokeWidth;
    bool important;

    // FIXME: find a way to set this property in the stylesheet like the other user style preferences, see <https://bugs.webkit.org/show_bug.cgi?id=169874>.
    if (document().page()->group().captionPreferences().captionStrokeWidthForFont(m_fontSize, language, strokeWidth, important))
        setInlineStyleProperty(CSSPropertyStrokeWidth, strokeWidth, CSSPrimitiveValue::CSS_PX, important);
}

void MediaControlTextTrackContainerElement::updateTimerFired()
{
    if (!document().page())
        return;

    if (m_textTrackRepresentation)
        updateStyleForTextTrackRepresentation();

    updateActiveCuesFontSize();
    updateDisplay();
    updateTextStrokeStyle();
}

void MediaControlTextTrackContainerElement::updateTextTrackRepresentation()
{
    auto mediaElement = parentMediaElement(this);
    if (!mediaElement)
        return;

    if (!mediaElement->requiresTextTrackRepresentation()) {
        if (m_textTrackRepresentation) {
            clearTextTrackRepresentation();
            updateSizes(true);
        }
        return;
    }

    if (!m_textTrackRepresentation) {
        m_textTrackRepresentation = TextTrackRepresentation::create(*this);
        if (document().page())
            m_textTrackRepresentation->setContentScale(document().page()->deviceScaleFactor());
        m_updateTextTrackRepresentationStyle = true;
        mediaElement->setTextTrackRepresentation(m_textTrackRepresentation.get());
    }

    m_textTrackRepresentation->update();
    updateStyleForTextTrackRepresentation();
}

void MediaControlTextTrackContainerElement::clearTextTrackRepresentation()
{
    if (!m_textTrackRepresentation)
        return;

    m_textTrackRepresentation = nullptr;
    m_updateTextTrackRepresentationStyle = true;
    if (auto mediaElement = parentMediaElement(this))
        mediaElement->setTextTrackRepresentation(nullptr);
    updateStyleForTextTrackRepresentation();
    updateActiveCuesFontSize();
}

void MediaControlTextTrackContainerElement::updateStyleForTextTrackRepresentation()
{
    if (!m_updateTextTrackRepresentationStyle)
        return;
    m_updateTextTrackRepresentationStyle = false;

    if (m_textTrackRepresentation) {
        setInlineStyleProperty(CSSPropertyWidth, m_videoDisplaySize.size().width(), CSSPrimitiveValue::CSS_PX);
        setInlineStyleProperty(CSSPropertyHeight, m_videoDisplaySize.size().height(), CSSPrimitiveValue::CSS_PX);
        setInlineStyleProperty(CSSPropertyPosition, CSSValueAbsolute);
        setInlineStyleProperty(CSSPropertyLeft, 0, CSSPrimitiveValue::CSS_PX);
        setInlineStyleProperty(CSSPropertyTop, 0, CSSPrimitiveValue::CSS_PX);
        return;
    }

    removeInlineStyleProperty(CSSPropertyPosition);
    removeInlineStyleProperty(CSSPropertyWidth);
    removeInlineStyleProperty(CSSPropertyHeight);
    removeInlineStyleProperty(CSSPropertyLeft);
    removeInlineStyleProperty(CSSPropertyTop);
}

void MediaControlTextTrackContainerElement::enteredFullscreen()
{
    if (hasChildNodes())
        updateTextTrackRepresentation();
    updateSizes(true);
}

void MediaControlTextTrackContainerElement::exitedFullscreen()
{
    clearTextTrackRepresentation();
    updateSizes(true);
}

void MediaControlTextTrackContainerElement::updateSizes(bool forceUpdate)
{
    auto mediaElement = parentMediaElement(this);
    if (!mediaElement)
        return;

    if (!document().page())
        return;

    mediaElement->syncTextTrackBounds();

    IntRect videoBox;
    if (m_textTrackRepresentation) {
        videoBox = m_textTrackRepresentation->bounds();
        float deviceScaleFactor = document().page()->deviceScaleFactor();
        videoBox.setWidth(videoBox.width() * deviceScaleFactor);
        videoBox.setHeight(videoBox.height() * deviceScaleFactor);
    } else {
        if (!is<RenderVideo>(mediaElement->renderer()))
            return;
        videoBox = downcast<RenderVideo>(*mediaElement->renderer()).videoBox();
    }

    if (!forceUpdate && m_videoDisplaySize == videoBox)
        return;

    m_videoDisplaySize = videoBox;
    m_updateTextTrackRepresentationStyle = true;

    // FIXME (121170): This function is called during layout, and should lay out the text tracks immediately.
    m_updateTimer.startOneShot(0_s);
}

RefPtr<Image> MediaControlTextTrackContainerElement::createTextTrackRepresentationImage()
{
    if (!hasChildNodes())
        return nullptr;

    RefPtr<Frame> frame = document().frame();
    if (!frame)
        return nullptr;

    document().updateLayout();

    auto* renderer = this->renderer();
    if (!renderer)
        return nullptr;

    if (!renderer->hasLayer())
        return nullptr;

    RenderLayer* layer = downcast<RenderLayerModelObject>(*renderer).layer();

    float deviceScaleFactor = 1;
    if (Page* page = document().page())
        deviceScaleFactor = page->deviceScaleFactor();

    IntRect paintingRect = IntRect(IntPoint(), layer->size());

    // FIXME (149422): This buffer should not be unconditionally unaccelerated.
    std::unique_ptr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), Unaccelerated, deviceScaleFactor));
    if (!buffer)
        return nullptr;

    layer->paint(buffer->context(), paintingRect, LayoutSize(), PaintBehaviorFlattenCompositingLayers | PaintBehaviorSnapshotting, nullptr, RenderLayer::PaintLayerPaintingCompositingAllPhases);

    return ImageBuffer::sinkIntoImage(WTFMove(buffer));
}

void MediaControlTextTrackContainerElement::textTrackRepresentationBoundsChanged(const IntRect&)
{
    if (hasChildNodes())
        updateTextTrackRepresentation();
    updateSizes();
}

#endif // ENABLE(VIDEO_TRACK)

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

} // namespace WebCore

#endif // ENABLE(VIDEO)
