/*
 * This file is part of the WebKit project.
 *
 * Copyright (C) 2006 Apple Computer, Inc.
 * Copyright (C) 2008, 2009 Google, Inc.
 * 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 "core/rendering/RenderThemeChromiumWin.h"

#include <windows.h>
#include <uxtheme.h>
#include <vssym32.h>

#include "CSSValueKeywords.h"
#include "HTMLNames.h"
#include "core/html/HTMLMediaElement.h"
#include "core/html/shadow/MediaControlElements.h"
#include "core/platform/ScrollbarTheme.h"
#include "core/platform/graphics/FontSelector.h"
#include "core/platform/graphics/GraphicsContext.h"
#include "core/platform/graphics/chromium/FontUtilsChromiumWin.h"
#include "core/platform/graphics/chromium/TransparencyWin.h"
#include "core/rendering/PaintInfo.h"
#include "core/rendering/RenderBox.h"
#include "core/rendering/RenderProgress.h"
#include "core/rendering/RenderSlider.h"
#include "platform/LayoutTestSupport.h"
#include "platform/win/SystemInfo.h"
#include "public/platform/Platform.h"
#include "public/platform/WebColor.h"
#include "public/platform/WebRect.h"
#include "public/platform/win/WebThemeEngine.h"
#include "wtf/CurrentTime.h"

// FIXME: This dependency should eventually be removed.
#include <skia/ext/skia_utils_win.h>

namespace WebCore {

// The standard width for the menu list drop-down button when run under
// layout test mode. Use the value that's currently captured in most baselines.
static const int kStandardMenuListButtonWidth = 17;

namespace {
// We must not create multiple ThemePainter instances.
class ThemePainter {
public:
    ThemePainter(GraphicsContext* context, const IntRect& r)
    {
#ifndef NDEBUG
        ASSERT(!s_hasInstance);
        s_hasInstance = true;
#endif
        TransparencyWin::TransformMode transformMode = getTransformMode(context->getCTM());
        m_helper.init(context, getLayerMode(context, transformMode), transformMode, r);

        if (!m_helper.context()) {
            // TransparencyWin doesn't have well-defined copy-ctor nor op=()
            // so we re-initialize it instead of assigning a fresh istance.
            // On the reinitialization, we fallback to use NoLayer mode.
            // Note that the original initialization failure can be caused by
            // a failure of an internal buffer allocation and NoLayer mode
            // does not have such buffer allocations.
            m_helper.~TransparencyWin();
            new (&m_helper) TransparencyWin();
            m_helper.init(context, TransparencyWin::NoLayer, transformMode, r);
        }
    }

    ~ThemePainter()
    {
        m_helper.composite();
#ifndef NDEBUG
        s_hasInstance = false;
#endif
    }

    GraphicsContext* context() { return m_helper.context(); }
    const IntRect& drawRect() { return m_helper.drawRect(); }

private:

    static TransparencyWin::LayerMode getLayerMode(GraphicsContext* context, TransparencyWin::TransformMode transformMode)
    {
        if (!context->isCertainlyOpaque()) // Might have transparent background.
            return TransparencyWin::WhiteLayer;
        if (context->canvas()->isDrawingToLayer()) // Needs antialiasing help.
            return TransparencyWin::OpaqueCompositeLayer;
        // Nothing interesting.
        return transformMode == TransparencyWin::KeepTransform ? TransparencyWin::NoLayer : TransparencyWin::OpaqueCompositeLayer;
    }

    static TransparencyWin::TransformMode getTransformMode(const AffineTransform& matrix)
    {
        if (matrix.b() || matrix.c()) // Skew.
            return TransparencyWin::Untransform;
        if (matrix.a() != 1.0 || matrix.d() != 1.0) // Scale.
            return TransparencyWin::ScaleTransform;
        // Nothing interesting.
        return TransparencyWin::KeepTransform;
    }

    TransparencyWin m_helper;
#ifndef NDEBUG
    static bool s_hasInstance;
#endif
};

#ifndef NDEBUG
bool ThemePainter::s_hasInstance = false;
#endif

} // namespace

// Internal static helper functions.  We don't put them in an anonymous
// namespace so they have easier access to the WebCore namespace.

static bool supportsFocus(ControlPart appearance)
{
    switch (appearance) {
    case SquareButtonPart:
    case PushButtonPart:
    case ButtonPart:
    case SearchFieldPart:
    case TextFieldPart:
    case TextAreaPart:
        return true;
    }
    return false;
}

static double querySystemBlinkInterval(double defaultInterval)
{
    UINT blinkTime = GetCaretBlinkTime();
    if (!blinkTime)
        return defaultInterval;
    if (blinkTime == INFINITE)
        return 0;
    return blinkTime / 1000.0;
}

PassRefPtr<RenderTheme> RenderThemeChromiumWin::create()
{
    return adoptRef(new RenderThemeChromiumWin);
}

RenderTheme& RenderTheme::theme()
{
    static RenderTheme* renderTheme = RenderThemeChromiumWin::create().leakRef();
    return *renderTheme;
}

bool RenderThemeChromiumWin::supportsFocusRing(const RenderStyle* style) const
{
    // Let webkit draw one of its halo rings around any focused element,
    // except push buttons. For buttons we use the windows PBS_DEFAULTED
    // styling to give it a blue border.
    return style->appearance() == ButtonPart
            || style->appearance() == PushButtonPart
            || style->appearance() == SquareButtonPart;
}

Color RenderThemeChromiumWin::platformActiveSelectionBackgroundColor() const
{
    if (isRunningLayoutTest())
        return Color(0x00, 0x00, 0xff); // Royal blue.
    COLORREF color = GetSysColor(COLOR_HIGHLIGHT);
    return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
}

Color RenderThemeChromiumWin::platformInactiveSelectionBackgroundColor() const
{
    if (isRunningLayoutTest())
        return Color(0x99, 0x99, 0x99); // Medium gray.
    COLORREF color = GetSysColor(COLOR_GRAYTEXT);
    return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
}

Color RenderThemeChromiumWin::platformActiveSelectionForegroundColor() const
{
    if (isRunningLayoutTest())
        return Color(0xff, 0xff, 0xcc); // Pale yellow.
    COLORREF color = GetSysColor(COLOR_HIGHLIGHTTEXT);
    return Color(GetRValue(color), GetGValue(color), GetBValue(color), 0xff);
}

Color RenderThemeChromiumWin::platformInactiveSelectionForegroundColor() const
{
    return Color::white;
}

Color RenderThemeChromiumWin::platformActiveTextSearchHighlightColor() const
{
    return Color(0xff, 0x96, 0x32); // Orange.
}

Color RenderThemeChromiumWin::platformInactiveTextSearchHighlightColor() const
{
    return Color(0xff, 0xff, 0x96); // Yellow.
}

// Map a CSSValue* system color to an index understood by GetSysColor().
static int cssValueIdToSysColorIndex(int 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 RenderThemeChromiumWin::systemColor(CSSValueID cssValueId) const
{
    int sysColorIndex = cssValueIdToSysColorIndex(cssValueId);
    if (isRunningLayoutTest() || (sysColorIndex == -1))
        return RenderTheme::systemColor(cssValueId);

    COLORREF color = GetSysColor(sysColorIndex);
    return Color(GetRValue(color), GetGValue(color), GetBValue(color));
}

IntSize RenderThemeChromiumWin::sliderTickSize() const
{
    return IntSize(1, 3);
}

int RenderThemeChromiumWin::sliderTickOffsetFromTrackCenter() const
{
    return 11;
}

void RenderThemeChromiumWin::adjustSliderThumbSize(RenderStyle* style, Element* element) const
{
    // These sizes match what WinXP draws for various menus.
    const int sliderThumbAlongAxis = 11;
    const int sliderThumbAcrossAxis = 21;
    if (style->appearance() == SliderThumbHorizontalPart) {
        style->setWidth(Length(sliderThumbAlongAxis, Fixed));
        style->setHeight(Length(sliderThumbAcrossAxis, Fixed));
    } else if (style->appearance() == SliderThumbVerticalPart) {
        style->setWidth(Length(sliderThumbAcrossAxis, Fixed));
        style->setHeight(Length(sliderThumbAlongAxis, Fixed));
    } else
        RenderThemeChromiumSkia::adjustSliderThumbSize(style, element);
}

bool RenderThemeChromiumWin::paintCheckbox(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    return paintButton(o, i, r);
}
bool RenderThemeChromiumWin::paintRadio(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    return paintButton(o, i, r);
}

bool RenderThemeChromiumWin::paintButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    const ThemeData& themeData = getThemeData(o);

    ThemePainter painter(i.context, r);
    WebKit::WebCanvas* canvas = painter.context()->canvas();
    WebKit::Platform::current()->themeEngine()->paintButton(canvas, themeData.m_part, themeData.m_state, themeData.m_classicState, WebKit::WebRect(painter.drawRect()));
    return false;
}

bool RenderThemeChromiumWin::paintTextField(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    return paintTextFieldInternal(o, i, r, true);
}

bool RenderThemeChromiumWin::paintSliderTrack(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    const ThemeData& themeData = getThemeData(o);

    ThemePainter painter(i.context, r);
    WebKit::WebCanvas* canvas = painter.context()->canvas();
    WebKit::Platform::current()->themeEngine()->paintTrackbar(canvas, themeData.m_part, themeData.m_state, themeData.m_classicState, WebKit::WebRect(painter.drawRect()));

    paintSliderTicks(o, i, r);

    return false;
}

bool RenderThemeChromiumWin::paintSliderThumb(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    const ThemeData& themeData = getThemeData(o);

    ThemePainter painter(i.context, r);
    WebKit::WebCanvas* canvas = painter.context()->canvas();
    WebKit::Platform::current()->themeEngine()->paintTrackbar(canvas, themeData.m_part, themeData.m_state, themeData.m_classicState, WebKit::WebRect(painter.drawRect()));

    return false;
}

static int menuListButtonWidth()
{
    static int width = isRunningLayoutTest() ? kStandardMenuListButtonWidth :
        IntSize(WebKit::Platform::current()->themeEngine()->getSize(SBP_ARROWBTN)).width();
    return width;
}

// Used to paint unstyled menulists (i.e. with the default border)
bool RenderThemeChromiumWin::paintMenuList(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    if (!o->isBox())
        return false;

    const RenderBox* box = toRenderBox(o);
    int borderRight = box->borderRight();
    int borderLeft = box->borderLeft();
    int borderTop = box->borderTop();
    int borderBottom = box->borderBottom();

    // If all the borders are 0, then tell skia not to paint the border on the
    // textfield.  FIXME: http://b/1210017 Figure out how to get Windows to not
    // draw individual borders and then pass that to skia so we can avoid
    // drawing any borders that are set to 0. For non-zero borders, we draw the
    // border, but webkit just draws over it.
    bool drawEdges = !(!borderRight && !borderLeft && !borderTop && !borderBottom);

    paintTextFieldInternal(o, i, r, drawEdges);
    return paintMenuListButton(o, i, r);
}

bool RenderThemeChromiumWin::paintMenuListButton(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    if (!o->isBox())
        return false;

    const RenderBox* box = toRenderBox(o);
    // Take padding and border into account.  If the MenuList is smaller than
    // the size of a button, make sure to shrink it appropriately and not put
    // its x position to the left of the menulist.
    const int buttonWidth = menuListButtonWidth();
    int spacingLeft = box->borderLeft() + box->paddingLeft();
    int spacingRight = box->borderRight() + box->paddingRight();
    int spacingTop = box->borderTop() + box->paddingTop();
    int spacingBottom = box->borderBottom() + box->paddingBottom();

    int buttonX;
    if (r.maxX() - r.x() < buttonWidth)
        buttonX = r.x();
    else
        buttonX = o->style()->direction() == LTR ? r.maxX() - spacingRight - buttonWidth : r.x() + spacingLeft;

    // Compute the rectangle of the button in the destination image.
    IntRect rect(buttonX,
                 r.y() + spacingTop,
                 std::min(buttonWidth, r.maxX() - r.x()),
                 r.height() - (spacingTop + spacingBottom));

    // Get the correct theme data for a textfield and paint the menu.
    ThemePainter painter(i.context, rect);
    WebKit::WebCanvas* canvas = painter.context()->canvas();
    WebKit::Platform::current()->themeEngine()->paintMenuList(canvas, CP_DROPDOWNBUTTON, determineState(o), determineClassicState(o), WebKit::WebRect(painter.drawRect()));
    return false;
}

double RenderThemeChromiumWin::caretBlinkIntervalInternal() const
{
    // This involves a system call, so we cache the result.
    static double blinkInterval = querySystemBlinkInterval(RenderTheme::caretBlinkInterval());
    return blinkInterval;
}

unsigned RenderThemeChromiumWin::determineState(RenderObject* o, ControlSubPart subPart)
{
    unsigned result = TS_NORMAL;
    ControlPart appearance = o->style()->appearance();
    if (!isEnabled(o))
        result = TS_DISABLED;
    else if (isReadOnlyControl(o))
        result = (appearance == TextFieldPart || appearance == TextAreaPart || appearance == SearchFieldPart) ? ETS_READONLY : TS_DISABLED;
    // Active overrides hover and focused.
    else if (isPressed(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartPressed(o))
        result = TS_PRESSED;
    else if (supportsFocus(appearance) && isFocused(o))
        result = ETS_FOCUSED;
    else if (isHovered(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartHovered(o))
        result = TS_HOT;

    // CBS_UNCHECKED*: 1-4
    // CBS_CHECKED*: 5-8
    // CBS_MIXED*: 9-12
    if (isIndeterminate(o))
        result += 8;
    else if (isChecked(o))
        result += 4;
    return result;
}

unsigned RenderThemeChromiumWin::determineSliderThumbState(RenderObject* o)
{
    unsigned result = TUS_NORMAL;
    if (!isEnabled(o))
        result = TUS_DISABLED;
    else if (supportsFocus(o->style()->appearance()) && isFocused(o))
        result = TUS_FOCUSED;
    else if (isPressed(o))
        result = TUS_PRESSED;
    else if (isHovered(o))
        result = TUS_HOT;
    return result;
}

unsigned RenderThemeChromiumWin::determineClassicState(RenderObject* o, ControlSubPart subPart)
{
    unsigned result = 0;

    ControlPart part = o->style()->appearance();

    // Sliders are always in the normal state.
    if (part == SliderHorizontalPart || part == SliderVerticalPart)
        return result;

    // So are readonly text fields.
    if (isReadOnlyControl(o) && (part == TextFieldPart || part == TextAreaPart || part == SearchFieldPart))
        return result;

    if (part == SliderThumbHorizontalPart || part == SliderThumbVerticalPart) {
        if (!isEnabled(o))
            result = DFCS_INACTIVE;
        else if (isPressed(o)) // Active supersedes hover
            result = DFCS_PUSHED;
        else if (isHovered(o))
            result = DFCS_HOT;
    } else {
        if (!isEnabled(o) || isReadOnlyControl(o))
            result = DFCS_INACTIVE;
        // Active supersedes hover
        else if (isPressed(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartPressed(o))
            result = DFCS_PUSHED;
        else if (supportsFocus(part) && isFocused(o)) // So does focused
            result = 0;
        else if (isHovered(o) && (subPart == SpinButtonUp) == isSpinUpButtonPartHovered(o))
            result = DFCS_HOT;
        // Classic theme can't represent indeterminate states. Use unchecked appearance.
        if (isChecked(o) && !isIndeterminate(o))
            result |= DFCS_CHECKED;
    }
    return result;
}

ThemeData RenderThemeChromiumWin::getThemeData(RenderObject* o, ControlSubPart subPart)
{
    ThemeData result;
    switch (o->style()->appearance()) {
    case CheckboxPart:
        result.m_part = BP_CHECKBOX;
        result.m_state = determineState(o);
        result.m_classicState = DFCS_BUTTONCHECK;
        break;
    case RadioPart:
        result.m_part = BP_RADIOBUTTON;
        result.m_state = determineState(o);
        result.m_classicState = DFCS_BUTTONRADIO;
        break;
    case SquareButtonPart:
    case PushButtonPart:
    case ButtonPart:
        result.m_part = BP_PUSHBUTTON;
        result.m_state = determineState(o);
        result.m_classicState = DFCS_BUTTONPUSH;
        break;
    case SliderHorizontalPart:
        result.m_part = TKP_TRACK;
        result.m_state = TRS_NORMAL;
        break;
    case SliderVerticalPart:
        result.m_part = TKP_TRACKVERT;
        result.m_state = TRVS_NORMAL;
        break;
    case SliderThumbHorizontalPart:
        result.m_part = TKP_THUMBBOTTOM;
        result.m_state = determineSliderThumbState(o);
        break;
    case SliderThumbVerticalPart:
        result.m_part = TKP_THUMBVERT;
        result.m_state = determineSliderThumbState(o);
        break;
    case ListboxPart:
    case MenulistPart:
    case MenulistButtonPart:
    case SearchFieldPart:
    case TextFieldPart:
    case TextAreaPart:
        result.m_part = EP_EDITTEXT;
        result.m_state = determineState(o);
        break;
    case InnerSpinButtonPart:
        result.m_part = subPart == SpinButtonUp ? SPNP_UP : SPNP_DOWN;
        result.m_state = determineState(o, subPart);
        result.m_classicState = subPart == SpinButtonUp ? DFCS_SCROLLUP : DFCS_SCROLLDOWN;
        break;
    }

    result.m_classicState |= determineClassicState(o, subPart);

    return result;
}

bool RenderThemeChromiumWin::paintTextFieldInternal(RenderObject* o,
                                                    const PaintInfo& i,
                                                    const IntRect& r,
                                                    bool drawEdges)
{
    // Fallback to white if the specified color object is invalid.
    Color backgroundColor(Color::white);
    if (o->style()->visitedDependentColor(CSSPropertyBackgroundColor).isValid())
        backgroundColor = o->style()->visitedDependentColor(CSSPropertyBackgroundColor);

    // If we have background-image, don't fill the content area to expose the
    // parent's background. Also, we shouldn't fill the content area if the
    // alpha of the color is 0. The API of Windows GDI ignores the alpha.
    //
    // Note that we should paint the content area white if we have neither the
    // background color nor background image explicitly specified to keep the
    // appearance of select element consistent with other browsers.
    bool fillContentArea = !o->style()->hasBackgroundImage() && backgroundColor.alpha();

    if (o->style()->hasBorderRadius()) {
        // If the style has rounded borders, setup the context to clip the
        // background (themed or filled) appropriately.
        // FIXME: make sure we do the right thing if css background-clip is set.
        i.context->save();
        i.context->clipRoundedRect(o->style()->getRoundedBorderFor(r));
    }
    {
        const ThemeData& themeData = getThemeData(o);
        ThemePainter painter(i.context, r);
        WebKit::WebCanvas* canvas = painter.context()->canvas();
        WebKit::Platform::current()->themeEngine()->paintTextField(canvas, themeData.m_part, themeData.m_state, themeData.m_classicState, WebKit::WebRect(painter.drawRect()), backgroundColor.rgb(), fillContentArea, drawEdges);
        // End of block commits the painter before restoring context.
    }
    if (o->style()->hasBorderRadius())
        i.context->restore();
    return false;
}

void RenderThemeChromiumWin::adjustInnerSpinButtonStyle(RenderStyle* style, Element*) const
{
    int width = ScrollbarTheme::theme()->scrollbarThickness();
    style->setWidth(Length(width, Fixed));
    style->setMinWidth(Length(width, Fixed));
}

bool RenderThemeChromiumWin::paintInnerSpinButton(RenderObject* object, const PaintInfo& info, const IntRect& rect)
{
    IntRect half = rect;

    // Need explicit blocks to avoid to create multiple ThemePainter instances.
    {
        half.setHeight(rect.height() / 2);
        const ThemeData& upThemeData = getThemeData(object, SpinButtonUp);
        ThemePainter upPainter(info.context, half);
        WebKit::WebCanvas* canvas = upPainter.context()->canvas();
        WebKit::Platform::current()->themeEngine()->paintSpinButton(canvas, upThemeData.m_part, upThemeData.m_state, upThemeData.m_classicState, WebKit::WebRect(upPainter.drawRect()));
    }

    {
        half.setY(rect.y() + rect.height() / 2);
        const ThemeData& downThemeData = getThemeData(object, SpinButtonDown);
        ThemePainter downPainter(info.context, half);
        WebKit::WebCanvas* canvas = downPainter.context()->canvas();
        WebKit::Platform::current()->themeEngine()->paintSpinButton(canvas, downThemeData.m_part, downThemeData.m_state, downThemeData.m_classicState, WebKit::WebRect(downPainter.drawRect()));
    }
    return false;
}

// MSDN says that update intervals for the bar is 30ms.
// http://msdn.microsoft.com/en-us/library/bb760842(v=VS.85).aspx
static const double progressAnimationFrameRate = 0.033;

double RenderThemeChromiumWin::animationRepeatIntervalForProgressBar(RenderProgress*) const
{
    return progressAnimationFrameRate;
}

double RenderThemeChromiumWin::animationDurationForProgressBar(RenderProgress* renderProgress) const
{
    // On Chromium Windows port, animationProgress() and associated values aren't used.
    // So here we can return arbitrary positive value.
    return progressAnimationFrameRate;
}

void RenderThemeChromiumWin::adjustProgressBarStyle(RenderStyle*, Element*) const
{
}

bool RenderThemeChromiumWin::paintProgressBar(RenderObject* o, const PaintInfo& i, const IntRect& r)
{
    if (!o->isProgress())
        return true;

    RenderProgress* renderProgress = toRenderProgress(o);
    // For indeterminate bar, valueRect is ignored and it is computed by the theme engine
    // because the animation is a platform detail and WebKit doesn't need to know how.
    IntRect valueRect = renderProgress->isDeterminate() ? determinateProgressValueRectFor(renderProgress, r) : IntRect(0, 0, 0, 0);
    double animatedSeconds = renderProgress->animationStartTime() ?  WTF::currentTime() - renderProgress->animationStartTime() : 0;
    ThemePainter painter(i.context, r);
    DirectionFlippingScope scope(o, i, r);
    WebKit::WebCanvas* canvas = painter.context()->canvas();
    WebKit::Platform::current()->themeEngine()->paintProgressBar(canvas, WebKit::WebRect(r), WebKit::WebRect(valueRect), renderProgress->isDeterminate(), animatedSeconds);
    return false;
}

bool RenderThemeChromiumWin::shouldOpenPickerWithF4Key() const
{
    return true;
}

bool RenderThemeChromiumWin::shouldUseFallbackTheme(RenderStyle* style) const
{
    ControlPart part = style->appearance();
    if (part == CheckboxPart || part == RadioPart)
        return style->effectiveZoom() != 1;
    return false;
}

} // namespace WebCore
