// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "gfx/native_theme_win.h"

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

#include "base/logging.h"
#include "base/scoped_handle.h"
#include "base/win/windows_version.h"
#include "gfx/gdi_util.h"
#include "gfx/rect.h"
#include "skia/ext/platform_canvas.h"
#include "skia/ext/skia_utils_win.h"
#include "third_party/skia/include/core/SkShader.h"

namespace {

void SetCheckerboardShader(SkPaint* paint, const RECT& align_rect) {
  // Create a 2x2 checkerboard pattern using the 3D face and highlight colors.
  SkColor face = skia::COLORREFToSkColor(GetSysColor(COLOR_3DFACE));
  SkColor highlight = skia::COLORREFToSkColor(GetSysColor(COLOR_3DHILIGHT));
  SkColor buffer[] = { face, highlight, highlight, face };
  // Confusing bit: we first create a temporary bitmap with our desired pattern,
  // then copy it to another bitmap.  The temporary bitmap doesn't take
  // ownership of the pixel data, and so will point to garbage when this
  // function returns.  The copy will copy the pixel data into a place owned by
  // the bitmap, which is in turn owned by the shader, etc., so it will live
  // until we're done using it.
  SkBitmap temp_bitmap;
  temp_bitmap.setConfig(SkBitmap::kARGB_8888_Config, 2, 2);
  temp_bitmap.setPixels(buffer);
  SkBitmap bitmap;
  temp_bitmap.copyTo(&bitmap, temp_bitmap.config());
  SkShader* shader = SkShader::CreateBitmapShader(bitmap,
                                                  SkShader::kRepeat_TileMode,
                                                  SkShader::kRepeat_TileMode);

  // Align the pattern with the upper corner of |align_rect|.
  SkMatrix matrix;
  matrix.setTranslate(SkIntToScalar(align_rect.left),
                      SkIntToScalar(align_rect.top));
  shader->setLocalMatrix(matrix);
  SkSafeUnref(paint->setShader(shader));
}

}  // namespace

namespace gfx {

/* static */
const NativeTheme* NativeTheme::instance() {
  // The global NativeTheme instance.
  static const NativeTheme s_native_theme;
  return &s_native_theme;
}

NativeTheme::NativeTheme()
    : theme_dll_(LoadLibrary(L"uxtheme.dll")),
      draw_theme_(NULL),
      draw_theme_ex_(NULL),
      get_theme_color_(NULL),
      get_theme_content_rect_(NULL),
      get_theme_part_size_(NULL),
      open_theme_(NULL),
      close_theme_(NULL),
      set_theme_properties_(NULL),
      is_theme_active_(NULL),
      get_theme_int_(NULL) {
  if (theme_dll_) {
    draw_theme_ = reinterpret_cast<DrawThemeBackgroundPtr>(
        GetProcAddress(theme_dll_, "DrawThemeBackground"));
    draw_theme_ex_ = reinterpret_cast<DrawThemeBackgroundExPtr>(
        GetProcAddress(theme_dll_, "DrawThemeBackgroundEx"));
    get_theme_color_ = reinterpret_cast<GetThemeColorPtr>(
        GetProcAddress(theme_dll_, "GetThemeColor"));
    get_theme_content_rect_ = reinterpret_cast<GetThemeContentRectPtr>(
        GetProcAddress(theme_dll_, "GetThemeBackgroundContentRect"));
    get_theme_part_size_ = reinterpret_cast<GetThemePartSizePtr>(
        GetProcAddress(theme_dll_, "GetThemePartSize"));
    open_theme_ = reinterpret_cast<OpenThemeDataPtr>(
        GetProcAddress(theme_dll_, "OpenThemeData"));
    close_theme_ = reinterpret_cast<CloseThemeDataPtr>(
        GetProcAddress(theme_dll_, "CloseThemeData"));
    set_theme_properties_ = reinterpret_cast<SetThemeAppPropertiesPtr>(
        GetProcAddress(theme_dll_, "SetThemeAppProperties"));
    is_theme_active_ = reinterpret_cast<IsThemeActivePtr>(
        GetProcAddress(theme_dll_, "IsThemeActive"));
    get_theme_int_ = reinterpret_cast<GetThemeIntPtr>(
        GetProcAddress(theme_dll_, "GetThemeInt"));
  }
  memset(theme_handles_, 0, sizeof(theme_handles_));
}

NativeTheme::~NativeTheme() {
  if (theme_dll_) {
    // todo (cpu): fix this soon.
    // CloseHandles();
    FreeLibrary(theme_dll_);
  }
}

HRESULT NativeTheme::PaintButton(HDC hdc,
                                 int part_id,
                                 int state_id,
                                 int classic_state,
                                 RECT* rect) const {
  HANDLE handle = GetThemeHandle(BUTTON);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);

  // Draw it manually.
  // All pressed states have both low bits set, and no other states do.
  const bool focused = ((state_id & ETS_FOCUSED) == ETS_FOCUSED);
  const bool pressed = ((state_id & PBS_PRESSED) == PBS_PRESSED);
  if ((BP_PUSHBUTTON == part_id) && (pressed || focused)) {
    // BP_PUSHBUTTON has a focus rect drawn around the outer edge, and the
    // button itself is shrunk by 1 pixel.
    HBRUSH brush = GetSysColorBrush(COLOR_3DDKSHADOW);
    if (brush) {
      FrameRect(hdc, rect, brush);
      InflateRect(rect, -1, -1);
    }
  }
  DrawFrameControl(hdc, rect, DFC_BUTTON, classic_state);

  // Draw the focus rectangle (the dotted line box) only on buttons.  For radio
  // and checkboxes, we let webkit draw the focus rectangle (orange glow).
  if ((BP_PUSHBUTTON == part_id) && focused) {
    // The focus rect is inside the button.  The exact number of pixels depends
    // on whether we're in classic mode or using uxtheme.
    if (handle && get_theme_content_rect_) {
      get_theme_content_rect_(handle, hdc, part_id, state_id, rect, rect);
    } else {
      InflateRect(rect, -GetSystemMetrics(SM_CXEDGE),
                  -GetSystemMetrics(SM_CYEDGE));
    }
    DrawFocusRect(hdc, rect);
  }

  return S_OK;
}

HRESULT NativeTheme::PaintDialogBackground(HDC hdc, bool active,
                                           RECT* rect) const {
  HANDLE handle = GetThemeHandle(WINDOW);
  if (handle && draw_theme_) {
    return draw_theme_(handle, hdc, WP_DIALOG,
                       active ? FS_ACTIVE : FS_INACTIVE, rect, NULL);
  }

  // Classic just renders a flat color background.
  FillRect(hdc, rect, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1));
  return S_OK;
}

HRESULT NativeTheme::PaintListBackground(HDC hdc,
                                         bool enabled,
                                         RECT* rect) const {
  HANDLE handle = GetThemeHandle(LIST);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, 1, TS_NORMAL, rect, NULL);

  // Draw it manually.
  HBRUSH bg_brush = GetSysColorBrush(COLOR_WINDOW);
  FillRect(hdc, rect, bg_brush);
  DrawEdge(hdc, rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  return S_OK;
}

HRESULT NativeTheme::PaintMenuArrow(ThemeName theme,
                                    HDC hdc,
                                    int part_id,
                                    int state_id,
                                    RECT* rect,
                                    MenuArrowDirection arrow_direction,
                                    ControlState control_state) const {
  HANDLE handle = GetThemeHandle(MENU);
  if (handle && draw_theme_) {
    if (arrow_direction == RIGHT_POINTING_ARROW) {
      return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
    } else {
      // There is no way to tell the uxtheme API to draw a left pointing arrow;
      // it doesn't have a flag equivalent to DFCS_MENUARROWRIGHT.  But they
      // are needed for RTL locales on Vista.  So use a memory DC and mirror
      // the region with GDI's StretchBlt.
      Rect r(*rect);
      ScopedHDC mem_dc(CreateCompatibleDC(hdc));
      ScopedBitmap mem_bitmap(CreateCompatibleBitmap(hdc, r.width(),
                                                     r.height()));
      HGDIOBJ old_bitmap = SelectObject(mem_dc, mem_bitmap);
      // Copy and horizontally mirror the background from hdc into mem_dc. Use
      // a negative-width source rect, starting at the rightmost pixel.
      StretchBlt(mem_dc, 0, 0, r.width(), r.height(),
                 hdc, r.right()-1, r.y(), -r.width(), r.height(), SRCCOPY);
      // Draw the arrow.
      RECT theme_rect = {0, 0, r.width(), r.height()};
      HRESULT result = draw_theme_(handle, mem_dc, part_id,
                                   state_id, &theme_rect, NULL);
      // Copy and mirror the result back into mem_dc.
      StretchBlt(hdc, r.x(), r.y(), r.width(), r.height(),
                 mem_dc, r.width()-1, 0, -r.width(), r.height(), SRCCOPY);
      SelectObject(mem_dc, old_bitmap);
      return result;
    }
  }

  // For some reason, Windows uses the name DFCS_MENUARROWRIGHT to indicate a
  // left pointing arrow. This makes the following 'if' statement slightly
  // counterintuitive.
  UINT state;
  if (arrow_direction == RIGHT_POINTING_ARROW)
    state = DFCS_MENUARROW;
  else
    state = DFCS_MENUARROWRIGHT;
  return PaintFrameControl(hdc, rect, DFC_MENU, state, control_state);
}

HRESULT NativeTheme::PaintMenuBackground(ThemeName theme,
                                         HDC hdc,
                                         int part_id,
                                         int state_id,
                                         RECT* rect) const {
  HANDLE handle = GetThemeHandle(MENU);
  if (handle && draw_theme_) {
    HRESULT result = draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
    FrameRect(hdc, rect, GetSysColorBrush(COLOR_3DSHADOW));
    return result;
  }

  FillRect(hdc, rect, GetSysColorBrush(COLOR_MENU));
  DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT);
  return S_OK;
}

HRESULT NativeTheme::PaintMenuCheckBackground(ThemeName theme,
                                              HDC hdc,
                                              int part_id,
                                              int state_id,
                                              RECT* rect) const {
  HANDLE handle = GetThemeHandle(MENU);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
  // Nothing to do for background.
  return S_OK;
}

HRESULT NativeTheme::PaintMenuCheck(ThemeName theme,
                                    HDC hdc,
                                    int part_id,
                                    int state_id,
                                    RECT* rect,
                                    ControlState control_state) const {
  HANDLE handle = GetThemeHandle(MENU);
  if (handle && draw_theme_) {
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
  }
  return PaintFrameControl(hdc, rect, DFC_MENU, DFCS_MENUCHECK, control_state);
}

HRESULT NativeTheme::PaintMenuGutter(HDC hdc,
                                     int part_id,
                                     int state_id,
                                     RECT* rect) const {
  HANDLE handle = GetThemeHandle(MENU);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
  return E_NOTIMPL;
}

HRESULT NativeTheme::PaintMenuItemBackground(ThemeName theme,
                                             HDC hdc,
                                             int part_id,
                                             int state_id,
                                             bool selected,
                                             RECT* rect) const {
  HANDLE handle = GetThemeHandle(MENU);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
  if (selected)
    FillRect(hdc, rect, GetSysColorBrush(COLOR_HIGHLIGHT));
  return S_OK;
}

HRESULT NativeTheme::PaintMenuList(HDC hdc,
                                   int part_id,
                                   int state_id,
                                   int classic_state,
                                   RECT* rect) const {
  HANDLE handle = GetThemeHandle(MENULIST);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);

  // Draw it manually.
  DrawFrameControl(hdc, rect, DFC_SCROLL, DFCS_SCROLLCOMBOBOX | classic_state);
  return S_OK;
}

HRESULT NativeTheme::PaintMenuSeparator(HDC hdc,
                                        int part_id,
                                        int state_id,
                                        RECT* rect) const {
  HANDLE handle = GetThemeHandle(MENU);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
  DrawEdge(hdc, rect, EDGE_ETCHED, BF_TOP);
  return S_OK;
}

HRESULT NativeTheme::PaintScrollbarArrow(HDC hdc,
                                         int state_id,
                                         int classic_state,
                                         RECT* rect) const {
  HANDLE handle = GetThemeHandle(SCROLLBAR);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, SBP_ARROWBTN, state_id, rect, NULL);

  // Draw it manually.
  DrawFrameControl(hdc, rect, DFC_SCROLL, classic_state);
  return S_OK;
}

HRESULT NativeTheme::PaintScrollbarTrack(
    HDC hdc,
    int part_id,
    int state_id,
    int classic_state,
    RECT* target_rect,
    RECT* align_rect,
    skia::PlatformCanvas* canvas) const {
  HANDLE handle = GetThemeHandle(SCROLLBAR);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, target_rect, NULL);

  // Draw it manually.
  const DWORD colorScrollbar = GetSysColor(COLOR_SCROLLBAR);
  const DWORD color3DFace = GetSysColor(COLOR_3DFACE);
  if ((colorScrollbar != color3DFace) &&
      (colorScrollbar != GetSysColor(COLOR_WINDOW))) {
    FillRect(hdc, target_rect, reinterpret_cast<HBRUSH>(COLOR_SCROLLBAR + 1));
  } else {
    SkPaint paint;
    SetCheckerboardShader(&paint, *align_rect);
    canvas->drawIRect(skia::RECTToSkIRect(*target_rect), paint);
  }
  if (classic_state & DFCS_PUSHED)
    InvertRect(hdc, target_rect);
  return S_OK;
}

HRESULT NativeTheme::PaintScrollbarThumb(HDC hdc,
                                         int part_id,
                                         int state_id,
                                         int classic_state,
                                         RECT* rect) const {
  HANDLE handle = GetThemeHandle(SCROLLBAR);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);

  // Draw it manually.
  if ((part_id == SBP_THUMBBTNHORZ) || (part_id == SBP_THUMBBTNVERT))
    DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT | BF_MIDDLE);
  // Classic mode doesn't have a gripper.
  return S_OK;
}

HRESULT NativeTheme::PaintSpinButton(HDC hdc,
                                     int part_id,
                                     int state_id,
                                     int classic_state,
                                     RECT* rect) const {
  HANDLE handle = GetThemeHandle(SPIN);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
  DrawFrameControl(hdc, rect, DFC_SCROLL, classic_state);
  return S_OK;
}

HRESULT NativeTheme::PaintStatusGripper(HDC hdc,
                                        int part_id,
                                        int state_id,
                                        int classic_state,
                                        RECT* rect) const {
  HANDLE handle = GetThemeHandle(STATUS);
  if (handle && draw_theme_) {
    // Paint the status bar gripper.  There doesn't seem to be a
    // standard gripper in Windows for the space between
    // scrollbars.  This is pretty close, but it's supposed to be
    // painted over a status bar.
    return draw_theme_(handle, hdc, SP_GRIPPER, 0, rect, NULL);
  }

  // Draw a windows classic scrollbar gripper.
  DrawFrameControl(hdc, rect, DFC_SCROLL, DFCS_SCROLLSIZEGRIP);
  return S_OK;
}

HRESULT NativeTheme::PaintTabPanelBackground(HDC hdc, RECT* rect) const {
  HANDLE handle = GetThemeHandle(TAB);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, TABP_BODY, 0, rect, NULL);

  // Classic just renders a flat color background.
  FillRect(hdc, rect, reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1));
  return S_OK;
}

HRESULT NativeTheme::PaintTrackbar(HDC hdc,
                                   int part_id,
                                   int state_id,
                                   int classic_state,
                                   RECT* rect,
                                   skia::PlatformCanvas* canvas) const {
  // Make the channel be 4 px thick in the center of the supplied rect.  (4 px
  // matches what XP does in various menus; GetThemePartSize() doesn't seem to
  // return good values here.)
  RECT channel_rect = *rect;
  const int channel_thickness = 4;
  if (part_id == TKP_TRACK) {
    channel_rect.top +=
        ((channel_rect.bottom - channel_rect.top - channel_thickness) / 2);
    channel_rect.bottom = channel_rect.top + channel_thickness;
  } else if (part_id == TKP_TRACKVERT) {
    channel_rect.left +=
        ((channel_rect.right - channel_rect.left - channel_thickness) / 2);
    channel_rect.right = channel_rect.left + channel_thickness;
  }  // else this isn't actually a channel, so |channel_rect| == |rect|.

  HANDLE handle = GetThemeHandle(TRACKBAR);
  if (handle && draw_theme_)
    return draw_theme_(handle, hdc, part_id, state_id, &channel_rect, NULL);

  // Classic mode, draw it manually.
  if ((part_id == TKP_TRACK) || (part_id == TKP_TRACKVERT)) {
    DrawEdge(hdc, &channel_rect, EDGE_SUNKEN, BF_RECT);
  } else if (part_id == TKP_THUMBVERT) {
    DrawEdge(hdc, rect, EDGE_RAISED, BF_RECT | BF_SOFT | BF_MIDDLE);
  } else {
    // Split rect into top and bottom pieces.
    RECT top_section = *rect;
    RECT bottom_section = *rect;
    top_section.bottom -= ((bottom_section.right - bottom_section.left) / 2);
    bottom_section.top = top_section.bottom;
    DrawEdge(hdc, &top_section, EDGE_RAISED,
             BF_LEFT | BF_TOP | BF_RIGHT | BF_SOFT | BF_MIDDLE | BF_ADJUST);

    // Split triangular piece into two diagonals.
    RECT& left_half = bottom_section;
    RECT right_half = bottom_section;
    right_half.left += ((bottom_section.right - bottom_section.left) / 2);
    left_half.right = right_half.left;
    DrawEdge(hdc, &left_half, EDGE_RAISED,
             BF_DIAGONAL_ENDTOPLEFT | BF_SOFT | BF_MIDDLE | BF_ADJUST);
    DrawEdge(hdc, &right_half, EDGE_RAISED,
             BF_DIAGONAL_ENDBOTTOMLEFT | BF_SOFT | BF_MIDDLE | BF_ADJUST);

    // If the button is pressed, draw hatching.
    if (classic_state & DFCS_PUSHED) {
      SkPaint paint;
      SetCheckerboardShader(&paint, *rect);

      // Fill all three pieces with the pattern.
      canvas->drawIRect(skia::RECTToSkIRect(top_section), paint);

      SkScalar left_triangle_top = SkIntToScalar(left_half.top);
      SkScalar left_triangle_right = SkIntToScalar(left_half.right);
      SkPath left_triangle;
      left_triangle.moveTo(SkIntToScalar(left_half.left), left_triangle_top);
      left_triangle.lineTo(left_triangle_right, left_triangle_top);
      left_triangle.lineTo(left_triangle_right,
                           SkIntToScalar(left_half.bottom));
      left_triangle.close();
      canvas->drawPath(left_triangle, paint);

      SkScalar right_triangle_left = SkIntToScalar(right_half.left);
      SkScalar right_triangle_top = SkIntToScalar(right_half.top);
      SkPath right_triangle;
      right_triangle.moveTo(right_triangle_left, right_triangle_top);
      right_triangle.lineTo(SkIntToScalar(right_half.right),
                            right_triangle_top);
      right_triangle.lineTo(right_triangle_left,
                            SkIntToScalar(right_half.bottom));
      right_triangle.close();
      canvas->drawPath(right_triangle, paint);
    }
  }
  return S_OK;
}

//    <-a->
// [  *****             ]
//  ____ |              |
//  <-a-> <------b----->
// a: object_width
// b: frame_width
// *: animating object
//
// - the animation goes from "[" to "]" repeatedly.
// - the animation offset is at first "|"
//
static int ComputeAnimationProgress(int frame_width,
                                    int object_width,
                                    int pixels_per_second,
                                    double animated_seconds) {
  int animation_width = frame_width + object_width;
  double interval = static_cast<double>(animation_width) / pixels_per_second;
  double ratio = fmod(animated_seconds, interval) / interval;
  return static_cast<int>(animation_width * ratio) - object_width;
}

static RECT InsetRect(const RECT* rect, int size) {
  gfx::Rect result(*rect);
  result.Inset(size, size);
  return result.ToRECT();
}

HRESULT NativeTheme::PaintProgressBar(HDC hdc,
                                      RECT* bar_rect,
                                      RECT* value_rect,
                                      bool determinate,
                                      double animated_seconds,
                                      skia::PlatformCanvas* canvas) const {
  // There is no documentation about the animation speed, frame-rate, nor
  // size of moving overlay of the indeterminate progress bar.
  // So we just observed real-world programs and guessed following parameters.
  const int kDeteminateOverlayPixelsPerSecond = 300;
  const int kDeteminateOverlayWidth = 120;
  const int kIndeterminateOverlayPixelsPerSecond =  175;
  const int kVistaIndeterminateOverlayWidth = 120;
  const int kXPIndeterminateOverlayWidth = 55;
  // The thickness of the bar frame inside |value_rect|
  const int kXPBarPadding = 3;

  bool pre_vista = base::win::GetVersion() < base::win::VERSION_VISTA;
  HANDLE handle = GetThemeHandle(PROGRESS);
  if (handle && draw_theme_ && draw_theme_ex_) {
    draw_theme_(handle, hdc, PP_BAR, 0, bar_rect, NULL);

    int bar_width = bar_rect->right - bar_rect->left;
    if (determinate) {
      // TODO(morrita): this RTL guess can be wrong.
      // We should pass the direction from WebKit side.
      bool is_rtl = (bar_rect->right == value_rect->right &&
                     bar_rect->left != value_rect->left);
      // We should care the direction here because PP_CNUNK painting
      // is asymmetric.
      DTBGOPTS value_draw_options;
      value_draw_options.dwSize = sizeof(DTBGOPTS);
      value_draw_options.dwFlags = is_rtl ? DTBG_MIRRORDC : 0;
      value_draw_options.rcClip = *bar_rect;

      if (pre_vista) {
        // On XP, progress bar is chunk-style and has no glossy effect.
        // We need to shrink destination rect to fit the part inside the bar
        // with an appropriate margin.
        RECT shrunk_value_rect = InsetRect(value_rect, kXPBarPadding);
        draw_theme_ex_(handle, hdc, PP_CHUNK, 0,
                       &shrunk_value_rect, &value_draw_options);
      } else  {
        // On Vista or later, the progress bar part has a
        // single-block value part. It also has glossy effect.
        // And the value part has exactly same height as the bar part
        // so we don't need to shrink the rect.
        draw_theme_ex_(handle, hdc, PP_FILL, 0,
                       value_rect, &value_draw_options);

        int dx = ComputeAnimationProgress(bar_width,
                                          kDeteminateOverlayWidth,
                                          kDeteminateOverlayPixelsPerSecond,
                                          animated_seconds);
        RECT overlay_rect = *value_rect;
        overlay_rect.left += dx;
        overlay_rect.right = overlay_rect.left + kDeteminateOverlayWidth;
        draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, value_rect);
      }
    } else {
      // A glossy overlay for indeterminate progress bar has small pause
      // after each animation. We emulate this by adding an invisible margin
      // the animation has to traverse.
      int width_with_margin = bar_width + kIndeterminateOverlayPixelsPerSecond;
      int overlay_width = pre_vista ?
          kXPIndeterminateOverlayWidth : kVistaIndeterminateOverlayWidth;
      int dx = ComputeAnimationProgress(width_with_margin,
                                        overlay_width,
                                        kIndeterminateOverlayPixelsPerSecond,
                                        animated_seconds);
      RECT overlay_rect = *bar_rect;
      overlay_rect.left += dx;
      overlay_rect.right = overlay_rect.left + overlay_width;
      if (pre_vista) {
        RECT shrunk_rect = InsetRect(&overlay_rect, kXPBarPadding);
        RECT shrunk_bar_rect = InsetRect(bar_rect, kXPBarPadding);
        draw_theme_(handle, hdc, PP_CHUNK, 0, &shrunk_rect, &shrunk_bar_rect);
      } else {
        draw_theme_(handle, hdc, PP_MOVEOVERLAY, 0, &overlay_rect, bar_rect);
      }
    }

    return S_OK;
  }

  HBRUSH bg_brush = GetSysColorBrush(COLOR_BTNFACE);
  HBRUSH fg_brush = GetSysColorBrush(COLOR_BTNSHADOW);
  FillRect(hdc, bar_rect, bg_brush);
  FillRect(hdc, value_rect, fg_brush);
  DrawEdge(hdc, bar_rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);
  return S_OK;
}

HRESULT NativeTheme::PaintTextField(HDC hdc,
                                    int part_id,
                                    int state_id,
                                    int classic_state,
                                    RECT* rect,
                                    COLORREF color,
                                    bool fill_content_area,
                                    bool draw_edges) const {
  // TODO(ojan): http://b/1210017 Figure out how to give the ability to
  // exclude individual edges from being drawn.

  HANDLE handle = GetThemeHandle(TEXTFIELD);
  // TODO(mpcomplete): can we detect if the color is specified by the user,
  // and if not, just use the system color?
  // CreateSolidBrush() accepts a RGB value but alpha must be 0.
  HBRUSH bg_brush = CreateSolidBrush(color);
  HRESULT hr;
  // DrawThemeBackgroundEx was introduced in XP SP2, so that it's possible
  // draw_theme_ex_ is NULL and draw_theme_ is non-null.
  if (handle && (draw_theme_ex_ || (draw_theme_ && draw_edges))) {
    if (draw_theme_ex_) {
      static DTBGOPTS omit_border_options = {
        sizeof(DTBGOPTS),
        DTBG_OMITBORDER,
        {0,0,0,0}
      };
      DTBGOPTS* draw_opts = draw_edges ? NULL : &omit_border_options;
      hr = draw_theme_ex_(handle, hdc, part_id, state_id, rect, draw_opts);
    } else {
      hr = draw_theme_(handle, hdc, part_id, state_id, rect, NULL);
    }

    // TODO(maruel): Need to be fixed if get_theme_content_rect_ is NULL.
    if (fill_content_area && get_theme_content_rect_) {
      RECT content_rect;
      hr = get_theme_content_rect_(handle, hdc, part_id, state_id, rect,
                                   &content_rect);
      FillRect(hdc, &content_rect, bg_brush);
    }
  } else {
    // Draw it manually.
    if (draw_edges)
      DrawEdge(hdc, rect, EDGE_SUNKEN, BF_RECT | BF_ADJUST);

    if (fill_content_area) {
      FillRect(hdc, rect, (classic_state & DFCS_INACTIVE) ?
                   reinterpret_cast<HBRUSH>(COLOR_BTNFACE + 1) : bg_brush);
    }
    hr = S_OK;
  }
  DeleteObject(bg_brush);
  return hr;
}

bool NativeTheme::IsThemingActive() const {
  if (is_theme_active_)
    return !!is_theme_active_();
  return false;
}

HRESULT NativeTheme::GetThemePartSize(ThemeName theme_name,
                                      HDC hdc,
                                      int part_id,
                                      int state_id,
                                      RECT* rect,
                                      int ts,
                                      SIZE* size) const {
  HANDLE handle = GetThemeHandle(theme_name);
  if (handle && get_theme_part_size_)
    return get_theme_part_size_(handle, hdc, part_id, state_id, rect, ts, size);

  return E_NOTIMPL;
}

HRESULT NativeTheme::GetThemeColor(ThemeName theme,
                                   int part_id,
                                   int state_id,
                                   int prop_id,
                                   SkColor* color) const {
  HANDLE handle = GetThemeHandle(theme);
  if (handle && get_theme_color_) {
    COLORREF color_ref;
    if (get_theme_color_(handle, part_id, state_id, prop_id, &color_ref) ==
        S_OK) {
      *color = skia::COLORREFToSkColor(color_ref);
      return S_OK;
    }
  }
  return E_NOTIMPL;
}

SkColor NativeTheme::GetThemeColorWithDefault(ThemeName theme,
                                              int part_id,
                                              int state_id,
                                              int prop_id,
                                              int default_sys_color) const {
  SkColor color;
  if (GetThemeColor(theme, part_id, state_id, prop_id, &color) != S_OK)
    color = skia::COLORREFToSkColor(GetSysColor(default_sys_color));
  return color;
}

HRESULT NativeTheme::GetThemeInt(ThemeName theme,
                                 int part_id,
                                 int state_id,
                                 int prop_id,
                                 int *value) const {
  HANDLE handle = GetThemeHandle(theme);
  if (handle && get_theme_int_)
    return get_theme_int_(handle, part_id, state_id, prop_id, value);
  return E_NOTIMPL;
}

Size NativeTheme::GetThemeBorderSize(ThemeName theme) const {
  // For simplicity use the wildcard state==0, part==0, since it works
  // for the cases we currently depend on.
  int border;
  if (GetThemeInt(theme, 0, 0, TMT_BORDERSIZE, &border) == S_OK)
    return Size(border, border);
  else
    return Size(GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
}


void NativeTheme::DisableTheming() const {
  if (!set_theme_properties_)
    return;
  set_theme_properties_(0);
}

HRESULT NativeTheme::PaintFrameControl(HDC hdc,
                                       RECT* rect,
                                       UINT type,
                                       UINT state,
                                       ControlState control_state) const {
  const int width = rect->right - rect->left;
  const int height = rect->bottom - rect->top;

  // DrawFrameControl for menu arrow/check wants a monochrome bitmap.
  ScopedBitmap mask_bitmap(CreateBitmap(width, height, 1, 1, NULL));

  if (mask_bitmap == NULL)
    return E_OUTOFMEMORY;

  ScopedHDC bitmap_dc(CreateCompatibleDC(NULL));
  HGDIOBJ org_bitmap = SelectObject(bitmap_dc, mask_bitmap);
  RECT local_rect = { 0, 0, width, height };
  DrawFrameControl(bitmap_dc, &local_rect, type, state);

  // We're going to use BitBlt with a b&w mask. This results in using the dest
  // dc's text color for the black bits in the mask, and the dest dc's
  // background color for the white bits in the mask. DrawFrameControl draws the
  // check in black, and the background in white.
  int bg_color_key;
  int text_color_key;
  switch (control_state) {
    case CONTROL_HIGHLIGHTED:
      bg_color_key = COLOR_HIGHLIGHT;
      text_color_key = COLOR_HIGHLIGHTTEXT;
      break;
    case CONTROL_NORMAL:
      bg_color_key = COLOR_MENU;
      text_color_key = COLOR_MENUTEXT;
      break;
    case CONTROL_DISABLED:
      bg_color_key = COLOR_MENU;
      text_color_key = COLOR_GRAYTEXT;
      break;
    default:
      NOTREACHED();
      bg_color_key = COLOR_MENU;
      text_color_key = COLOR_MENUTEXT;
      break;
  }
  COLORREF old_bg_color = SetBkColor(hdc, GetSysColor(bg_color_key));
  COLORREF old_text_color = SetTextColor(hdc, GetSysColor(text_color_key));
  BitBlt(hdc, rect->left, rect->top, width, height, bitmap_dc, 0, 0, SRCCOPY);
  SetBkColor(hdc, old_bg_color);
  SetTextColor(hdc, old_text_color);

  SelectObject(bitmap_dc, org_bitmap);

  return S_OK;
}

void NativeTheme::CloseHandles() const
{
  if (!close_theme_)
    return;

  for (int i = 0; i < LAST; ++i) {
    if (theme_handles_[i])
      close_theme_(theme_handles_[i]);
      theme_handles_[i] = NULL;
  }
}

bool NativeTheme::IsClassicTheme(ThemeName name) const {
  if (!theme_dll_)
    return true;

  return !GetThemeHandle(name);
}

HANDLE NativeTheme::GetThemeHandle(ThemeName theme_name) const
{
  if (!open_theme_ || theme_name < 0 || theme_name >= LAST)
    return 0;

  if (theme_handles_[theme_name])
    return theme_handles_[theme_name];

  // Not found, try to load it.
  HANDLE handle = 0;
  switch (theme_name) {
  case BUTTON:
    handle = open_theme_(NULL, L"Button");
    break;
  case LIST:
    handle = open_theme_(NULL, L"Listview");
    break;
  case MENU:
    handle = open_theme_(NULL, L"Menu");
    break;
  case MENULIST:
    handle = open_theme_(NULL, L"Combobox");
    break;
  case SCROLLBAR:
    handle = open_theme_(NULL, L"Scrollbar");
    break;
  case STATUS:
    handle = open_theme_(NULL, L"Status");
    break;
  case TAB:
    handle = open_theme_(NULL, L"Tab");
    break;
  case TEXTFIELD:
    handle = open_theme_(NULL, L"Edit");
    break;
  case TRACKBAR:
    handle = open_theme_(NULL, L"Trackbar");
    break;
  case WINDOW:
    handle = open_theme_(NULL, L"Window");
    break;
  case PROGRESS:
    handle = open_theme_(NULL, L"Progress");
    break;
  case SPIN:
    handle = open_theme_(NULL, L"Spin");
    break;
  default:
    NOTREACHED();
  }
  theme_handles_[theme_name] = handle;
  return handle;
}

}  // namespace gfx
