/*
 * Copyright (C) 2006-2017 Apple Inc. All rights reserved.
 * Copyright (C) 2009 Kenneth Rohde Christiansen
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public License
 * along with this library; see the file COPYING.LIB.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 *
 */

#include "config.h"
#include "RenderThemeWin.h"

#include "CSSValueKeywords.h"
#include "Element.h"
#include "FontMetrics.h"
#include "Frame.h"
#include "FrameSelection.h"
#include "GraphicsContext.h"
#include "HTMLMeterElement.h"
#include "LocalWindowsContext.h"
#include "PaintInfo.h"
#include "RenderMeter.h"
#include "RenderSlider.h"
#include "Settings.h"
#include "SystemInfo.h"
#include "UserAgentStyleSheets.h"
#include "WebCoreBundleWin.h"
#include <wtf/FileSystem.h>
#include <wtf/SoftLinking.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/win/GDIObject.h>

#include <tchar.h>

/* 
 * The following constants are used to determine how a widget is drawn using
 * Windows' Theme API. For more information on theme parts and states see
 * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp
 */

// Generic state constants
#define TS_NORMAL    1
#define TS_HOVER     2
#define TS_ACTIVE    3
#define TS_DISABLED  4
#define TS_FOCUSED   5

// Button constants
#define BP_BUTTON    1
#define BP_RADIO     2
#define BP_CHECKBOX  3

// Textfield constants
#define TFP_TEXTFIELD 1
#define EP_EDITBORDER_NOSCROLL 6
#define TFS_READONLY  6

// ComboBox constants (from vsstyle.h)
#define CP_DROPDOWNBUTTON 1
#define CP_BORDER 4
#define CP_READONLY 5
#define CP_DROPDOWNBUTTONRIGHT 6

// TrackBar (slider) parts
#define TKP_TRACK       1
#define TKP_TRACKVERT   2

// TrackBar (slider) thumb parts
#define TKP_THUMBBOTTOM 4
#define TKP_THUMBTOP    5
#define TKP_THUMBLEFT   7
#define TKP_THUMBRIGHT  8

// Trackbar (slider) thumb states
#define TUS_NORMAL      1
#define TUS_HOT         2
#define TUS_PRESSED     3
#define TUS_FOCUSED     4
#define TUS_DISABLED    5

// button states
#define PBS_NORMAL      1
#define PBS_HOT         2
#define PBS_PRESSED     3
#define PBS_DISABLED    4
#define PBS_DEFAULTED   5

// Spin button parts
#define SPNP_UP         1
#define SPNP_DOWN       2

// Spin button states
#define DNS_NORMAL      1
#define DNS_HOT         2
#define DNS_PRESSED     3
#define DNS_DISABLED    4
#define UPS_NORMAL      1
#define UPS_HOT         2
#define UPS_PRESSED     3
#define UPS_DISABLED    4

// Progress bar parts
#define PP_BAR          1
#define PP_BARVERT      2
#define PP_CHUNK        3
#define PP_CHUNKVERT    4
#define PP_FILL         5
#define PP_FILLVERT     6
#define PP_PULSEOVERLAY 7
#define PP_MOVEOVERLAY  8
#define PP_PULSEOVERLAYVERT 9
#define PP_MOVEOVERLAYVERT  10
#define PP_TRANSPARENTBAR   11
#define PP_TRANSPARENTBARVERT 12

// Progress bar states
#define PBBS_NORMAL     1
#define PBBS_PARTIAL    2
#define PBBVS_NORMAL    1 // Vertical
#define PBBVS_PARTIAL   2

// Progress bar fill states
#define PBFS_NORMAL     1
#define PBFS_ERROR      2
#define PBFS_PAUSED     3
#define PBFS_PARTIAL    4
#define PBFVS_NORMAL    1 // Vertical
#define PBFVS_ERROR     2
#define PBFVS_PAUSED    3
#define PBFVS_PARTIAL   4


SOFT_LINK_LIBRARY(uxtheme)
SOFT_LINK(uxtheme, OpenThemeData, HANDLE, WINAPI, (HWND hwnd, LPCWSTR pszClassList), (hwnd, pszClassList))
SOFT_LINK(uxtheme, CloseThemeData, HRESULT, WINAPI, (HANDLE hTheme), (hTheme))
SOFT_LINK(uxtheme, DrawThemeBackground, HRESULT, WINAPI, (HANDLE hTheme, HDC hdc, int iPartId, int iStateId, const RECT* pRect, const RECT* pClipRect), (hTheme, hdc, iPartId, iStateId, pRect, pClipRect))
SOFT_LINK(uxtheme, IsThemeActive, BOOL, WINAPI, (), ())
SOFT_LINK(uxtheme, IsThemeBackgroundPartiallyTransparent, BOOL, WINAPI, (HANDLE hTheme, int iPartId, int iStateId), (hTheme, iPartId, iStateId))

static bool haveTheme;

static const unsigned vistaMenuListButtonOutset = 1;


namespace WebCore {

// This is the fixed width IE and Firefox use for buttons on dropdown menus
static const int dropDownButtonWidth = 17;

// Default font size to match Firefox.
static const float defaultControlFontPixelSize = 13;

static const float defaultCancelButtonSize = 9;
static const float minCancelButtonSize = 5;
static const float maxCancelButtonSize = 21;
static const float defaultSearchFieldResultsDecorationSize = 13;
static const float minSearchFieldResultsDecorationSize = 9;
static const float maxSearchFieldResultsDecorationSize = 30;
static const float defaultSearchFieldResultsButtonWidth = 18;

static bool gWebKitIsBeingUnloaded;

void RenderThemeWin::setWebKitIsBeingUnloaded()
{
    gWebKitIsBeingUnloaded = true;
}

RenderTheme& RenderTheme::singleton()
{
    static NeverDestroyed<RenderThemeWin> theme;
    return theme;
}

RenderThemeWin::RenderThemeWin()
    : m_buttonTheme(0)
    , m_textFieldTheme(0)
    , m_menuListTheme(0)
    , m_sliderTheme(0)
    , m_spinButtonTheme(0)
    , m_progressBarTheme(0)
{
    haveTheme = uxthemeLibrary() && IsThemeActive();
}

RenderThemeWin::~RenderThemeWin()
{
    // If WebKit is being unloaded, then uxtheme.dll is no longer available.
    if (gWebKitIsBeingUnloaded || !uxthemeLibrary())
        return;
    close();
}

HANDLE RenderThemeWin::buttonTheme() const
{
    if (haveTheme && !m_buttonTheme)
        m_buttonTheme = OpenThemeData(0, L"Button");
    return m_buttonTheme;
}

HANDLE RenderThemeWin::textFieldTheme() const
{
    if (haveTheme && !m_textFieldTheme)
        m_textFieldTheme = OpenThemeData(0, L"Edit");
    return m_textFieldTheme;
}

HANDLE RenderThemeWin::menuListTheme() const
{
    if (haveTheme && !m_menuListTheme)
        m_menuListTheme = OpenThemeData(0, L"ComboBox");
    return m_menuListTheme;
}

HANDLE RenderThemeWin::sliderTheme() const
{
    if (haveTheme && !m_sliderTheme)
        m_sliderTheme = OpenThemeData(0, L"TrackBar");
    return m_sliderTheme;
}

HANDLE RenderThemeWin::spinButtonTheme() const
{
    if (haveTheme && !m_spinButtonTheme)
        m_spinButtonTheme = OpenThemeData(0, L"Spin");
    return m_spinButtonTheme;
}

HANDLE RenderThemeWin::progressBarTheme() const
{
    if (haveTheme && !m_progressBarTheme)
        m_progressBarTheme = OpenThemeData(0, L"Progress");
    return m_progressBarTheme;
}

void RenderThemeWin::close()
{
    // This method will need to be called when the OS theme changes to flush our cached themes.
    if (m_buttonTheme)
        CloseThemeData(m_buttonTheme);
    if (m_textFieldTheme)
        CloseThemeData(m_textFieldTheme);
    if (m_menuListTheme)
        CloseThemeData(m_menuListTheme);
    if (m_sliderTheme)
        CloseThemeData(m_sliderTheme);
    if (m_spinButtonTheme)
        CloseThemeData(m_spinButtonTheme);
    if (m_progressBarTheme)
        CloseThemeData(m_progressBarTheme);
    m_buttonTheme = m_textFieldTheme = m_menuListTheme = m_sliderTheme = m_spinButtonTheme = m_progressBarTheme = 0;

    haveTheme = uxthemeLibrary() && IsThemeActive();
}

void RenderThemeWin::themeChanged()
{
    close();
}

String RenderThemeWin::extraDefaultStyleSheet()
{
    return StringImpl::createWithoutCopying(themeWinUserAgentStyleSheet, sizeof(themeWinUserAgentStyleSheet));
}

String RenderThemeWin::extraQuirksStyleSheet()
{
    return StringImpl::createWithoutCopying(themeWinQuirksUserAgentStyleSheet, sizeof(themeWinQuirksUserAgentStyleSheet));
}

bool RenderThemeWin::supportsHover(const RenderStyle&) const
{
    // The Classic/2k look has no hover effects.
    return haveTheme;
}

Color RenderThemeWin::platformActiveSelectionBackgroundColor(OptionSet<StyleColorOptions>) const
{
    COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
    return SRGBA<uint8_t> { GetRValue(color), GetGValue(color), GetBValue(color) };
}

Color RenderThemeWin::platformInactiveSelectionBackgroundColor(OptionSet<StyleColorOptions>) const
{
    // This color matches Firefox.
    return SRGBA<uint8_t> { 176, 176, 176 };
}

Color RenderThemeWin::platformActiveSelectionForegroundColor(OptionSet<StyleColorOptions>) const
{
    COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
    return SRGBA<uint8_t> { GetRValue(color), GetGValue(color), GetBValue(color) };
}

Color RenderThemeWin::platformInactiveSelectionForegroundColor(OptionSet<StyleColorOptions> options) const
{
    return platformActiveSelectionForegroundColor(options);
}

static void fillFontDescription(FontCascadeDescription& fontDescription, LOGFONT& logFont, float fontSize)
{    
    fontDescription.setIsAbsoluteSize(true);
    fontDescription.setOneFamily(logFont.lfFaceName);
    fontDescription.setSpecifiedSize(fontSize);
    fontDescription.setWeight(logFont.lfWeight >= 700 ? boldWeightValue() : normalWeightValue()); // FIXME: Use real weight.
    fontDescription.setIsItalic(logFont.lfItalic);
}

void RenderThemeWin::updateCachedSystemFontDescription(CSSValueID valueID, FontCascadeDescription& fontDescription) const
{
    static bool initialized;
    static NONCLIENTMETRICS ncm;

    if (!initialized) {
        initialized = true;
        ncm.cbSize = sizeof(NONCLIENTMETRICS);
        ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, sizeof(ncm), &ncm, 0);
    }
 
    LOGFONT logFont;
    bool shouldUseDefaultControlFontPixelSize = false;
    switch (valueID) {
    case CSSValueIcon:
        ::SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(logFont), &logFont, 0);
        break;
    case CSSValueMenu:
        logFont = ncm.lfMenuFont;
        break;
    case CSSValueMessageBox:
        logFont = ncm.lfMessageFont;
        break;
    case CSSValueStatusBar:
        logFont = ncm.lfStatusFont;
        break;
    case CSSValueCaption:
        logFont = ncm.lfCaptionFont;
        break;
    case CSSValueSmallCaption:
        logFont = ncm.lfSmCaptionFont;
        break;
    case CSSValueWebkitSmallControl:
    case CSSValueWebkitMiniControl: // Just map to small.
    case CSSValueWebkitControl: // Just map to small.
        shouldUseDefaultControlFontPixelSize = true;
        FALLTHROUGH;
    default: { // Everything else uses the stock GUI font.
        HGDIOBJ hGDI = ::GetStockObject(DEFAULT_GUI_FONT);
        if (!hGDI)
            return;
        if (::GetObject(hGDI, sizeof(logFont), &logFont) <= 0)
            return;
    }
    }
    fillFontDescription(fontDescription, logFont, shouldUseDefaultControlFontPixelSize ? defaultControlFontPixelSize : abs(logFont.lfHeight));
}

bool RenderThemeWin::supportsFocus(ControlPart appearance) const
{
    switch (appearance) {
        case PushButtonPart:
        case ButtonPart:
        case DefaultButtonPart:
            return true;
        default:
            return false;
    }
}

bool RenderThemeWin::supportsFocusRing(const RenderStyle& style) const
{
    return supportsFocus(style.effectiveAppearance());
}

unsigned RenderThemeWin::determineClassicState(const RenderObject& o, ControlSubPart subPart)
{
    unsigned state = 0;
    switch (o.style().effectiveAppearance()) {
        case PushButtonPart:
        case ButtonPart:
        case DefaultButtonPart:
            state = DFCS_BUTTONPUSH;
            if (!isEnabled(o))
                state |= DFCS_INACTIVE;
            else if (isPressed(o))
                state |= DFCS_PUSHED;
            break;
        case RadioPart:
        case CheckboxPart:
            state = (o.style().effectiveAppearance() == RadioPart) ? DFCS_BUTTONRADIO : DFCS_BUTTONCHECK;
            if (isChecked(o))
                state |= DFCS_CHECKED;
            if (!isEnabled(o))
                state |= DFCS_INACTIVE;
            else if (isPressed(o))
                state |= DFCS_PUSHED;
            break;
        case MenulistPart:
            state = DFCS_SCROLLCOMBOBOX;
            if (!isEnabled(o))
                state |= DFCS_INACTIVE;
            else if (isPressed(o))
                state |= DFCS_PUSHED;
            break;
        case InnerSpinButtonPart: {
            bool isUpButton = subPart == SpinButtonUp;
            state = isUpButton ? DFCS_SCROLLUP : DFCS_SCROLLDOWN;
            if (!isEnabled(o) || isReadOnlyControl(o))
                state |= DFCS_INACTIVE;
            else if (isPressed(o) && isUpButton == isSpinUpButtonPartPressed(o))
                state |= DFCS_PUSHED;
            else if (isHovered(o) && isUpButton == isSpinUpButtonPartHovered(o))
                state |= DFCS_HOT;
            break;
        }
        default:
            break;
    }
    return state;
}

unsigned RenderThemeWin::determineState(const RenderObject& o)
{
    unsigned result = TS_NORMAL;
    ControlPart appearance = o.style().effectiveAppearance();
    if (!isEnabled(o))
        result = TS_DISABLED;
    else if (isReadOnlyControl(o) && (TextFieldPart == appearance || TextAreaPart == appearance || SearchFieldPart == appearance))
        result = TFS_READONLY; // Readonly is supported on textfields.
    else if (isPressed(o)) // Active overrides hover and focused.
        result = TS_ACTIVE;
    else if (supportsFocus(appearance) && isFocused(o))
        result = TS_FOCUSED;
    else if (isHovered(o))
        result = TS_HOVER;
    if (isChecked(o))
        result += 4; // 4 unchecked states, 4 checked states.
    else if (isIndeterminate(o) && appearance == CheckboxPart)
        result += 8;
    return result;
}

unsigned RenderThemeWin::determineSliderThumbState(const RenderObject& o)
{
    unsigned result = TUS_NORMAL;
    if (!isEnabled(o))
        result = TUS_DISABLED;
    else if (supportsFocus(o.style().effectiveAppearance()) && isFocused(o))
        result = TUS_FOCUSED;
    else if (isPressed(o))
        result = TUS_PRESSED;
    else if (isHovered(o))
        result = TUS_HOT;
    return result;
}

unsigned RenderThemeWin::determineButtonState(const RenderObject& o)
{
    unsigned result = PBS_NORMAL;
    if (!isEnabled(o))
        result = PBS_DISABLED;
    else if (isPressed(o))
        result = PBS_PRESSED;
    else if (supportsFocus(o.style().effectiveAppearance()) && isFocused(o))
        result = PBS_DEFAULTED;
    else if (isHovered(o))
        result = PBS_HOT;
    else if (isDefault(o))
        result = PBS_DEFAULTED;
    return result;
}

unsigned RenderThemeWin::determineSpinButtonState(const RenderObject& o, ControlSubPart subPart)
{
    bool isUpButton = subPart == SpinButtonUp;
    unsigned result = isUpButton ? UPS_NORMAL : DNS_NORMAL;
    if (!isEnabled(o) || isReadOnlyControl(o))
        result = isUpButton ? UPS_DISABLED : DNS_DISABLED;
    else if (isPressed(o) && isUpButton == isSpinUpButtonPartPressed(o))
        result = isUpButton ? UPS_PRESSED : DNS_PRESSED;
    else if (isHovered(o) && isUpButton == isSpinUpButtonPartHovered(o))
        result = isUpButton ? UPS_HOT : DNS_HOT;
    return result;
}

ThemeData RenderThemeWin::getClassicThemeData(const RenderObject& o, ControlSubPart subPart)
{
    ThemeData result;
    switch (o.style().effectiveAppearance()) {
        case PushButtonPart:
        case ButtonPart:
        case DefaultButtonPart:
        case CheckboxPart:
        case RadioPart:
            result.m_part = DFC_BUTTON;
            result.m_state = determineClassicState(o);
            break;
        case MenulistPart:
            result.m_part = DFC_SCROLL;
            result.m_state = determineClassicState(o);
            break;
        case MeterPart:
            result.m_part = PP_BAR;
            result.m_state = determineState(o);
            break;
        case SearchFieldPart:
        case TextFieldPart:
        case TextAreaPart:
            result.m_part = TFP_TEXTFIELD;
            result.m_state = determineState(o);
            break;
        case SliderHorizontalPart:
            result.m_part = TKP_TRACK;
            result.m_state = TS_NORMAL;
            break;
        case SliderVerticalPart:
            result.m_part = TKP_TRACKVERT;
            result.m_state = TS_NORMAL;
            break;
        case SliderThumbHorizontalPart:
            result.m_part = TKP_THUMBBOTTOM;
            result.m_state = determineSliderThumbState(o);
            break;
        case SliderThumbVerticalPart:
            result.m_part = TKP_THUMBRIGHT;
            result.m_state = determineSliderThumbState(o);
            break;
        case InnerSpinButtonPart:
            result.m_part = DFC_SCROLL;
            result.m_state = determineClassicState(o, subPart);
            break;
        default:
            break;
    }
    return result;
}

ThemeData RenderThemeWin::getThemeData(const RenderObject& o, ControlSubPart subPart)
{
    if (!haveTheme)
        return getClassicThemeData(o, subPart);

    ThemeData result;
    switch (o.style().effectiveAppearance()) {
        case PushButtonPart:
        case ButtonPart:
        case DefaultButtonPart:
            result.m_part = BP_BUTTON;
            result.m_state = determineButtonState(o);
            break;
        case CheckboxPart:
            result.m_part = BP_CHECKBOX;
            result.m_state = determineState(o);
            break;
        case MenulistPart:
        case MenulistButtonPart: {
            const bool isVistaOrLater = (windowsVersion() >= WindowsVista);
            result.m_part = isVistaOrLater ? CP_DROPDOWNBUTTONRIGHT : CP_DROPDOWNBUTTON;
            if (isVistaOrLater) {
                result.m_state = TS_NORMAL;
            } else
                result.m_state = determineState(o);
            break;
        }
        case MeterPart:
            result.m_part = PP_BAR;
            result.m_state = determineState(o);
            break;
        case RadioPart:
            result.m_part = BP_RADIO;
            result.m_state = determineState(o);
            break;
        case SearchFieldPart:
        case TextFieldPart:
        case TextAreaPart:
            result.m_part = (windowsVersion() >= WindowsVista) ? EP_EDITBORDER_NOSCROLL : TFP_TEXTFIELD;
            result.m_state = determineState(o);
            break;
        case SliderHorizontalPart:
            result.m_part = TKP_TRACK;
            result.m_state = TS_NORMAL;
            break;
        case SliderVerticalPart:
            result.m_part = TKP_TRACKVERT;
            result.m_state = TS_NORMAL;
            break;
        case SliderThumbHorizontalPart:
            result.m_part = TKP_THUMBBOTTOM;
            result.m_state = determineSliderThumbState(o);
            break;
        case SliderThumbVerticalPart:
            result.m_part = TKP_THUMBRIGHT;
            result.m_state = determineSliderThumbState(o);
            break;
        case InnerSpinButtonPart:
            result.m_part = subPart == SpinButtonUp ? SPNP_UP : SPNP_DOWN;
            result.m_state = determineSpinButtonState(o, subPart);
            break;
        default:
            break;
    }

    return result;
}

static void drawControl(GraphicsContext& context, const RenderObject& o, HANDLE theme, const ThemeData& themeData, const IntRect& r)
{
    bool alphaBlend = false;
    if (theme)
        alphaBlend = IsThemeBackgroundPartiallyTransparent(theme, themeData.m_part, themeData.m_state);
    LocalWindowsContext windowsContext(context, r, alphaBlend);
    RECT widgetRect = r;
    if (theme)
        DrawThemeBackground(theme, windowsContext.hdc(), themeData.m_part, themeData.m_state, &widgetRect, 0);
    else {
        HDC hdc = windowsContext.hdc();
        if (themeData.m_part == TFP_TEXTFIELD) {
            ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
            if (themeData.m_state == TS_DISABLED || themeData.m_state ==  TFS_READONLY)
                ::FillRect(hdc, &widgetRect, (HBRUSH)(COLOR_BTNFACE+1));
            else
                ::FillRect(hdc, &widgetRect, (HBRUSH)(COLOR_WINDOW+1));
        } else if (themeData.m_part == TKP_TRACK || themeData.m_part == TKP_TRACKVERT) {
            ::DrawEdge(hdc, &widgetRect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
            ::FillRect(hdc, &widgetRect, (HBRUSH)GetStockObject(GRAY_BRUSH));
        } else if ((o.style().effectiveAppearance() == SliderThumbHorizontalPart
        || o.style().effectiveAppearance() == SliderThumbVerticalPart)
        && (themeData.m_part == TKP_THUMBBOTTOM || themeData.m_part == TKP_THUMBTOP
        || themeData.m_part == TKP_THUMBLEFT || themeData.m_part == TKP_THUMBRIGHT)) {
            ::DrawEdge(hdc, &widgetRect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
            if (themeData.m_state == TUS_DISABLED) {
                static WORD patternBits[8] = {0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55};
                auto patternBmp = adoptGDIObject(::CreateBitmap(8, 8, 1, 1, patternBits));
                if (patternBmp) {
                    auto brush = adoptGDIObject(::CreatePatternBrush(patternBmp.get()));
                    COLORREF oldForeColor = ::SetTextColor(hdc, ::GetSysColor(COLOR_3DFACE));
                    COLORREF oldBackColor = ::SetBkColor(hdc, ::GetSysColor(COLOR_3DHILIGHT));
                    POINT p;
                    ::GetViewportOrgEx(hdc, &p);
                    ::SetBrushOrgEx(hdc, p.x + widgetRect.left, p.y + widgetRect.top, NULL);
                    HGDIOBJ oldBrush = ::SelectObject(hdc, brush.get());
                    ::FillRect(hdc, &widgetRect, brush.get());
                    ::SetTextColor(hdc, oldForeColor);
                    ::SetBkColor(hdc, oldBackColor);
                    ::SelectObject(hdc, oldBrush);
                } else
                    ::FillRect(hdc, &widgetRect, (HBRUSH)COLOR_3DHILIGHT);
            }
        } else {
            // Push buttons, buttons, checkboxes and radios, and the dropdown arrow in menulists.
            if (o.style().effectiveAppearance() == DefaultButtonPart) {
                HBRUSH brush = ::GetSysColorBrush(COLOR_3DDKSHADOW);
                ::FrameRect(hdc, &widgetRect, brush);
                ::InflateRect(&widgetRect, -1, -1);
                ::DrawEdge(hdc, &widgetRect, BDR_RAISEDOUTER, BF_RECT | BF_MIDDLE);
            }
            ::DrawFrameControl(hdc, &widgetRect, themeData.m_part, themeData.m_state);
        }
    }

    if (!alphaBlend && !context.isInTransparencyLayer())
        DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), r, 255);
}

bool RenderThemeWin::paintButton(const RenderObject& o, const PaintInfo& i, const IntRect& r)
{  
    drawControl(i.context(),  o, buttonTheme(), getThemeData(o), r);
    return false;
}

void RenderThemeWin::adjustInnerSpinButtonStyle(RenderStyle& style, const Element*) const
{
    int width = ::GetSystemMetrics(SM_CXVSCROLL);
    if (width <= 0)
        width = 17; // Vista's default.
    style.setWidth(Length(width, LengthType::Fixed));
    style.setMinWidth(Length(width, LengthType::Fixed));
}

bool RenderThemeWin::paintInnerSpinButton(const RenderObject& o, const PaintInfo& i, const IntRect& r)
{
    // We split the specified rectangle into two vertically. We can't draw a
    // spin button of which height is less than 2px.
    if (r.height() < 2)
        return false;
    IntRect upRect(r);
    upRect.setHeight(r.height() / 2);
    IntRect downRect(r);
    downRect.setY(upRect.maxY());
    downRect.setHeight(r.height() - upRect.height());
    drawControl(i.context(), o, spinButtonTheme(), getThemeData(o, SpinButtonUp), upRect);
    drawControl(i.context(), o, spinButtonTheme(), getThemeData(o, SpinButtonDown), downRect);
    return false;
}

void RenderThemeWin::setCheckboxSize(RenderStyle& style) const
{
    // If the width and height are both specified, then we have nothing to do.
    if (!style.width().isIntrinsicOrAuto() && !style.height().isAuto())
        return;

    // FIXME:  A hard-coded size of 13 is used.  This is wrong but necessary for now.  It matches Firefox.
    // At different DPI settings on Windows, querying the theme gives you a larger size that accounts for
    // the higher DPI.  Until our entire engine honors a DPI setting other than 96, we can't rely on the theme's
    // metrics.
    if (style.width().isIntrinsicOrAuto())
        style.setWidth(Length(13, LengthType::Fixed));
    if (style.height().isAuto())
        style.setHeight(Length(13, LengthType::Fixed));
}

bool RenderThemeWin::paintTextField(const RenderObject& o, const PaintInfo& i, const FloatRect& r)
{
    drawControl(i.context(),  o, textFieldTheme(), getThemeData(o), IntRect(r));
    return false;
}

bool RenderThemeWin::paintMenuList(const RenderObject& renderer, const PaintInfo& paintInfo, const FloatRect& rect)
{
    HANDLE theme;
    int part;
    if (haveTheme && (windowsVersion() >= WindowsVista)) {
        theme = menuListTheme();
        part = CP_READONLY;
    } else {
        theme = textFieldTheme();
        part = TFP_TEXTFIELD;
    }

    drawControl(paintInfo.context(), renderer, theme, ThemeData(part, determineState(renderer)), IntRect(rect));
    
    paintMenuListButtonDecorations(downcast<RenderBox>(renderer), paintInfo, FloatRect(rect));

    return false;
}

void RenderThemeWin::adjustMenuListStyle(RenderStyle& style, const Element* e) const
{
    style.resetBorder();
    adjustMenuListButtonStyle(style, e);
}

void RenderThemeWin::adjustMenuListButtonStyle(RenderStyle& style, const Element*) const
{
    // These are the paddings needed to place the text correctly in the <select> box
    const int dropDownBoxPaddingTop    = 2;
    const int dropDownBoxPaddingRight  = style.direction() == TextDirection::LTR ? 4 + dropDownButtonWidth : 4;
    const int dropDownBoxPaddingBottom = 2;
    const int dropDownBoxPaddingLeft   = style.direction() == TextDirection::LTR ? 4 : 4 + dropDownButtonWidth;
    // The <select> box must be at least 12px high for the button to render nicely on Windows
    const int dropDownBoxMinHeight = 12;
    
    // Position the text correctly within the select box and make the box wide enough to fit the dropdown button
    style.setPaddingTop(Length(dropDownBoxPaddingTop, LengthType::Fixed));
    style.setPaddingRight(Length(dropDownBoxPaddingRight, LengthType::Fixed));
    style.setPaddingBottom(Length(dropDownBoxPaddingBottom, LengthType::Fixed));
    style.setPaddingLeft(Length(dropDownBoxPaddingLeft, LengthType::Fixed));

    // Height is locked to auto
    style.setHeight(Length(LengthType::Auto));

    // Calculate our min-height
    int minHeight = style.fontMetrics().height();
    minHeight = std::max(minHeight, dropDownBoxMinHeight);

    style.setMinHeight(Length(minHeight, LengthType::Fixed));

    style.setLineHeight(RenderStyle::initialLineHeight());
    
    // White-space is locked to pre
    style.setWhiteSpace(WhiteSpace::Pre);
}

void RenderThemeWin::paintMenuListButtonDecorations(const RenderBox& renderer, const PaintInfo& paintInfo, const FloatRect& rect)
{
    // FIXME: Don't make hardcoded assumptions about the thickness of the textfield border.
    int borderThickness = haveTheme ? 1 : 2;

    // Paint the dropdown button on the inner edge of the text field,
    // leaving space for the text field's 1px border
    IntRect buttonRect(rect);
    buttonRect.inflate(-borderThickness);
    if (renderer.style().direction() == TextDirection::LTR)
        buttonRect.setX(buttonRect.maxX() - dropDownButtonWidth);
    buttonRect.setWidth(dropDownButtonWidth);

    if ((windowsVersion() >= WindowsVista)) {
        // Outset the top, right, and bottom borders of the button so that they coincide with the <select>'s border.
        buttonRect.setY(buttonRect.y() - vistaMenuListButtonOutset);
        buttonRect.setHeight(buttonRect.height() + 2 * vistaMenuListButtonOutset);
        buttonRect.setWidth(buttonRect.width() + vistaMenuListButtonOutset);
    }

    drawControl(paintInfo.context(), renderer, menuListTheme(), getThemeData(renderer), buttonRect);
}

const int trackWidth = 4;

bool RenderThemeWin::paintSliderTrack(const RenderObject& o, const PaintInfo& i, const IntRect& r)
{
    IntRect bounds = r;
    
    if (o.style().effectiveAppearance() ==  SliderHorizontalPart) {
        bounds.setHeight(trackWidth);
        bounds.setY(r.y() + r.height() / 2 - trackWidth / 2);
    } else if (o.style().effectiveAppearance() == SliderVerticalPart) {
        bounds.setWidth(trackWidth);
        bounds.setX(r.x() + r.width() / 2 - trackWidth / 2);
    }
    
    drawControl(i.context(),  o, sliderTheme(), getThemeData(o), bounds);
    return false;
}

bool RenderThemeWin::paintSliderThumb(const RenderObject& o, const PaintInfo& i, const IntRect& r)
{   
    drawControl(i.context(),  o, sliderTheme(), getThemeData(o), r);
    return false;
}

const int sliderThumbWidth = 7;
const int sliderThumbHeight = 15;

void RenderThemeWin::adjustSliderThumbSize(RenderStyle& style, const Element*) const
{
    ControlPart part = style.effectiveAppearance();
    if (part == SliderThumbVerticalPart) {
        style.setWidth(Length(sliderThumbHeight, LengthType::Fixed));
        style.setHeight(Length(sliderThumbWidth, LengthType::Fixed));
    } else if (part == SliderThumbHorizontalPart) {
        style.setWidth(Length(sliderThumbWidth, LengthType::Fixed));
        style.setHeight(Length(sliderThumbHeight, LengthType::Fixed));
    }
}

bool RenderThemeWin::paintSearchField(const RenderObject& o, const PaintInfo& i, const IntRect& r)
{
    return paintTextField(o, i, r);
}

void RenderThemeWin::adjustSearchFieldStyle(RenderStyle& style, const Element* e) const
{
    // Override paddingSize to match AppKit text positioning.
    const int padding = 1;
    style.setPaddingLeft(Length(padding, LengthType::Fixed));
    style.setPaddingRight(Length(padding, LengthType::Fixed));
    style.setPaddingTop(Length(padding, LengthType::Fixed));
    style.setPaddingBottom(Length(padding, LengthType::Fixed));
    if (e && e->focused() && e->document().frame()->selection().isFocusedAndActive())
        style.setOutlineOffset(-2);
}

bool RenderThemeWin::paintSearchFieldCancelButton(const RenderBox& o, const PaintInfo& paintInfo, const IntRect& r)
{
    IntRect bounds = r;
    ASSERT(o.parent());
    if (!is<RenderBox>(o.parent()))
        return false;

    IntRect parentBox = downcast<RenderBox>(*o.parent()).absoluteContentBox();
    
    // Make sure the scaled button stays square and will fit in its parent's box
    bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height())));
    bounds.setWidth(bounds.height());

    // Center the button vertically.  Round up though, so if it has to be one pixel off-center, it will
    // be one pixel closer to the bottom of the field.  This tends to look better with the text.
    bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);

    static Image& cancelImage = Image::loadPlatformResource("searchCancel").leakRef();
    static Image& cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").leakRef();
    paintInfo.context().drawImage(isPressed(o) ? cancelPressedImage : cancelImage, bounds);
    return false;
}

void RenderThemeWin::adjustSearchFieldCancelButtonStyle(RenderStyle& style, const Element*) const
{
    // Scale the button size based on the font size
    float fontScale = style.computedFontPixelSize() / defaultControlFontPixelSize;
    int cancelButtonSize = lroundf(std::min(std::max(minCancelButtonSize, defaultCancelButtonSize * fontScale), maxCancelButtonSize));
    style.setWidth(Length(cancelButtonSize, LengthType::Fixed));
    style.setHeight(Length(cancelButtonSize, LengthType::Fixed));
}

void RenderThemeWin::adjustSearchFieldDecorationPartStyle(RenderStyle& style, const Element*) const
{
    IntSize emptySize(1, 11);
    style.setWidth(Length(emptySize.width(), LengthType::Fixed));
    style.setHeight(Length(emptySize.height(), LengthType::Fixed));
}

void RenderThemeWin::adjustSearchFieldResultsDecorationPartStyle(RenderStyle& style, const Element*) const
{
    // Scale the decoration size based on the font size
    float fontScale = style.computedFontPixelSize() / defaultControlFontPixelSize;
    int magnifierSize = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), 
                                     maxSearchFieldResultsDecorationSize));
    style.setWidth(Length(magnifierSize, LengthType::Fixed));
    style.setHeight(Length(magnifierSize, LengthType::Fixed));
}

bool RenderThemeWin::paintSearchFieldResultsDecorationPart(const RenderBox& o, const PaintInfo& paintInfo, const IntRect& r)
{
    IntRect bounds = r;
    ASSERT(o.parent());
    if (!is<RenderBox>(o.parent()))
        return false;
    
    IntRect parentBox = downcast<RenderBox>(*o.parent()).absoluteContentBox();
    
    // Make sure the scaled decoration stays square and will fit in its parent's box
    bounds.setHeight(std::min(parentBox.width(), std::min(parentBox.height(), bounds.height())));
    bounds.setWidth(bounds.height());

    // Center the decoration vertically.  Round up though, so if it has to be one pixel off-center, it will
    // be one pixel closer to the bottom of the field.  This tends to look better with the text.
    bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);
    
    static Image& magnifierImage = Image::loadPlatformResource("searchMagnifier").leakRef();
    paintInfo.context().drawImage(magnifierImage, bounds);
    return false;
}

void RenderThemeWin::adjustSearchFieldResultsButtonStyle(RenderStyle& style, const Element*) const
{
    // Scale the button size based on the font size
    float fontScale = style.computedFontPixelSize() / defaultControlFontPixelSize;
    int magnifierHeight = lroundf(std::min(std::max(minSearchFieldResultsDecorationSize, defaultSearchFieldResultsDecorationSize * fontScale), 
                                   maxSearchFieldResultsDecorationSize));
    int magnifierWidth = lroundf(magnifierHeight * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize);
    style.setWidth(Length(magnifierWidth, LengthType::Fixed));
    style.setHeight(Length(magnifierHeight, LengthType::Fixed));
}

bool RenderThemeWin::paintSearchFieldResultsButton(const RenderBox& o, const PaintInfo& paintInfo, const IntRect& r)
{
    IntRect bounds = r;
    ASSERT(o.parent());
    if (!o.parent())
        return false;
    if (!is<RenderBox>(o.parent()))
        return false;
    
    IntRect parentBox = downcast<RenderBox>(*o.parent()).absoluteContentBox();
    
    // Make sure the scaled decoration will fit in its parent's box
    bounds.setHeight(std::min(parentBox.height(), bounds.height()));
    bounds.setWidth(std::min<int>(parentBox.width(), bounds.height() * defaultSearchFieldResultsButtonWidth / defaultSearchFieldResultsDecorationSize));

    // Center the button vertically.  Round up though, so if it has to be one pixel off-center, it will
    // be one pixel closer to the bottom of the field.  This tends to look better with the text.
    bounds.setY(parentBox.y() + (parentBox.height() - bounds.height() + 1) / 2);

    static Image& magnifierImage = Image::loadPlatformResource("searchMagnifierResults").leakRef();
    paintInfo.context().drawImage(magnifierImage, bounds);
    return false;
}

// Map a CSSValue* system color to an index understood by GetSysColor
static int cssValueIdToSysColorIndex(CSSValueID cssValueId)
{
    switch (cssValueId) {
    case CSSValueActiveborder: return COLOR_ACTIVEBORDER;
    case CSSValueActivecaption: return COLOR_ACTIVECAPTION;
    case CSSValueAppworkspace: return COLOR_APPWORKSPACE;
    case CSSValueBackground: return COLOR_BACKGROUND;
    case CSSValueButtonface: return COLOR_BTNFACE;
    case CSSValueButtonhighlight: return COLOR_BTNHIGHLIGHT;
    case CSSValueButtonshadow: return COLOR_BTNSHADOW;
    case CSSValueButtontext: return COLOR_BTNTEXT;
    case CSSValueCaptiontext: return COLOR_CAPTIONTEXT;
    case CSSValueGraytext: return COLOR_GRAYTEXT;
    case CSSValueHighlight: return COLOR_HIGHLIGHT;
    case CSSValueHighlighttext: return COLOR_HIGHLIGHTTEXT;
    case CSSValueInactiveborder: return COLOR_INACTIVEBORDER;
    case CSSValueInactivecaption: return COLOR_INACTIVECAPTION;
    case CSSValueInactivecaptiontext: return COLOR_INACTIVECAPTIONTEXT;
    case CSSValueInfobackground: return COLOR_INFOBK;
    case CSSValueInfotext: return COLOR_INFOTEXT;
    case CSSValueMenu: return COLOR_MENU;
    case CSSValueMenutext: return COLOR_MENUTEXT;
    case CSSValueScrollbar: return COLOR_SCROLLBAR;
    case CSSValueThreeddarkshadow: return COLOR_3DDKSHADOW;
    case CSSValueThreedface: return COLOR_3DFACE;
    case CSSValueThreedhighlight: return COLOR_3DHIGHLIGHT;
    case CSSValueThreedlightshadow: return COLOR_3DLIGHT;
    case CSSValueThreedshadow: return COLOR_3DSHADOW;
    case CSSValueWindow: return COLOR_WINDOW;
    case CSSValueWindowframe: return COLOR_WINDOWFRAME;
    case CSSValueWindowtext: return COLOR_WINDOWTEXT;
    default: return -1; // Unsupported CSSValue
    }
}

Color RenderThemeWin::systemColor(CSSValueID cssValueId, OptionSet<StyleColorOptions> options) const
{
#if HAVE(OS_DARK_MODE_SUPPORT)
    switch (cssValueId) {
    case CSSValueWebkitControlBackground:
        // FIXME: Dark mode isn't supported yet. https://webkit.org/b/230032
        return Color::white;
    }
#endif
    int sysColorIndex = cssValueIdToSysColorIndex(cssValueId);
    if (sysColorIndex == -1)
        return RenderTheme::systemColor(cssValueId, options);

    COLORREF color = GetSysColor(sysColorIndex);
    return SRGBA<uint8_t> { GetRValue(color), GetGValue(color), GetBValue(color) };
}

#if ENABLE(VIDEO)
static void fillBufferWithContentsOfFile(FileSystem::PlatformFileHandle file, long long filesize, Vector<uint8_t>& buffer)
{
    // Load the file content into buffer
    buffer.resize(filesize + 1);

    int bufferPosition = 0;
    int bufferReadSize = 4096;
    int bytesRead = 0;
    while (filesize > bufferPosition) {
        if (filesize - bufferPosition < bufferReadSize)
            bufferReadSize = filesize - bufferPosition;

        bytesRead = FileSystem::readFromFile(file, buffer.data() + bufferPosition, bufferReadSize);
        if (bytesRead != bufferReadSize) {
            buffer.clear();
            return;
        }

        bufferPosition += bufferReadSize;
    }

    buffer[filesize] = 0;
}

String RenderThemeWin::stringWithContentsOfFile(const String& name, const String& type)
{
#if USE(CF)
    RetainPtr<CFURLRef> requestedURLRef = adoptCF(CFBundleCopyResourceURL(webKitBundle(), name.createCFString().get(), type.createCFString().get(), 0));
    if (!requestedURLRef)
        return String();

    UInt8 requestedFilePath[MAX_PATH];
    if (!CFURLGetFileSystemRepresentation(requestedURLRef.get(), false, requestedFilePath, MAX_PATH))
        return String();

    FileSystem::PlatformFileHandle requestedFileHandle = FileSystem::openFile(requestedFilePath, FileSystem::FileOpenMode::Read);
    if (!FileSystem::isHandleValid(requestedFileHandle))
        return String();

    auto filesize = FileSystem::fileSize(requestedFileHandle);
    if (!filesize) {
        FileSystem::closeFile(requestedFileHandle);
        return String();
    }

    Vector<uint8_t> fileContents;
    fillBufferWithContentsOfFile(requestedFileHandle, *filesize, fileContents);
    FileSystem::closeFile(requestedFileHandle);

    return String(fileContents.data(), *filesize);
#else
    return emptyString();
#endif
}

String RenderThemeWin::mediaControlsStyleSheet()
{
#if ENABLE(MEDIA_CONTROLS_SCRIPT)
    if (m_mediaControlsStyleSheet.isEmpty())
        m_mediaControlsStyleSheet = stringWithContentsOfFile("mediaControlsApple"_s, "css"_s);
    return m_mediaControlsStyleSheet;
#else
    return emptyString();
#endif
}

Vector<String, 2> RenderThemeWin::mediaControlsScripts()
{
#if ENABLE(MEDIA_CONTROLS_SCRIPT)
    if (m_mediaControlsScript.isEmpty()) {
        StringBuilder scriptBuilder;
        scriptBuilder.append(stringWithContentsOfFile("mediaControlsLocalizedStrings"_s, "js"_s));
        scriptBuilder.append(stringWithContentsOfFile("mediaControlsApple"_s, "js"_s));
        m_mediaControlsScript = scriptBuilder.toString();
    }
    return { m_mediaControlsScript };
#else
    return { };
#endif
}
#endif

void RenderThemeWin::adjustMeterStyle(RenderStyle& style, const Element*) const
{
    style.setBoxShadow(nullptr);
}

bool RenderThemeWin::supportsMeter(ControlPart part, const HTMLMeterElement&) const
{
    switch (part) {
    case MeterPart:
        return true;
    default:
        return false;
    }
}

IntSize RenderThemeWin::meterSizeForBounds(const RenderMeter&, const IntRect& bounds) const
{
    return bounds.size();
}

bool RenderThemeWin::paintMeter(const RenderObject& renderObject, const PaintInfo& paintInfo, const IntRect& rect)
{
    if (!is<RenderMeter>(renderObject))
        return true;

    HTMLMeterElement* element = downcast<RenderMeter>(renderObject).meterElement();

    ThemeData theme = getThemeData(renderObject);

    int remaining = static_cast<int>((1.0 - element->valueRatio()) * static_cast<double>(rect.size().width()));

    // Draw the background
    drawControl(paintInfo.context(), renderObject, progressBarTheme(), theme, rect);

    // Draw the progress portion
    IntRect completedRect(rect);
    completedRect.contract(remaining, 0);

    theme.m_part = PP_FILL;
    drawControl(paintInfo.context(), renderObject, progressBarTheme(), theme, completedRect);

    return true;
}


}
