/*
 * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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.
 */

#pragma once

#if PLATFORM(IOS_FAMILY)

#include "RenderThemeCocoa.h"

#if USE(SYSTEM_PREVIEW)
#if HAVE(IOSURFACE)
#include "IOSurface.h"
#endif
#include <wtf/RetainPtr.h>
#endif

OBJC_CLASS CIContext;

namespace WebCore {
    
class RenderStyle;
class GraphicsContext;

struct AttachmentLayout;

class RenderThemeIOS final : public RenderThemeCocoa {
public:
    friend NeverDestroyed<RenderThemeIOS>;

    static void adjustRoundBorderRadius(RenderStyle&, RenderBox&);

    static CFStringRef contentSizeCategory();

    WEBCORE_EXPORT static void setContentSizeCategory(const String&);

#if USE(SYSTEM_PREVIEW)
    void paintSystemPreviewBadge(Image&, const PaintInfo&, const FloatRect&) override;
#endif

protected:
    LengthBox popupInternalPaddingBox(const RenderStyle&) const override;
    
    FontCascadeDescription& cachedSystemFontDescription(CSSValueID systemFontID) const override;
    void updateCachedSystemFontDescription(CSSValueID, FontCascadeDescription&) const override;
    int baselinePosition(const RenderBox&) const override;

    bool isControlStyled(const RenderStyle&, const RenderStyle& userAgentStyle) const override;

    // Methods for each appearance value.
    void adjustCheckboxStyle(StyleResolver&, RenderStyle&, const Element*) const override;
    bool paintCheckboxDecorations(const RenderObject&, const PaintInfo&, const IntRect&) override;

    void adjustRadioStyle(StyleResolver&, RenderStyle&, const Element*) const override;
    bool paintRadioDecorations(const RenderObject&, const PaintInfo&, const IntRect&) override;

    void adjustButtonStyle(StyleResolver&, RenderStyle&, const Element*) const override;
    bool paintButtonDecorations(const RenderObject&, const PaintInfo&, const IntRect&) override;
    bool paintPushButtonDecorations(const RenderObject&, const PaintInfo&, const IntRect&) override;
    void setButtonSize(RenderStyle&) const override;

    bool paintFileUploadIconDecorations(const RenderObject& inputRenderer, const RenderObject& buttonRenderer, const PaintInfo&, const IntRect&, Icon*, FileUploadDecorations) override;

    bool paintTextFieldDecorations(const RenderObject&, const PaintInfo&, const FloatRect&) override;
    bool paintTextAreaDecorations(const RenderObject&, const PaintInfo&, const FloatRect&) override;

    void adjustMenuListButtonStyle(StyleResolver&, RenderStyle&, const Element*) const override;
    bool paintMenuListButtonDecorations(const RenderBox&, const PaintInfo&, const FloatRect&) override;

    void adjustSliderTrackStyle(StyleResolver&, RenderStyle&, const Element*) const override;
    bool paintSliderTrack(const RenderObject&, const PaintInfo&, const IntRect&) override;

    void adjustSliderThumbSize(RenderStyle&, const Element*) const override;
    bool paintSliderThumbDecorations(const RenderObject&, const PaintInfo&, const IntRect&) override;

    // Returns the repeat interval of the animation for the progress bar.
    Seconds animationRepeatIntervalForProgressBar(RenderProgress&) const override;
    // Returns the duration of the animation for the progress bar.
    Seconds animationDurationForProgressBar(RenderProgress&) const override;

    bool paintProgressBar(const RenderObject&, const PaintInfo&, const IntRect&) override;

#if ENABLE(DATALIST_ELEMENT)
    IntSize sliderTickSize() const override;
    int sliderTickOffsetFromTrackCenter() const override;
#endif

    void adjustSearchFieldStyle(StyleResolver&, RenderStyle&, const Element*) const override;
    bool paintSearchFieldDecorations(const RenderObject&, const PaintInfo&, const IntRect&) override;

    bool supportsFocusRing(const RenderStyle&) const final;

    Color platformActiveSelectionBackgroundColor(OptionSet<StyleColor::Options>) const override;
    Color platformInactiveSelectionBackgroundColor(OptionSet<StyleColor::Options>) const override;
#if ENABLE(FULL_KEYBOARD_ACCESS)
    Color platformFocusRingColor(OptionSet<StyleColor::Options>) const final;
#endif

#if ENABLE(TOUCH_EVENTS)
    Color platformTapHighlightColor() const override { return 0x4D1A1A1A; }
#endif

    bool shouldHaveSpinButton(const HTMLInputElement&) const override;

#if ENABLE(VIDEO)
    String mediaControlsStyleSheet() override;
    String modernMediaControlsStyleSheet() override;
    String mediaControlsScript() override;
    String mediaControlsBase64StringForIconNameAndType(const String&, const String&) override;
#endif

#if ENABLE(ATTACHMENT_ELEMENT)
    LayoutSize attachmentIntrinsicSize(const RenderAttachment&) const override;
    int attachmentBaseline(const RenderAttachment&) const override;
    bool paintAttachment(const RenderObject&, const PaintInfo&, const IntRect&) override;
#endif

    bool shouldMockBoldSystemFontForAccessibility() const override { return m_shouldMockBoldSystemFontForAccessibility; }
    void setShouldMockBoldSystemFontForAccessibility(bool shouldMockBoldSystemFontForAccessibility) override { m_shouldMockBoldSystemFontForAccessibility = shouldMockBoldSystemFontForAccessibility; }

private:
    RenderThemeIOS();
    virtual ~RenderThemeIOS() = default;

    void purgeCaches() override;

#if PLATFORM(WATCHOS)
    String extraDefaultStyleSheet() final;
#endif

    const Color& shadowColor() const;
    FloatRect addRoundedBorderClip(const RenderObject& box, GraphicsContext&, const IntRect&);

    Color systemColor(CSSValueID, OptionSet<StyleColor::Options>) const override;

    String m_legacyMediaControlsScript;
    String m_mediaControlsScript;
    String m_legacyMediaControlsStyleSheet;
    String m_mediaControlsStyleSheet;

#if USE(SYSTEM_PREVIEW)
    RetainPtr<CIContext> m_ciContext;
#if HAVE(IOSURFACE)
    std::unique_ptr<IOSurface> m_largeBadgeSurface;
    std::unique_ptr<IOSurface> m_smallBadgeSurface;
#endif
#endif

    bool m_shouldMockBoldSystemFontForAccessibility { false };
};

}

#endif // PLATFORM(IOS_FAMILY)
