// Copyright (c) 2013 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 "ash/desktop_background/wallpaper_resizer.h"

#include "ash/desktop_background/wallpaper_resizer_observer.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/threading/worker_pool.h"
#include "content/public/browser/browser_thread.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/skia_util.h"

using content::BrowserThread;

namespace ash {
namespace {

// For our scaling ratios we need to round positive numbers.
int RoundPositive(double x) {
  return static_cast<int>(floor(x + 0.5));
}

// Resizes |orig_bitmap| to |target_size| using |layout| and stores the
// resulting bitmap at |resized_bitmap_out|.
void Resize(SkBitmap orig_bitmap,
            const gfx::Size& target_size,
            WallpaperLayout layout,
            SkBitmap* resized_bitmap_out) {
  DCHECK(BrowserThread::GetBlockingPool()->RunsTasksOnCurrentThread());
  SkBitmap new_bitmap = orig_bitmap;

  const int orig_width = orig_bitmap.width();
  const int orig_height = orig_bitmap.height();
  const int new_width = target_size.width();
  const int new_height = target_size.height();

  if (orig_width > new_width || orig_height > new_height) {
    gfx::Rect wallpaper_rect(0, 0, orig_width, orig_height);
    gfx::Size cropped_size = gfx::Size(std::min(new_width, orig_width),
                                       std::min(new_height, orig_height));
    switch (layout) {
      case WALLPAPER_LAYOUT_CENTER:
        wallpaper_rect.ClampToCenteredSize(cropped_size);
        orig_bitmap.extractSubset(&new_bitmap,
                                  gfx::RectToSkIRect(wallpaper_rect));
        break;
      case WALLPAPER_LAYOUT_TILE:
        wallpaper_rect.set_size(cropped_size);
        orig_bitmap.extractSubset(&new_bitmap,
                                  gfx::RectToSkIRect(wallpaper_rect));
        break;
      case WALLPAPER_LAYOUT_STRETCH:
        new_bitmap = skia::ImageOperations::Resize(
            orig_bitmap, skia::ImageOperations::RESIZE_LANCZOS3,
            new_width, new_height);
        break;
      case WALLPAPER_LAYOUT_CENTER_CROPPED:
        if (orig_width > new_width && orig_height > new_height) {
          // The dimension with the smallest ratio must be cropped, the other
          // one is preserved. Both are set in gfx::Size cropped_size.
          double horizontal_ratio = static_cast<double>(new_width) /
              static_cast<double>(orig_width);
          double vertical_ratio = static_cast<double>(new_height) /
              static_cast<double>(orig_height);

          if (vertical_ratio > horizontal_ratio) {
            cropped_size = gfx::Size(
                RoundPositive(static_cast<double>(new_width) / vertical_ratio),
                orig_height);
          } else {
            cropped_size = gfx::Size(orig_width, RoundPositive(
                static_cast<double>(new_height) / horizontal_ratio));
          }
          wallpaper_rect.ClampToCenteredSize(cropped_size);
          SkBitmap sub_image;
          orig_bitmap.extractSubset(&sub_image,
                                    gfx::RectToSkIRect(wallpaper_rect));
          new_bitmap = skia::ImageOperations::Resize(
              sub_image, skia::ImageOperations::RESIZE_LANCZOS3,
              new_width, new_height);
        }
    }
  }

  *resized_bitmap_out = new_bitmap;
  resized_bitmap_out->setImmutable();
}

}  // namespace

WallpaperResizer::WallpaperResizer(int image_resource_id,
                                   const gfx::Size& target_size,
                                   WallpaperLayout layout)
    : wallpaper_image_(*(ui::ResourceBundle::GetSharedInstance().
          GetImageNamed(image_resource_id).ToImageSkia())),
      target_size_(target_size),
      layout_(layout),
      weak_ptr_factory_(this) {
}

WallpaperResizer::WallpaperResizer(const gfx::ImageSkia& image,
                                   const gfx::Size& target_size,
                                   WallpaperLayout layout)
    : wallpaper_image_(image),
      target_size_(target_size),
      layout_(layout),
      weak_ptr_factory_(this) {
}

WallpaperResizer::~WallpaperResizer() {
}

void WallpaperResizer::StartResize() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  SkBitmap* resized_bitmap = new SkBitmap;
  if (!content::BrowserThread::PostBlockingPoolTaskAndReply(
          FROM_HERE,
          base::Bind(&Resize, *wallpaper_image_.bitmap(), target_size_,
                     layout_, resized_bitmap),
          base::Bind(&WallpaperResizer::OnResizeFinished,
                     weak_ptr_factory_.GetWeakPtr(),
                     base::Owned(resized_bitmap)))) {
    LOG(WARNING) << "PostSequencedWorkerTask failed. "
                 << "Wallpaper may not be resized.";
  }
}

void WallpaperResizer::AddObserver(WallpaperResizerObserver* observer) {
  observers_.AddObserver(observer);
}

void WallpaperResizer::RemoveObserver(WallpaperResizerObserver* observer) {
  observers_.RemoveObserver(observer);
}

void WallpaperResizer::OnResizeFinished(SkBitmap* resized_bitmap) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  wallpaper_image_ = gfx::ImageSkia::CreateFrom1xBitmap(*resized_bitmap);
  FOR_EACH_OBSERVER(WallpaperResizerObserver, observers_,
                    OnWallpaperResized());
}

} // namespace ash
