// Copyright (c) 2012 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 "ui/views/controls/menu/menu_image_util.h"

#include "base/i18n/rtl.h"
#include "base/logging.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/image/image_skia_source.h"
#include "ui/gfx/point.h"
#include "ui/gfx/size.h"
#include "ui/resources/grit/ui_resources.h"

namespace {

// Size of the radio button inciator.
const int kSelectedIndicatorSize = 5;
const int kIndicatorSize = 10;

// Used for the radio indicator. See theme_draw for details.
const double kGradientStop = .5;
const SkColor kGradient0 = SkColorSetRGB(255, 255, 255);
const SkColor kGradient1 = SkColorSetRGB(255, 255, 255);
const SkColor kGradient2 = SkColorSetRGB(0xD8, 0xD8, 0xD8);
const SkColor kBaseStroke = SkColorSetRGB(0x8F, 0x8F, 0x8F);
const SkColor kRadioButtonIndicatorGradient0 = SkColorSetRGB(0, 0, 0);
const SkColor kRadioButtonIndicatorGradient1 = SkColorSetRGB(0x83, 0x83, 0x83);
const SkColor kIndicatorStroke = SkColorSetRGB(0, 0, 0);

class RadioButtonImageSource : public gfx::CanvasImageSource {
 public:
  explicit RadioButtonImageSource(bool selected)
      : CanvasImageSource(gfx::Size(kIndicatorSize + 2, kIndicatorSize + 2),
                          false),
        selected_(selected) {
  }
  virtual ~RadioButtonImageSource() {}

  virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
    canvas->Translate(gfx::Vector2d(1, 1));

    SkPoint gradient_points[3];
    gradient_points[0].iset(0, 0);
    gradient_points[1].iset(0,
                            static_cast<int>(kIndicatorSize * kGradientStop));
    gradient_points[2].iset(0, kIndicatorSize);
    SkColor gradient_colors[3] = { kGradient0, kGradient1, kGradient2 };
    skia::RefPtr<SkShader> shader = skia::AdoptRef(
        SkGradientShader::CreateLinear(
            gradient_points, gradient_colors, NULL, arraysize(gradient_points),
            SkShader::kClamp_TileMode));
    SkPaint paint;
    paint.setStyle(SkPaint::kFill_Style);
    paint.setAntiAlias(true);
    paint.setShader(shader.get());
    int radius = kIndicatorSize / 2;
    canvas->sk_canvas()->drawCircle(radius, radius, radius, paint);
    paint.setStrokeWidth(SkIntToScalar(0));
    paint.setShader(NULL);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(kBaseStroke);
    canvas->sk_canvas()->drawCircle(radius, radius, radius, paint);

    if (selected_) {
      SkPoint selected_gradient_points[2];
      selected_gradient_points[0].iset(0, 0);
      selected_gradient_points[1].iset(0, kSelectedIndicatorSize);
      SkColor selected_gradient_colors[2] = { kRadioButtonIndicatorGradient0,
                                              kRadioButtonIndicatorGradient1 };
      shader = skia::AdoptRef(
          SkGradientShader::CreateLinear(
              selected_gradient_points, selected_gradient_colors, NULL,
              arraysize(selected_gradient_points), SkShader::kClamp_TileMode));
      paint.setShader(shader.get());
      paint.setStyle(SkPaint::kFill_Style);
      canvas->sk_canvas()->drawCircle(radius, radius,
                                      kSelectedIndicatorSize / 2, paint);

      paint.setStrokeWidth(SkIntToScalar(0));
      paint.setShader(NULL);
      paint.setStyle(SkPaint::kStroke_Style);
      paint.setColor(kIndicatorStroke);
      canvas->sk_canvas()->drawCircle(radius, radius,
                                      kSelectedIndicatorSize / 2, paint);
    }
  }

 private:
  bool selected_;

  DISALLOW_COPY_AND_ASSIGN(RadioButtonImageSource);
};

class SubmenuArrowImageSource : public gfx::CanvasImageSource {
 public:
  SubmenuArrowImageSource(int image_id)
      : gfx::CanvasImageSource(ui::ResourceBundle::GetSharedInstance().
            GetImageNamed(image_id).ToImageSkia()->size(), false),
        image_id_(image_id) {}
  virtual ~SubmenuArrowImageSource() {}

  virtual void Draw(gfx::Canvas* canvas) OVERRIDE {
    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
    const gfx::ImageSkia* r = rb.GetImageNamed(image_id_).ToImageSkia();
    canvas->Scale(-1, 1);
    canvas->DrawImageInt(*r, - r->width(), 0);
  }

 private:
  static gfx::Size GetSubmenuArrowSize() {
    return ui::ResourceBundle::GetSharedInstance()
        .GetImageNamed(IDR_MENU_HIERARCHY_ARROW).ToImageSkia()->size();
  }

  int image_id_;

  DISALLOW_COPY_AND_ASSIGN(SubmenuArrowImageSource);
};

gfx::ImageSkia GetRtlSubmenuArrowImage(bool rtl,
                                       bool dark_background) {
  int image_id = dark_background ? IDR_MENU_HIERARCHY_ARROW_DARK_BACKGROUND :
                                   IDR_MENU_HIERARCHY_ARROW;

  if (!rtl) {
    return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
        AsImageSkia();
  }

  static gfx::ImageSkia* kRtlArrow = NULL;
  static gfx::ImageSkia* kRtlArrowDarkBg = NULL;
  gfx::ImageSkia** image = dark_background ? &kRtlArrowDarkBg : &kRtlArrow;

  if (!*image) {
    SubmenuArrowImageSource* source = new SubmenuArrowImageSource(image_id);
    *image = new gfx::ImageSkia(source, source->size());
  }

  return **image;
}

}  // namespace

namespace views {

gfx::ImageSkia GetMenuCheckImage(bool dark_background) {
  int image_id = dark_background ? IDR_MENU_CHECK_CHECKED_DARK_BACKGROUND :
                                   IDR_MENU_CHECK_CHECKED;
  return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
      AsImageSkia();
}

gfx::ImageSkia GetRadioButtonImage(bool selected) {
  int image_id = selected ? IDR_MENU_RADIO_SELECTED : IDR_MENU_RADIO_EMPTY;
  return ui::ResourceBundle::GetSharedInstance().GetImageNamed(image_id).
      AsImageSkia();
}

gfx::ImageSkia GetSubmenuArrowImage(bool dark_background) {
  return GetRtlSubmenuArrowImage(base::i18n::IsRTL(), dark_background);
}

}  // namespace views
