/*
 * 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 "CSSValueKey.h"
#include "RenderThemeCocoa.h"

#if USE(SYSTEM_PREVIEW)
#include "IOSurface.h"
#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

    using CSSValueToSystemColorMap = HashMap<CSSValueKey, Color>;

    WEBCORE_EXPORT static const CSSValueToSystemColorMap& cssValueToSystemColorMap();
    WEBCORE_EXPORT static void setCSSValueToSystemColorMap(CSSValueToSystemColorMap&&);

    WEBCORE_EXPORT static void setFocusRingColor(const Color&);

private:
    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(RenderStyle&, const Element*) const override;
    bool paintCheckboxDecorations(const RenderObject&, const PaintInfo&, const IntRect&) override;

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

    void adjustButtonStyle(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(RenderStyle&, const Element*) const override;
    bool paintMenuListButtonDecorations(const RenderBox&, const PaintInfo&, const FloatRect&) override;

    void adjustSliderTrackStyle(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(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 SimpleColor { 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;
    std::unique_ptr<IOSurface> m_largeBadgeSurface;
    std::unique_ptr<IOSurface> m_smallBadgeSurface;
#endif

    bool m_shouldMockBoldSystemFontForAccessibility { false };
};

}

#endif // PLATFORM(IOS_FAMILY)
