// Copyright 2014 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 "chrome/browser/profiles/profile_avatar_icon_util.h"

#include "base/file_util.h"
#include "base/format_macros.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/stringprintf.h"
#include "chrome/common/chrome_paths.h"
#include "grit/generated_resources.h"
#include "grit/theme_resources.h"
#include "skia/ext/image_operations.h"
#include "third_party/skia/include/core/SkPaint.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkScalar.h"
#include "third_party/skia/include/core/SkXfermode.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_operations.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/skia_util.h"

// Helper methods for transforming and drawing avatar icons.
namespace {

// Determine what the scaled height of the avatar icon should be for a
// specified width, to preserve the aspect ratio.
int GetScaledAvatarHeightForWidth(int width, const gfx::ImageSkia& avatar) {
  // Multiply the width by the inverted aspect ratio (height over
  // width), and then add 0.5 to ensure the int truncation rounds nicely.
  int scaled_height = width *
      ((float) avatar.height() / (float) avatar.width()) + 0.5f;
  return scaled_height;
}

// A CanvasImageSource that draws a sized and positioned avatar with an
// optional border independently of the scale factor.
class AvatarImageSource : public gfx::CanvasImageSource {
 public:
  enum AvatarPosition {
    POSITION_CENTER,
    POSITION_BOTTOM_CENTER,
  };

  enum AvatarBorder {
    BORDER_NONE,
    BORDER_NORMAL,
    BORDER_ETCHED,
  };

  AvatarImageSource(gfx::ImageSkia avatar,
                    const gfx::Size& canvas_size,
                    int width,
                    AvatarPosition position,
                    AvatarBorder border);
  virtual ~AvatarImageSource();

  // CanvasImageSource override:
  virtual void Draw(gfx::Canvas* canvas) OVERRIDE;

 private:
  gfx::ImageSkia avatar_;
  const gfx::Size canvas_size_;
  const int width_;
  const int height_;
  const AvatarPosition position_;
  const AvatarBorder border_;

  DISALLOW_COPY_AND_ASSIGN(AvatarImageSource);
};

AvatarImageSource::AvatarImageSource(gfx::ImageSkia avatar,
                                     const gfx::Size& canvas_size,
                                     int width,
                                     AvatarPosition position,
                                     AvatarBorder border)
    : gfx::CanvasImageSource(canvas_size, false),
      canvas_size_(canvas_size),
      width_(width),
      height_(GetScaledAvatarHeightForWidth(width, avatar)),
      position_(position),
      border_(border) {
  avatar_ = gfx::ImageSkiaOperations::CreateResizedImage(
      avatar, skia::ImageOperations::RESIZE_BEST,
      gfx::Size(width_, height_));
}

AvatarImageSource::~AvatarImageSource() {
}

void AvatarImageSource::Draw(gfx::Canvas* canvas) {
  // Center the avatar horizontally.
  int x = (canvas_size_.width() - width_) / 2;
  int y;

  if (position_ == POSITION_CENTER) {
    // Draw the avatar centered on the canvas.
    y = (canvas_size_.height() - height_) / 2;
  } else {
    // Draw the avatar on the bottom center of the canvas, leaving 1px below.
    y = canvas_size_.height() - height_ - 1;
  }

  canvas->DrawImageInt(avatar_, x, y);

  // The border should be square.
  int border_size = std::max(width_, height_);
  // Reset the x and y for the square border.
  x = (canvas_size_.width() - border_size) / 2;
  y = (canvas_size_.height() - border_size) / 2;

  if (border_ == BORDER_NORMAL) {
    // Draw a gray border on the inside of the avatar.
    SkColor border_color = SkColorSetARGB(83, 0, 0, 0);

    // Offset the rectangle by a half pixel so the border is drawn within the
    // appropriate pixels no matter the scale factor. Subtract 1 from the right
    // and bottom sizes to specify the endpoints, yielding -0.5.
    SkPath path;
    path.addRect(SkFloatToScalar(x + 0.5f),  // left
                 SkFloatToScalar(y + 0.5f),  // top
                 SkFloatToScalar(x + border_size - 0.5f),   // right
                 SkFloatToScalar(y + border_size - 0.5f));  // bottom

    SkPaint paint;
    paint.setColor(border_color);
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(SkIntToScalar(1));

    canvas->DrawPath(path, paint);
  } else if (border_ == BORDER_ETCHED) {
    // Give the avatar an etched look by drawing a highlight on the bottom and
    // right edges.
    SkColor shadow_color = SkColorSetARGB(83, 0, 0, 0);
    SkColor highlight_color = SkColorSetARGB(96, 255, 255, 255);

    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setStrokeWidth(SkIntToScalar(1));

    SkPath path;

    // Left and top shadows. To support higher scale factors than 1, position
    // the orthogonal dimension of each line on the half-pixel to separate the
    // pixel. For a vertical line, this means adding 0.5 to the x-value.
    path.moveTo(SkFloatToScalar(x + 0.5f), SkIntToScalar(y + height_));

    // Draw up to the top-left. Stop with the y-value at a half-pixel.
    path.rLineTo(SkIntToScalar(0), SkFloatToScalar(-height_ + 0.5f));

    // Draw right to the top-right, stopping within the last pixel.
    path.rLineTo(SkFloatToScalar(width_ - 0.5f), SkIntToScalar(0));

    paint.setColor(shadow_color);
    canvas->DrawPath(path, paint);

    path.reset();

    // Bottom and right highlights. Note that the shadows own the shared corner
    // pixels, so reduce the sizes accordingly.
    path.moveTo(SkIntToScalar(x + 1), SkFloatToScalar(y + height_ - 0.5f));

    // Draw right to the bottom-right.
    path.rLineTo(SkFloatToScalar(width_ - 1.5f), SkIntToScalar(0));

    // Draw up to the top-right.
    path.rLineTo(SkIntToScalar(0), SkFloatToScalar(-height_ + 1.5f));

    paint.setColor(highlight_color);
    canvas->DrawPath(path, paint);
  }
}

}  // namespace

namespace profiles {

struct IconResourceInfo {
  int resource_id;
  const char* filename;
};

const int kAvatarIconWidth = 38;
const int kAvatarIconHeight = 31;
const SkColor kAvatarTutorialBackgroundColor = SkColorSetRGB(0x42, 0x85, 0xf4);
const SkColor kAvatarTutorialContentTextColor = SkColorSetRGB(0xc6, 0xda, 0xfc);
const SkColor kAvatarBubbleAccountsBackgroundColor =
    SkColorSetRGB(0xf3, 0xf3, 0xf3);

const char kDefaultUrlPrefix[] = "chrome://theme/IDR_PROFILE_AVATAR_";
const char kGAIAPictureFileName[] = "Google Profile Picture.png";
const char kHighResAvatarFolderName[] = "Avatars";

// This avatar does not exist on the server, the high res copy is in the build.
const char kNoHighResAvatar[] = "NothingToDownload";

// The size of the function-static kDefaultAvatarIconResources array below.
const size_t kDefaultAvatarIconsCount = 27;

// The first 8 icons are generic.
const size_t kGenericAvatarIconsCount = 8;

// The avatar used as a placeholder (grey silhouette).
const int kPlaceholderAvatarIcon = 26;

gfx::Image GetSizedAvatarIcon(const gfx::Image& image,
                              bool is_rectangle,
                              int width, int height) {
  if (!is_rectangle && image.Height() <= height)
    return image;

  gfx::Size size(width, height);

  // Source for a centered, sized icon. GAIA images get a border.
  scoped_ptr<gfx::ImageSkiaSource> source(
      new AvatarImageSource(
          *image.ToImageSkia(),
          size,
          std::min(width, height),
          AvatarImageSource::POSITION_CENTER,
          AvatarImageSource::BORDER_NONE));

  return gfx::Image(gfx::ImageSkia(source.release(), size));
}

gfx::Image GetAvatarIconForMenu(const gfx::Image& image,
                                bool is_rectangle) {
  return GetSizedAvatarIcon(
      image, is_rectangle, kAvatarIconWidth, kAvatarIconHeight);
}

gfx::Image GetAvatarIconForWebUI(const gfx::Image& image,
                                 bool is_rectangle) {
  return GetSizedAvatarIcon(image, is_rectangle,
                            kAvatarIconWidth, kAvatarIconHeight);
}

gfx::Image GetAvatarIconForTitleBar(const gfx::Image& image,
                                    bool is_gaia_image,
                                    int dst_width,
                                    int dst_height) {
  // The image requires no border or resizing.
  if (!is_gaia_image && image.Height() <= kAvatarIconHeight)
    return image;

  int size = std::min(std::min(kAvatarIconWidth, kAvatarIconHeight),
                      std::min(dst_width, dst_height));
  gfx::Size dst_size(dst_width, dst_height);

  // Source for a sized icon drawn at the bottom center of the canvas,
  // with an etched border (for GAIA images).
  scoped_ptr<gfx::ImageSkiaSource> source(
      new AvatarImageSource(
          *image.ToImageSkia(),
          dst_size,
          size,
          AvatarImageSource::POSITION_BOTTOM_CENTER,
          is_gaia_image ? AvatarImageSource::BORDER_ETCHED :
              AvatarImageSource::BORDER_NONE));

  return gfx::Image(gfx::ImageSkia(source.release(), dst_size));
}

SkBitmap GetAvatarIconAsSquare(const SkBitmap& source_bitmap,
                               int scale_factor) {
  SkBitmap square_bitmap;
  if ((source_bitmap.width() == scale_factor * profiles::kAvatarIconWidth) &&
      (source_bitmap.height() == scale_factor * profiles::kAvatarIconHeight)) {
    // Shave a couple of columns so the |source_bitmap| is more square. So when
    // resized to a square aspect ratio it looks pretty.
    gfx::Rect frame(scale_factor * profiles::kAvatarIconWidth,
                    scale_factor * profiles::kAvatarIconHeight);
    frame.Inset(scale_factor * 2, 0, scale_factor * 2, 0);
    source_bitmap.extractSubset(&square_bitmap, gfx::RectToSkIRect(frame));
  } else {
    // If not the avatar icon's aspect ratio, the image should be square.
    DCHECK(source_bitmap.width() == source_bitmap.height());
    square_bitmap = source_bitmap;
  }
  return square_bitmap;
}

// Helper methods for accessing, transforming and drawing avatar icons.
size_t GetDefaultAvatarIconCount() {
  return kDefaultAvatarIconsCount;
}

size_t GetGenericAvatarIconCount() {
  return kGenericAvatarIconsCount;
}

int GetPlaceholderAvatarIndex() {
  return kPlaceholderAvatarIcon;
}

int GetPlaceholderAvatarIconResourceID() {
  return IDR_PROFILE_AVATAR_26;
}

const IconResourceInfo* GetDefaultAvatarIconResourceInfo(size_t index) {
  static const IconResourceInfo resource_info[kDefaultAvatarIconsCount] = {
    { IDR_PROFILE_AVATAR_0, "avatar_generic.png"},
    { IDR_PROFILE_AVATAR_1, "avatar_generic_aqua.png"},
    { IDR_PROFILE_AVATAR_2, "avatar_generic_blue.png"},
    { IDR_PROFILE_AVATAR_3, "avatar_generic_green.png"},
    { IDR_PROFILE_AVATAR_4, "avatar_generic_orange.png"},
    { IDR_PROFILE_AVATAR_5, "avatar_generic_purple.png"},
    { IDR_PROFILE_AVATAR_6, "avatar_generic_red.png"},
    { IDR_PROFILE_AVATAR_7, "avatar_generic_yellow.png"},
    { IDR_PROFILE_AVATAR_8, "avatar_secret_agent.png"},
    { IDR_PROFILE_AVATAR_9, "avatar_superhero.png"},
    { IDR_PROFILE_AVATAR_10, "avatar_volley_ball.png"},
    { IDR_PROFILE_AVATAR_11, "avatar_businessman.png"},
    { IDR_PROFILE_AVATAR_12, "avatar_ninja.png"},
    { IDR_PROFILE_AVATAR_13, "avatar_alien.png"},
    { IDR_PROFILE_AVATAR_14, "avatar_smiley.png"},
    { IDR_PROFILE_AVATAR_15, "avatar_flower.png"},
    { IDR_PROFILE_AVATAR_16, "avatar_pizza.png"},
    { IDR_PROFILE_AVATAR_17, "avatar_soccer.png"},
    { IDR_PROFILE_AVATAR_18, "avatar_burger.png"},
    { IDR_PROFILE_AVATAR_19, "avatar_cat.png"},
    { IDR_PROFILE_AVATAR_20, "avatar_cupcake.png"},
    { IDR_PROFILE_AVATAR_21, "avatar_dog.png"},
    { IDR_PROFILE_AVATAR_22, "avatar_horse.png"},
    { IDR_PROFILE_AVATAR_23, "avatar_margarita.png"},
    { IDR_PROFILE_AVATAR_24, "avatar_note.png"},
    { IDR_PROFILE_AVATAR_25, "avatar_sun_cloud.png"},
    { IDR_PROFILE_AVATAR_26, kNoHighResAvatar},
  };
  return &resource_info[index];
}

int GetDefaultAvatarIconResourceIDAtIndex(size_t index) {
  DCHECK(IsDefaultAvatarIconIndex(index));
  return GetDefaultAvatarIconResourceInfo(index)->resource_id;
}

const char* GetDefaultAvatarIconFileNameAtIndex(size_t index) {
  DCHECK(index < kDefaultAvatarIconsCount);
  return GetDefaultAvatarIconResourceInfo(index)->filename;
}

const char* GetNoHighResAvatarFileName() {
  return kNoHighResAvatar;
}

base::FilePath GetPathOfHighResAvatarAtIndex(size_t index) {
  std::string file_name = GetDefaultAvatarIconResourceInfo(index)->filename;
  base::FilePath user_data_dir;
  PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
  return user_data_dir.AppendASCII(
      kHighResAvatarFolderName).AppendASCII(file_name);
}

std::string GetDefaultAvatarIconUrl(size_t index) {
  DCHECK(IsDefaultAvatarIconIndex(index));
  return base::StringPrintf("%s%" PRIuS, kDefaultUrlPrefix, index);
}

bool IsDefaultAvatarIconIndex(size_t index) {
  return index < kDefaultAvatarIconsCount;
}

bool IsDefaultAvatarIconUrl(const std::string& url, size_t* icon_index) {
  DCHECK(icon_index);
  if (url.find(kDefaultUrlPrefix) != 0)
    return false;

  int int_value = -1;
  if (base::StringToInt(base::StringPiece(url.begin() +
                                          strlen(kDefaultUrlPrefix),
                                          url.end()),
                        &int_value)) {
    if (int_value < 0 ||
        int_value >= static_cast<int>(kDefaultAvatarIconsCount))
      return false;
    *icon_index = int_value;
    return true;
  }

  return false;
}

}  // namespace profiles
