// 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 "ash/wm/resize_shadow.h"

#include <memory>

#include "base/lazy_instance.h"
#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "ui/aura/window.h"
#include "ui/base/hit_test.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/gfx/image/canvas_image_source.h"

namespace {

// The width of the resize shadow that appears on the hovered edge of the
// window.
constexpr int kVisualThickness = 8;

// The corner radius of the resize shadow, which not coincidentally matches
// the corner radius of the actual window.
static constexpr int kCornerRadiusOfResizeShadow = 2;
static constexpr int kCornerRadiusOfWindow = 2;

// This class simply draws a roundrect. The layout and tiling is handled by
// ResizeShadow and NinePatchLayer.
class ResizeShadowImageSource : public gfx::CanvasImageSource {
 public:
  ResizeShadowImageSource()
      : gfx::CanvasImageSource(gfx::Size(kImageSide, kImageSide),
                               false /* is opaque */) {}

  ~ResizeShadowImageSource() override = default;

  // gfx::CanvasImageSource:
  void Draw(gfx::Canvas* canvas) override {
    cc::PaintFlags paint;
    paint.setAntiAlias(true);
    paint.setColor(SK_ColorBLACK);
    canvas->DrawRoundRect(gfx::RectF(gfx::SizeF(size())),
                          kCornerRadiusOfResizeShadow, paint);
  }

 private:
  // The image has to have enough space to depict the visual thickness (left and
  // right) plus an inset for extending beneath the window's rounded corner plus
  // one pixel for the center of the nine patch.
  static constexpr int kImageSide =
      2 * (kVisualThickness + kCornerRadiusOfWindow) + 1;

  DISALLOW_COPY_AND_ASSIGN(ResizeShadowImageSource);
};

base::LazyInstance<std::unique_ptr<gfx::ImageSkia>>::Leaky g_shadow_image =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

namespace ash {

ResizeShadow::ResizeShadow(aura::Window* window)
    : window_(window), last_hit_test_(HTNOWHERE) {
  window_->AddObserver(this);

  // Use a NinePatchLayer to tile the shadow image (which is simply a
  // roundrect).
  layer_.reset(new ui::Layer(ui::LAYER_NINE_PATCH));
  layer_->set_name("WindowResizeShadow");
  layer_->SetFillsBoundsOpaquely(false);
  layer_->SetOpacity(0.f);
  layer_->SetVisible(false);

  if (!g_shadow_image.Get()) {
    auto* source = new ResizeShadowImageSource();
    g_shadow_image.Get() = std::make_unique<gfx::ImageSkia>(
        base::WrapUnique(source), source->size());
  }
  layer_->UpdateNinePatchLayerImage(*g_shadow_image.Get());
  gfx::Rect aperture(g_shadow_image.Get()->size());
  constexpr gfx::Insets kApertureInsets(kVisualThickness +
                                        kCornerRadiusOfWindow);
  aperture.Inset(kApertureInsets);
  layer_->UpdateNinePatchLayerAperture(aperture);
  layer_->UpdateNinePatchLayerBorder(
      gfx::Rect(kApertureInsets.left(), kApertureInsets.top(),
                kApertureInsets.width(), kApertureInsets.height()));

  ReparentLayer();
}

ResizeShadow::~ResizeShadow() {
  window_->RemoveObserver(this);
}

void ResizeShadow::OnWindowBoundsChanged(aura::Window* window,
                                         const gfx::Rect& old_bounds,
                                         const gfx::Rect& new_bounds,
                                         ui::PropertyChangeReason reason) {
  UpdateBoundsAndVisibility();
}

void ResizeShadow::OnWindowHierarchyChanged(
    const aura::WindowObserver::HierarchyChangeParams& params) {
  ReparentLayer();
}

void ResizeShadow::OnWindowStackingChanged(aura::Window* window) {
  ReparentLayer();
}

void ResizeShadow::ShowForHitTest(int hit) {
  // Don't start animations unless something changed.
  if (hit == last_hit_test_)
    return;
  last_hit_test_ = hit;

  UpdateBoundsAndVisibility();
}

void ResizeShadow::Hide() {
  ShowForHitTest(HTNOWHERE);
}

void ResizeShadow::ReparentLayer() {
  DCHECK(window_->layer()->parent());
  if (layer_->parent() != window_->layer()->parent())
    window_->layer()->parent()->Add(layer_.get());
  layer_->parent()->StackBelow(layer_.get(), window_->layer());
}

void ResizeShadow::UpdateBoundsAndVisibility() {
  // The shadow layer is positioned such that one or two edges will stick out
  // from underneath |window_|. Thus |window_| occludes the rest of the
  // roundrect.
  const int hit = last_hit_test_;
  bool show_top = hit == HTTOPLEFT || hit == HTTOP || hit == HTTOPRIGHT;
  bool show_left = hit == HTTOPLEFT || hit == HTLEFT || hit == HTBOTTOMLEFT;
  bool show_bottom =
      hit == HTBOTTOMLEFT || hit == HTBOTTOM || hit == HTBOTTOMRIGHT;
  bool show_right = hit == HTTOPRIGHT || hit == HTRIGHT || hit == HTBOTTOMRIGHT;

  const int outset = -kVisualThickness;
  gfx::Insets outsets(show_top ? outset : 0, show_left ? outset : 0,
                      show_bottom ? outset : 0, show_right ? outset : 0);
  bool visible = !outsets.IsEmpty();
  if (!visible && !layer_->GetTargetVisibility())
    return;

  if (visible) {
    gfx::Rect bounds = window_->bounds();
    bounds.Inset(outsets);
    layer_->SetBounds(bounds);
  }

  // The resize shadow snaps in but fades out.
  ui::ScopedLayerAnimationSettings settings(layer_->GetAnimator());
  if (!visible) {
    constexpr int kShadowFadeOutDurationMs = 100;
    settings.SetTransitionDuration(
        base::TimeDelta::FromMilliseconds(kShadowFadeOutDurationMs));
  }
  constexpr float kShadowTargetOpacity = 0.5f;
  layer_->SetOpacity(visible ? kShadowTargetOpacity : 0.f);
  layer_->SetVisible(visible);
}

}  // namespace ash
