// Copyright 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/wm/overview/overview_item.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "ash/public/cpp/shell_window_ids.h"
#include "ash/public/cpp/window_properties.h"
#include "ash/public/cpp/window_state_type.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/scoped_animation_disabler.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/wm/desks/desks_util.h"
#include "ash/wm/drag_window_controller.h"
#include "ash/wm/overview/delayed_animation_observer_impl.h"
#include "ash/wm/overview/overview_animation_type.h"
#include "ash/wm/overview/overview_constants.h"
#include "ash/wm/overview/overview_controller.h"
#include "ash/wm/overview/overview_grid.h"
#include "ash/wm/overview/overview_grid_event_handler.h"
#include "ash/wm/overview/overview_highlight_controller.h"
#include "ash/wm/overview/overview_utils.h"
#include "ash/wm/overview/overview_window_drag_controller.h"
#include "ash/wm/overview/rounded_label_widget.h"
#include "ash/wm/overview/scoped_overview_animation_settings.h"
#include "ash/wm/overview/scoped_overview_transform_window.h"
#include "ash/wm/splitview/split_view_constants.h"
#include "ash/wm/splitview/split_view_utils.h"
#include "ash/wm/tablet_mode/tablet_mode_controller.h"
#include "ash/wm/window_state.h"
#include "ash/wm/window_transient_descendant_iterator.h"
#include "ash/wm/wm_event.h"
#include "base/auto_reset.h"
#include "base/bind.h"
#include "base/metrics/user_metrics.h"
#include "ui/accessibility/ax_enums.mojom.h"
#include "ui/aura/client/aura_constants.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/compositor/layer_animation_observer.h"
#include "ui/compositor/layer_animation_sequence.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/compositor_extra/shadow.h"
#include "ui/gfx/geometry/safe_integer_conversions.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/gfx/transform_util.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/animation/flood_fill_ink_drop_ripple.h"
#include "ui/views/animation/ink_drop_impl.h"
#include "ui/views/animation/ink_drop_mask.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/layout/layout_provider.h"
#include "ui/views/widget/widget.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/core/shadow_types.h"
#include "ui/wm/core/window_util.h"

namespace ash {

namespace {

// Opacity for fading out during closing a window.
constexpr float kClosingItemOpacity = 0.8f;

// Before closing a window animate both the window and the caption to shrink by
// this fraction of size.
constexpr float kPreCloseScale = 0.02f;

constexpr int kShadowElevation = 16;

// The amount of translation an item animates by when it is closed by using
// swipe to close.
constexpr int kSwipeToCloseCloseTranslationDp = 96;

// When an item is being dragged, the bounds are outset horizontally by this
// fraction of the width, and vertically by this fraction of the height. The
// outset in each dimension is on both sides, for a total of twice this much
// change in the size of the item along that dimension.
constexpr float kDragWindowScale = 0.05f;

constexpr int kCloseButtonInkDropInsetDp = 2;

constexpr SkColor kCloseButtonColor = SK_ColorWHITE;

// The colors of the close button ripple.
constexpr SkColor kCloseButtonInkDropRippleColor =
    SkColorSetA(kCloseButtonColor, 0x0F);
constexpr SkColor kCloseButtonInkDropRippleHighlightColor =
    SkColorSetA(kCloseButtonColor, 0x14);

// A self-deleting animation observer that runs the given callback when its
// associated animation completes. Optionally takes a callback that is run when
// the animation starts.
class AnimationObserver : public ui::ImplicitAnimationObserver {
 public:
  explicit AnimationObserver(base::OnceClosure on_animation_finished)
      : AnimationObserver(base::NullCallback(),
                          std::move(on_animation_finished)) {}

  AnimationObserver(base::OnceClosure on_animation_started,
                    base::OnceClosure on_animation_finished)
      : on_animation_started_(std::move(on_animation_started)),
        on_animation_finished_(std::move(on_animation_finished)) {
    DCHECK(!on_animation_finished_.is_null());
  }

  ~AnimationObserver() override = default;

  // ui::ImplicitAnimationObserver:
  void OnLayerAnimationStarted(ui::LayerAnimationSequence* sequence) override {
    if (!on_animation_started_.is_null())
      std::move(on_animation_started_).Run();
  }
  void OnImplicitAnimationsCompleted() override {
    std::move(on_animation_finished_).Run();
    delete this;
  }

 private:
  base::OnceClosure on_animation_started_;
  base::OnceClosure on_animation_finished_;

  DISALLOW_COPY_AND_ASSIGN(AnimationObserver);
};

OverviewAnimationType GetExitOverviewAnimationTypeForMinimizedWindow(
    OverviewSession::EnterExitOverviewType type,
    bool should_animate_when_exiting) {
  // We should never get here when overview mode should exit immediately. The
  // minimized window's |item_widget_| should be closed and destroyed
  // immediately.
  DCHECK_NE(type, OverviewSession::EnterExitOverviewType::kImmediateExit);

  // EnterExitOverviewType can only be set to kWindowMinimized in talbet mode.
  // Fade out the minimized window without animation if switch from tablet mode
  // to clamshell mode.
  if (type == OverviewSession::EnterExitOverviewType::kSlideOutExit) {
    return Shell::Get()->tablet_mode_controller()->InTabletMode()
               ? OVERVIEW_ANIMATION_EXIT_TO_HOME_LAUNCHER
               : OVERVIEW_ANIMATION_NONE;
  }
  return should_animate_when_exiting
             ? OVERVIEW_ANIMATION_EXIT_OVERVIEW_MODE_FADE_OUT
             : OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO;
}

// Applies |new_bounds_in_screen| to |widget|, animating and observing the
// transform if necessary.
void SetWidgetBoundsAndMaybeAnimateTransform(
    views::Widget* widget,
    const gfx::Rect& new_bounds_in_screen,
    OverviewAnimationType animation_type,
    ui::ImplicitAnimationObserver* observer) {
  aura::Window* window = widget->GetNativeWindow();
  gfx::RectF previous_bounds = gfx::RectF(window->GetBoundsInScreen());
  window->SetBoundsInScreen(
      new_bounds_in_screen,
      display::Screen::GetScreen()->GetDisplayNearestWindow(window));
  if (animation_type == OVERVIEW_ANIMATION_NONE) {
    // Make sure that |observer|, which could be a self-deleting object, will
    // not be leaked.
    DCHECK(!observer);
    return;
  }

  // For animations, compute the transform needed to place the widget at its
  // new bounds back to the old bounds, and then apply the idenity
  // transform. This so the bounds visually line up the concurrent transform
  // animations. Also transform animations may be more performant.
  const gfx::RectF current_bounds = gfx::RectF(window->GetBoundsInScreen());
  window->SetTransform(
      gfx::TransformBetweenRects(current_bounds, previous_bounds));
  ScopedOverviewAnimationSettings settings(animation_type, window);
  if (observer)
    settings.AddObserver(observer);
  window->SetTransform(gfx::Transform());
}

}  // namespace

// The close button for the overview item. It has a custom ink drop.
class OverviewItem::OverviewCloseButton : public views::ImageButton {
 public:
  explicit OverviewCloseButton(views::ButtonListener* listener)
      : views::ImageButton(listener) {
    SetInkDropMode(InkDropMode::ON_NO_GESTURE_HANDLER);
    SetImage(
        views::Button::STATE_NORMAL,
        gfx::CreateVectorIcon(kOverviewWindowCloseIcon, kCloseButtonColor));
    SetImageHorizontalAlignment(views::ImageButton::ALIGN_CENTER);
    SetImageVerticalAlignment(views::ImageButton::ALIGN_MIDDLE);
    SetMinimumImageSize(gfx::Size(kHeaderHeightDp, kHeaderHeightDp));
    SetAccessibleName(l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
    SetTooltipText(l10n_util::GetStringUTF16(IDS_APP_ACCNAME_CLOSE));
  }

  ~OverviewCloseButton() override = default;

  // Resets the listener so that the listener can go out of scope.
  void ResetListener() { listener_ = nullptr; }

 protected:
  // views::Button:
  std::unique_ptr<views::InkDrop> CreateInkDrop() override {
    auto ink_drop = std::make_unique<views::InkDropImpl>(this, size());
    ink_drop->SetAutoHighlightMode(
        views::InkDropImpl::AutoHighlightMode::SHOW_ON_RIPPLE);
    ink_drop->SetShowHighlightOnHover(true);
    return ink_drop;
  }
  std::unique_ptr<views::InkDropRipple> CreateInkDropRipple() const override {
    return std::make_unique<views::FloodFillInkDropRipple>(
        size(), gfx::Insets(), GetInkDropCenterBasedOnLastEvent(),
        kCloseButtonInkDropRippleColor, /*visible_opacity=*/1.f);
  }
  std::unique_ptr<views::InkDropHighlight> CreateInkDropHighlight()
      const override {
    return std::make_unique<views::InkDropHighlight>(
        gfx::PointF(GetLocalBounds().CenterPoint()),
        std::make_unique<views::CircleLayerDelegate>(
            kCloseButtonInkDropRippleHighlightColor, GetInkDropRadius()));
  }
  std::unique_ptr<views::InkDropMask> CreateInkDropMask() const override {
    return std::make_unique<views::CircleInkDropMask>(
        size(), GetLocalBounds().CenterPoint(), GetInkDropRadius());
  }

 private:
  int GetInkDropRadius() const {
    return std::min(size().width(), size().height()) / 2 -
           kCloseButtonInkDropInsetDp;
  }

  DISALLOW_COPY_AND_ASSIGN(OverviewCloseButton);
};

OverviewItem::OverviewItem(aura::Window* window,
                           OverviewSession* overview_session,
                           OverviewGrid* overview_grid)
    : root_window_(window->GetRootWindow()),
      transform_window_(this, window),
      overview_session_(overview_session),
      overview_grid_(overview_grid),
      weak_ptr_factory_(this) {
  CreateWindowLabel();
  for (auto* window_iter : WindowTransientDescendantIteratorRange(
           WindowTransientDescendantIterator(window))) {
    window_iter->AddObserver(this);
  }
  WindowState::Get(window)->AddObserver(this);
}

OverviewItem::~OverviewItem() {
  aura::Window* window = GetWindow();
  WindowState::Get(window)->RemoveObserver(this);
  for (auto* window_iter : WindowTransientDescendantIteratorRange(
           WindowTransientDescendantIterator(window))) {
    window_iter->RemoveObserver(this);
  }
}

aura::Window* OverviewItem::GetWindow() {
  return transform_window_.window();
}

bool OverviewItem::Contains(const aura::Window* target) const {
  return transform_window_.Contains(target);
}

void OverviewItem::RestoreWindow(bool reset_transform) {
  // TODO(oshima): SplitViewController has its own logic to adjust the
  // target state in |SplitViewController::OnOverviewModeEnding|.
  // Unify the mechanism to control it and remove ifs.
  if (Shell::Get()->tablet_mode_controller()->InTabletMode() &&
      !SplitViewController::Get(root_window_)->InSplitViewMode() &&
      reset_transform) {
    MaximizeIfSnapped(GetWindow());
  }

  caption_container_view_->ResetEventDelegate();
  close_button_->ResetListener();
  transform_window_.RestoreWindow(reset_transform);

  if (transform_window_.IsMinimized()) {
    const auto enter_exit_type = overview_session_->enter_exit_overview_type();

    if (enter_exit_type ==
        OverviewSession::EnterExitOverviewType::kImmediateExit) {
      ImmediatelyCloseWidgetOnExit(std::move(item_widget_));
      return;
    }

    FadeOutWidgetAndMaybeSlideOnExit(
        std::move(item_widget_),
        GetExitOverviewAnimationTypeForMinimizedWindow(
            enter_exit_type, should_animate_when_exiting_));
  }
}

void OverviewItem::EnsureVisible() {
  transform_window_.EnsureVisible();
}

void OverviewItem::Shutdown() {
  item_widget_.reset();
  caption_container_view_ = nullptr;
}

void OverviewItem::PrepareForOverview() {
  transform_window_.PrepareForOverview();
  aura::Window* widget_window = item_widget_->GetNativeWindow();
  widget_window->parent()->StackChildBelow(widget_window, GetWindow());

  prepared_for_overview_ = true;
}

void OverviewItem::SlideWindowIn() {
  // This only gets called if we see the home launcher on enter (all windows are
  // minimized).
  DCHECK(transform_window_.IsMinimized());

  // The mask and shadow will be shown when animation ends. Update the mask
  // after starting the animation since starting the animation lets the
  // controller know we are in starting animation.
  FadeInWidgetAndMaybeSlideOnEnter(item_widget_.get(),
                                   OVERVIEW_ANIMATION_ENTER_FROM_HOME_LAUNCHER,
                                   /*slide=*/true, /*observe=*/true);
  UpdateRoundedCornersAndShadow();
}

std::unique_ptr<ui::ScopedLayerAnimationSettings>
OverviewItem::UpdateYPositionAndOpacity(
    int new_grid_y,
    float opacity,
    OverviewSession::UpdateAnimationSettingsCallback callback) {
  aura::Window::Windows windows = GetWindowsForHomeGesture();
  std::unique_ptr<ui::ScopedLayerAnimationSettings> settings_to_observe;
  for (auto* window : windows) {
    ui::Layer* layer = window->layer();
    std::unique_ptr<ui::ScopedLayerAnimationSettings> settings;
    if (!callback.is_null()) {
      settings = std::make_unique<ui::ScopedLayerAnimationSettings>(
          layer->GetAnimator());
      callback.Run(settings.get());
    }
    layer->SetOpacity(opacity);

    int initial_y = 0;
    if (translation_y_map_.contains(window))
      initial_y = translation_y_map_[window];

    // Alter the y-translation. Offset by the window location relative to the
    // grid.
    gfx::Transform transform = layer->transform();
    transform.matrix().setFloat(1, 3, initial_y - new_grid_y);
    layer->SetTransform(transform);

    if (settings)
      settings_to_observe = std::move(settings);
  }

  return settings_to_observe;
}

void OverviewItem::UpdateItemContentViewForMinimizedWindow() {
  caption_container_view_->UpdatePreviewView();
}

float OverviewItem::GetItemScale(const gfx::Size& size) {
  gfx::SizeF inset_size(size.width(), size.height() - 2 * kWindowMargin);
  return ScopedOverviewTransformWindow::GetItemScale(
      GetTargetBoundsInScreen().size(), inset_size,
      transform_window_.GetTopInset(), kHeaderHeightDp);
}

gfx::RectF OverviewItem::GetTargetBoundsInScreen() const {
  return ::ash::GetTargetBoundsInScreen(transform_window_.window());
}

gfx::RectF OverviewItem::GetTransformedBounds() const {
  return transform_window_.GetTransformedBounds();
}

void OverviewItem::SetBounds(const gfx::RectF& target_bounds,
                             OverviewAnimationType animation_type) {
  if (in_bounds_update_ ||
      !Shell::Get()->overview_controller()->InOverviewSession())
    return;

  // Do not animate if the resulting bounds does not change. The original
  // window may change bounds so we still need to call SetItemBounds to update
  // the window transform.
  OverviewAnimationType new_animation_type = animation_type;
  if (target_bounds == target_bounds_ &&
      !GetWindow()->layer()->GetAnimator()->is_animating()) {
    new_animation_type = OVERVIEW_ANIMATION_NONE;
  }

  base::AutoReset<bool> auto_reset_in_bounds_update(&in_bounds_update_, true);
  // If |target_bounds_| is empty, this is the first update. Let
  // UpdateHeaderLayout know, as we do not want |item_widget_| to be animated
  // with the window.
  const bool is_first_update = target_bounds_.IsEmpty();
  target_bounds_ = target_bounds;

  // If the window is minimized we can avoid applying transforms on the original
  // window.
  if (transform_window_.IsMinimized()) {
    item_widget_->GetNativeWindow()->layer()->GetAnimator()->StopAnimating();

    gfx::Rect minimized_bounds = gfx::ToEnclosedRect(target_bounds);
    minimized_bounds.Inset(-kWindowMargin, -kWindowMargin);
    OverviewAnimationType minimized_animation_type =
        is_first_update ? OVERVIEW_ANIMATION_NONE : new_animation_type;
    SetWidgetBoundsAndMaybeAnimateTransform(
        item_widget_.get(), minimized_bounds, minimized_animation_type,
        minimized_animation_type ==
                OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW
            ? new AnimationObserver{base::BindOnce(
                                        &OverviewItem::
                                            OnItemBoundsAnimationStarted,
                                        weak_ptr_factory_.GetWeakPtr()),
                                    base::BindOnce(
                                        &OverviewItem::
                                            OnItemBoundsAnimationEnded,
                                        weak_ptr_factory_.GetWeakPtr())}
            : nullptr);

    // On the first update show |item_widget_|. It's created on creation of
    // |this|, and needs to be shown as soon as its bounds have been determined
    // as it contains a mirror view of the window in its contents. The header
    // will be faded in later to match non minimized windows.
    if (is_first_update) {
      if (!should_animate_when_entering_) {
        item_widget_->GetNativeWindow()->layer()->SetOpacity(1.f);
      } else {
        if (new_animation_type == OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW) {
          PerformItemSpawnedAnimation(item_widget_->GetNativeWindow(),
                                      gfx::Transform{});
        } else {
          FadeInWidgetAndMaybeSlideOnEnter(
              item_widget_.get(),
              OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
              /*slide=*/false, /*observe=*/true);
        }
      }
    }
  } else {
    gfx::RectF inset_bounds(target_bounds);
    inset_bounds.Inset(kWindowMargin, kWindowMargin);
    SetItemBounds(inset_bounds, new_animation_type, is_first_update);
    UpdateHeaderLayout(is_first_update ? OVERVIEW_ANIMATION_NONE
                                       : new_animation_type);
  }

  // Shadow is normally set after an animation is finished. In the case of no
  // animations, manually set the shadow. Shadow relies on both the window
  // transform and |item_widget_|'s new bounds so set it after SetItemBounds
  // and UpdateHeaderLayout. Do not apply the shadow for drop target.
  if (new_animation_type == OVERVIEW_ANIMATION_NONE)
    UpdateRoundedCornersAndShadow();

  if (cannot_snap_widget_) {
    SetWidgetBoundsAndMaybeAnimateTransform(
        cannot_snap_widget_.get(),
        cannot_snap_widget_->GetBoundsCenteredIn(
            gfx::ToEnclosingRect(GetWindowTargetBoundsWithInsets())),
        new_animation_type, nullptr);
  }

  translation_y_map_.clear();
  aura::Window::Windows windows = GetWindowsForHomeGesture();
  for (auto* window : windows) {
    // Cache the original y translation when setting bounds. They will be
    // possibly used later when swiping up from the shelf to close overview. Use
    // the target transform as some windows may still be animating.
    translation_y_map_[window] =
        window->layer()->GetTargetTransform().To2dTranslation().y();
  }
}

void OverviewItem::SendAccessibleSelectionEvent() {
  caption_container_view_->NotifyAccessibilityEvent(
      ax::mojom::Event::kSelection, true);
}

void OverviewItem::AnimateAndCloseWindow(bool up) {
  base::RecordAction(base::UserMetricsAction("WindowSelector_SwipeToClose"));

  animating_to_close_ = true;
  overview_session_->PositionWindows(/*animate=*/true);
  caption_container_view_->ResetEventDelegate();
  close_button_->ResetListener();

  int translation_y = kSwipeToCloseCloseTranslationDp * (up ? -1 : 1);
  gfx::Transform transform;
  transform.Translate(gfx::Vector2d(0, translation_y));

  auto animate_window = [this](aura::Window* window,
                               const gfx::Transform& transform, bool observe) {
    ScopedOverviewAnimationSettings settings(
        OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM, window);
    gfx::Transform original_transform = window->transform();
    original_transform.ConcatTransform(transform);
    window->SetTransform(original_transform);
    if (observe) {
      settings.AddObserver(new AnimationObserver{
          base::BindOnce(&OverviewItem::OnWindowCloseAnimationCompleted,
                         weak_ptr_factory_.GetWeakPtr())});
    }
  };

  AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM);
  if (cannot_snap_widget_)
    animate_window(cannot_snap_widget_->GetNativeWindow(), transform, false);
  if (!transform_window_.IsMinimized())
    animate_window(GetWindow(), transform, false);
  animate_window(item_widget_->GetNativeWindow(), transform, true);
}

void OverviewItem::CloseWindow() {
  gfx::RectF inset_bounds(target_bounds_);
  inset_bounds.Inset(target_bounds_.width() * kPreCloseScale,
                     target_bounds_.height() * kPreCloseScale);
  // Scale down both the window and label.
  SetBounds(inset_bounds, OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM);
  // First animate opacity to an intermediate value concurrently with the
  // scaling animation.
  AnimateOpacity(kClosingItemOpacity, OVERVIEW_ANIMATION_CLOSING_OVERVIEW_ITEM);

  // Fade out the window and the label, effectively hiding them.
  AnimateOpacity(0.0, OVERVIEW_ANIMATION_CLOSE_OVERVIEW_ITEM);
  transform_window_.Close();
}

void OverviewItem::UpdateCannotSnapWarningVisibility() {
  // Windows which can snap will never show this warning. Or if the window is
  // the drop target window, also do not show this warning.
  bool visible = true;
  if (CanSnapInSplitview(GetWindow()) ||
      overview_grid_->IsDropTargetWindow(GetWindow())) {
    visible = false;
  } else {
    const SplitViewController::State state =
        SplitViewController::Get(root_window_)->state();
    visible = state == SplitViewController::State::kLeftSnapped ||
              state == SplitViewController::State::kRightSnapped;
  }

  if (!visible && !cannot_snap_widget_)
    return;

  if (!cannot_snap_widget_) {
    RoundedLabelWidget::InitParams params;
    params.horizontal_padding = kSplitviewLabelHorizontalInsetDp;
    params.vertical_padding = kSplitviewLabelVerticalInsetDp;
    params.background_color = kSplitviewLabelBackgroundColor;
    params.foreground_color = kSplitviewLabelEnabledColor;
    params.rounding_dp = kSplitviewLabelRoundRectRadiusDp;
    params.preferred_height = kSplitviewLabelPreferredHeightDp;
    params.message_id = IDS_ASH_SPLIT_VIEW_CANNOT_SNAP;
    params.parent =
        root_window()->GetChildById(kShellWindowId_AlwaysOnTopContainer);
    params.hide_in_mini_view = true;
    cannot_snap_widget_ = std::make_unique<RoundedLabelWidget>();
    cannot_snap_widget_->Init(std::move(params));
  }

  DoSplitviewOpacityAnimation(cannot_snap_widget_->GetNativeWindow()->layer(),
                              visible
                                  ? SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_IN
                                  : SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT);
  const gfx::Rect bounds =
      gfx::ToEnclosingRect(GetWindowTargetBoundsWithInsets());
  cannot_snap_widget_->SetBoundsCenteredIn(bounds, /*animate=*/false);
}

void OverviewItem::HideCannotSnapWarning() {
  if (!cannot_snap_widget_)
    return;
  DoSplitviewOpacityAnimation(cannot_snap_widget_->GetNativeWindow()->layer(),
                              SPLITVIEW_ANIMATION_OVERVIEW_ITEM_FADE_OUT);
}

void OverviewItem::OnSelectorItemDragStarted(OverviewItem* item) {
  is_being_dragged_ = (item == this);
  caption_container_view_->SetHeaderVisibility(
      is_being_dragged_
          ? CaptionContainerView::HeaderVisibility::kInvisible
          : CaptionContainerView::HeaderVisibility::kCloseButtonInvisibleOnly);
}

void OverviewItem::OnSelectorItemDragEnded(bool snap) {
  if (snap) {
    if (!is_being_dragged_)
      caption_container_view_->HideCloseInstantlyAndThenShowItSlowly();
  } else {
    caption_container_view_->SetHeaderVisibility(
        CaptionContainerView::HeaderVisibility::kVisible);
  }
  is_being_dragged_ = false;
}

void OverviewItem::SetVisibleDuringWindowDragging(bool visible) {
  aura::Window::Windows windows = GetWindowsForHomeGesture();
  for (auto* window : windows) {
    ui::Layer* layer = window->layer();
    layer->SetOpacity(visible ? 1.f : 0.f);
  }
}

ScopedOverviewTransformWindow::GridWindowFillMode
OverviewItem::GetWindowDimensionsType() const {
  return transform_window_.type();
}

void OverviewItem::UpdateWindowDimensionsType() {
  transform_window_.UpdateWindowDimensionsType();
  const bool show_backdrop =
      GetWindowDimensionsType() !=
      ScopedOverviewTransformWindow::GridWindowFillMode::kNormal;
  caption_container_view_->SetBackdropVisibility(show_backdrop);
}

gfx::Rect OverviewItem::GetBoundsOfSelectedItem() {
  gfx::RectF original_bounds = target_bounds();
  ScaleUpSelectedItem(OVERVIEW_ANIMATION_NONE);
  gfx::RectF selected_bounds = transform_window_.GetTransformedBounds();
  SetBounds(original_bounds, OVERVIEW_ANIMATION_NONE);
  return gfx::ToEnclosedRect(selected_bounds);
}

void OverviewItem::ScaleUpSelectedItem(OverviewAnimationType animation_type) {
  gfx::RectF scaled_bounds = target_bounds();
  scaled_bounds.Inset(-scaled_bounds.width() * kDragWindowScale,
                      -scaled_bounds.height() * kDragWindowScale);
  SetBounds(scaled_bounds, animation_type);
}

bool OverviewItem::IsDragItem() {
  return overview_session_->window_drag_controller() &&
         overview_session_->window_drag_controller()->item() == this;
}

void OverviewItem::OnDragAnimationCompleted() {
  // This is function is called whenever the grid repositions its windows, but
  // we only need to restack the windows if an item was being dragged around
  // and then released.
  if (!should_restack_on_animation_end_)
    return;

  should_restack_on_animation_end_ = false;

  // First stack this item's window below the snapped window if split view
  // mode is active.
  aura::Window* dragged_window = GetWindow();
  aura::Window* dragged_widget_window = item_widget_->GetNativeWindow();
  aura::Window* parent_window = dragged_widget_window->parent();
  SplitViewController* split_view_controller =
      SplitViewController::Get(root_window_);
  if (split_view_controller->InSplitViewMode()) {
    aura::Window* snapped_window =
        split_view_controller->GetDefaultSnappedWindow();
    if (snapped_window->parent() == parent_window &&
        dragged_window->parent() == parent_window) {
      parent_window->StackChildBelow(dragged_window, snapped_window);
      parent_window->StackChildBelow(dragged_widget_window, dragged_window);
    }
  }

  // Then find the window which was stacked right above this overview item's
  // window before dragging and stack this overview item's window below it.
  const std::vector<std::unique_ptr<OverviewItem>>& overview_items =
      overview_grid_->window_list();
  aura::Window* stacking_target = nullptr;
  for (size_t index = 0; index < overview_items.size(); ++index) {
    if (index > 0) {
      aura::Window* window = overview_items[index - 1].get()->GetWindow();
      if (window->parent() == parent_window &&
          dragged_window->parent() == parent_window) {
        stacking_target =
            overview_items[index - 1].get()->item_widget()->GetNativeWindow();
      }
    }
    if (overview_items[index].get() == this && stacking_target) {
      parent_window->StackChildBelow(dragged_window, stacking_target);
      parent_window->StackChildBelow(dragged_widget_window, dragged_window);
      break;
    }
  }
}

void OverviewItem::UpdatePhantomsForDragging(bool is_touch_dragging) {
  DCHECK(AreMultiDisplayOverviewAndSplitViewEnabled());
  DCHECK_GT(Shell::GetAllRootWindows().size(), 1u);
  if (!phantoms_for_dragging_) {
    phantoms_for_dragging_ = std::make_unique<DragWindowController>(
        transform_window_.IsMinimized() ? item_widget_->GetNativeWindow()
                                        : GetWindow(),
        is_touch_dragging);
  }
  phantoms_for_dragging_->Update();
}

void OverviewItem::DestroyPhantomsForDragging() {
  DCHECK(AreMultiDisplayOverviewAndSplitViewEnabled());
  phantoms_for_dragging_.reset();
}

void OverviewItem::SetShadowBounds(base::Optional<gfx::Rect> bounds_in_screen) {
  // Shadow is normally turned off during animations and reapplied when they
  // are finished. On destruction, |shadow_| is cleaned up before
  // |transform_window_|, which may call this function, so early exit if
  // |shadow_| is nullptr.
  if (!shadow_)
    return;

  if (bounds_in_screen == base::nullopt) {
    shadow_->layer()->SetVisible(false);
    return;
  }

  shadow_->layer()->SetVisible(true);
  gfx::Rect bounds_in_item =
      gfx::Rect(item_widget_->GetNativeWindow()->GetTargetBounds().size());
  bounds_in_item.Inset(kOverviewMargin, kOverviewMargin);
  bounds_in_item.Inset(0, kHeaderHeightDp, 0, 0);
  bounds_in_item.ClampToCenteredSize(bounds_in_screen.value().size());

  shadow_->SetContentBounds(bounds_in_item);
}

void OverviewItem::UpdateRoundedCornersAndShadow() {
  // Do not show the rounded corners and the shadow if overview is shutting
  // down or we're currently in entering overview animation. Also don't update
  // or animate the window's frame header clip under these conditions.
  OverviewController* overview_controller = Shell::Get()->overview_controller();
  const bool is_shutting_down =
      !overview_controller || !overview_controller->InOverviewSession();
  const bool should_show_rounded_corners =
      !disable_mask_ && !is_shutting_down &&
      !overview_controller->IsInStartAnimation();

  transform_window_.UpdateRoundedCorners(
      should_show_rounded_corners,
      /*update_clip=*/should_show_rounded_corners);

  // In addition, the shadow should be hidden if
  // 1) this overview item is the drop target window or
  // 2) this overview item is in animation.
  const bool should_show_shadow =
      should_show_rounded_corners &&
      !overview_grid_->IsDropTargetWindow(GetWindow()) &&
      !transform_window_.GetOverviewWindow()
           ->layer()
           ->GetAnimator()
           ->is_animating();

  SetShadowBounds(should_show_shadow
                      ? base::make_optional(gfx::ToEnclosedRect(
                            transform_window_.GetTransformedBounds()))
                      : base::nullopt);
  if (transform_window_.IsMinimized()) {
    caption_container_view_->UpdatePreviewRoundedCorners(
        should_show_rounded_corners,
        views::LayoutProvider::Get()->GetCornerRadiusMetric(
            views::EMPHASIS_LOW));
  }
}

void OverviewItem::OnStartingAnimationComplete() {
  DCHECK(item_widget_);
  if (transform_window_.IsMinimized()) {
    // Fade the title in if minimized. The rest of |item_widget_| should
    // already be shown.
    caption_container_view_->SetHeaderVisibility(
        CaptionContainerView::HeaderVisibility::kVisible);
  } else {
    FadeInWidgetAndMaybeSlideOnEnter(
        item_widget_.get(), OVERVIEW_ANIMATION_ENTER_OVERVIEW_MODE_FADE_IN,
        /*slide=*/false, /*observe=*/false);
  }
  const bool show_backdrop =
      GetWindowDimensionsType() !=
      ScopedOverviewTransformWindow::GridWindowFillMode::kNormal;
  caption_container_view_->SetBackdropVisibility(show_backdrop);
  UpdateCannotSnapWarningVisibility();
}

void OverviewItem::StopWidgetAnimation() {
  DCHECK(item_widget_.get());
  item_widget_->GetNativeWindow()->layer()->GetAnimator()->StopAnimating();
}

void OverviewItem::SetOpacity(float opacity) {
  item_widget_->SetOpacity(opacity);
  transform_window_.SetOpacity(opacity);
  if (cannot_snap_widget_)
    cannot_snap_widget_->SetOpacity(opacity);
}

float OverviewItem::GetOpacity() {
  return item_widget_->GetNativeWindow()->layer()->GetTargetOpacity();
}

OverviewAnimationType OverviewItem::GetExitOverviewAnimationType() {
  if (overview_session_->enter_exit_overview_type() ==
      OverviewSession::EnterExitOverviewType::kImmediateExit) {
    return OVERVIEW_ANIMATION_NONE;
  }

  return should_animate_when_exiting_
             ? OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_EXIT
             : OVERVIEW_ANIMATION_NONE;
}

OverviewAnimationType OverviewItem::GetExitTransformAnimationType() {
  if (overview_session_->enter_exit_overview_type() ==
      OverviewSession::EnterExitOverviewType::kImmediateExit) {
    return OVERVIEW_ANIMATION_NONE;
  }

  return should_animate_when_exiting_ ? OVERVIEW_ANIMATION_RESTORE_WINDOW
                                      : OVERVIEW_ANIMATION_RESTORE_WINDOW_ZERO;
}

void OverviewItem::HandleMouseEvent(const ui::MouseEvent& event) {
  const gfx::PointF screen_location = event.target()->GetScreenLocationF(event);
  switch (event.type()) {
    case ui::ET_MOUSE_PRESSED:
      HandlePressEvent(screen_location, /*from_touch_gesture=*/false);
      break;
    case ui::ET_MOUSE_RELEASED:
      HandleReleaseEvent(screen_location);
      break;
    case ui::ET_MOUSE_DRAGGED:
      HandleDragEvent(screen_location);
      break;
    default:
      NOTREACHED();
      break;
  }
}

void OverviewItem::HandleGestureEvent(ui::GestureEvent* event) {
  if (ShouldUseTabletModeGridLayout()) {
    HandleGestureEventForTabletModeLayout(event);
    return;
  }

  const gfx::PointF location = event->details().bounding_box_f().CenterPoint();
  switch (event->type()) {
    case ui::ET_GESTURE_TAP_DOWN:
      HandlePressEvent(location, /*from_touch_gesture=*/true);
      break;
    case ui::ET_GESTURE_SCROLL_UPDATE:
      HandleDragEvent(location);
      break;
    case ui::ET_SCROLL_FLING_START:
      HandleFlingStartEvent(location, event->details().velocity_x(),
                            event->details().velocity_y());
      break;
    case ui::ET_GESTURE_SCROLL_END:
      HandleReleaseEvent(location);
      break;
    case ui::ET_GESTURE_LONG_PRESS:
      HandleLongPressEvent(location);
      break;
    case ui::ET_GESTURE_TAP:
      HandleTapEvent();
      break;
    case ui::ET_GESTURE_END:
      HandleGestureEndEvent();
      break;
    default:
      break;
  }
}

void OverviewItem::HandleGestureEventForTabletModeLayout(
    ui::GestureEvent* event) {
  const gfx::PointF location = event->details().bounding_box_f().CenterPoint();
  switch (event->type()) {
    case ui::ET_SCROLL_FLING_START:
      if (IsDragItem()) {
        HandleFlingStartEvent(location, event->details().velocity_x(),
                              event->details().velocity_y());
      } else {
        overview_grid()->grid_event_handler()->OnGestureEvent(event);
      }
      break;
    case ui::ET_GESTURE_SCROLL_BEGIN:
      if (std::abs(event->details().scroll_y_hint()) >
          std::abs(event->details().scroll_x_hint())) {
        HandlePressEvent(location, /*from_touch_gesture=*/true);
      } else {
        overview_grid()->grid_event_handler()->OnGestureEvent(event);
      }
      break;
    case ui::ET_GESTURE_SCROLL_UPDATE:
      if (IsDragItem())
        HandleDragEvent(location);
      else
        overview_grid()->grid_event_handler()->OnGestureEvent(event);
      break;
    case ui::ET_GESTURE_SCROLL_END:
      if (IsDragItem())
        HandleReleaseEvent(location);
      else
        overview_grid()->grid_event_handler()->OnGestureEvent(event);
      break;
    case ui::ET_GESTURE_LONG_PRESS:
      HandlePressEvent(location, /*from_touch_gesture=*/true);
      HandleLongPressEvent(location);
      break;
    case ui::ET_GESTURE_TAP:
      overview_session_->SelectWindow(this);
      break;
    case ui::ET_GESTURE_END:
      HandleGestureEndEvent();
      break;
    default:
      overview_grid()->grid_event_handler()->OnGestureEvent(event);
      break;
  }
}

bool OverviewItem::ShouldIgnoreGestureEvents() {
  return IsSlidingOutOverviewFromShelf();
}

void OverviewItem::OnHighlightedViewActivated() {
  overview_session_->OnHighlightedItemActivated(this);
}

void OverviewItem::OnHighlightedViewClosed() {
  overview_session_->OnHighlightedItemClosed(this);
}

void OverviewItem::ButtonPressed(views::Button* sender,
                                 const ui::Event& event) {
  DCHECK_EQ(sender, close_button_);
  if (IsSlidingOutOverviewFromShelf())
    return;

  base::RecordAction(
      base::UserMetricsAction("WindowSelector_OverviewCloseButton"));
  if (Shell::Get()->tablet_mode_controller()->InTabletMode()) {
    base::RecordAction(
        base::UserMetricsAction("Tablet_WindowCloseFromOverviewButton"));
  }
  CloseWindow();
}

void OverviewItem::OnWindowPropertyChanged(aura::Window* window,
                                           const void* key,
                                           intptr_t old) {
  if (prepared_for_overview_ && window == GetWindow() &&
      key == aura::client::kTopViewInset &&
      window->GetProperty(aura::client::kTopViewInset) !=
          static_cast<int>(old)) {
    overview_grid_->PositionWindows(/*animate=*/false);
  }
}

void OverviewItem::OnWindowBoundsChanged(aura::Window* window,
                                         const gfx::Rect& old_bounds,
                                         const gfx::Rect& new_bounds,
                                         ui::PropertyChangeReason reason) {
  // During preparation, window bounds can change. Ignore bounds change
  // notifications in this case; we'll reposition soon.
  if (!prepared_for_overview_)
    return;

  // Do not keep the overview bounds if we're shutting down.
  if (!Shell::Get()->overview_controller()->InOverviewSession())
    return;

  // The drop target will get its bounds set as opposed to its transform
  // set in |SetItemBounds| so do not position windows again when that
  // particular window has its bounds changed.
  aura::Window* main_window = GetWindow();
  if (overview_grid_->IsDropTargetWindow(main_window))
    return;

  if (reason == ui::PropertyChangeReason::NOT_FROM_ANIMATION) {
    if (window == main_window) {
      caption_container_view_->UpdatePreviewView();
    } else {
      // Transient window is repositioned. The new position within the
      // overview item needs to be recomputed.
      SetBounds(target_bounds_, OVERVIEW_ANIMATION_NONE);
    }
  }

  if (window != main_window)
    return;

  // Immediately finish any active bounds animation.
  window->layer()->GetAnimator()->StopAnimatingProperty(
      ui::LayerAnimationElement::BOUNDS);
  UpdateWindowDimensionsType();
  overview_grid_->PositionWindows(/*animate=*/false);
}

void OverviewItem::OnWindowDestroying(aura::Window* window) {
  // Stops observing the window and all of its transient descendents.
  for (auto* window_iter : WindowTransientDescendantIteratorRange(
           WindowTransientDescendantIterator(window))) {
    window_iter->RemoveObserver(this);
  }

  if (window != GetWindow())
    return;

  if (is_being_dragged_) {
    Shell::Get()->overview_controller()->UnpauseOcclusionTracker(
        kOcclusionPauseDurationForDrag);
  }

  overview_grid_->RemoveItem(this, /*item_destroying=*/true,
                             /*reposition=*/!animating_to_close_);
}

void OverviewItem::OnWindowTitleChanged(aura::Window* window) {
  if (window != GetWindow())
    return;

  caption_container_view_->SetTitle(window->GetTitle());
}

void OverviewItem::OnPostWindowStateTypeChange(WindowState* window_state,
                                               WindowStateType old_type) {
  // During preparation, window state can change, e.g. updating shelf
  // visibility may show the temporarily hidden (minimized) panels.
  if (!prepared_for_overview_)
    return;

  // When swiping away overview mode via shelf, windows will get minimized, but
  // we do not want show a mirrored view in this case.
  if (overview_session_->enter_exit_overview_type() ==
      OverviewSession::EnterExitOverviewType::kSwipeFromShelf) {
    return;
  }

  WindowStateType new_type = window_state->GetStateType();
  if (IsMinimizedWindowStateType(old_type) ==
      IsMinimizedWindowStateType(new_type)) {
    return;
  }

  const bool minimized = transform_window_.IsMinimized();
  caption_container_view_->SetShowPreview(minimized);
  if (!minimized)
    EnsureVisible();
  overview_grid_->PositionWindows(/*animate=*/false);
}

views::ImageButton* OverviewItem::GetCloseButtonForTesting() {
  return static_cast<views::ImageButton*>(close_button_);
}

float OverviewItem::GetCloseButtonVisibilityForTesting() const {
  return close_button_->layer()->opacity();
}

float OverviewItem::GetTitlebarOpacityForTesting() const {
  return caption_container_view_->header_view()->layer()->opacity();
}

gfx::Rect OverviewItem::GetShadowBoundsForTesting() {
  if (!shadow_ || !shadow_->layer()->visible())
    return gfx::Rect();

  return shadow_->content_bounds();
}

gfx::RectF OverviewItem::GetWindowTargetBoundsWithInsets() const {
  gfx::RectF window_target_bounds = target_bounds_;
  window_target_bounds.Inset(kWindowMargin, kWindowMargin);
  window_target_bounds.Inset(0, kHeaderHeightDp, 0, 0);
  return window_target_bounds;
}

void OverviewItem::OnWindowCloseAnimationCompleted() {
  transform_window_.Close();
}

void OverviewItem::OnItemSpawnedAnimationCompleted() {
  UpdateRoundedCornersAndShadow();
  OnDragAnimationCompleted();
  OnStartingAnimationComplete();
}

void OverviewItem::OnItemBoundsAnimationStarted() {
  // Remove the shadow before animating because it may affect animation
  // performance. The shadow will be added back once the animation is completed.
  // Note that we can't use UpdateRoundedCornersAndShadow() since we don't want
  // to update the rounded corners.
  SetShadowBounds(base::nullopt);
}

void OverviewItem::OnItemBoundsAnimationEnded() {
  UpdateRoundedCornersAndShadow();
  OnDragAnimationCompleted();
}

void OverviewItem::PerformItemSpawnedAnimation(
    aura::Window* window,
    const gfx::Transform& target_transform) {
  DCHECK(should_use_spawn_animation_);
  should_use_spawn_animation_ = false;

  constexpr float kInitialScaler = 0.1f;
  constexpr float kTargetScaler = 1.0f;

  // Scale-up |window| and fade it in along with the |cannot_snap_widget_|'s
  // window.
  gfx::Transform initial_transform = target_transform;
  initial_transform.Scale(kInitialScaler, kInitialScaler);
  SetTransform(window, initial_transform);
  transform_window_.SetOpacity(kInitialScaler);

  ScopedOverviewTransformWindow::ScopedAnimationSettings animation_settings;
  for (auto* window_iter : GetVisibleTransientTreeIterator(window)) {
    auto settings = std::make_unique<ScopedOverviewAnimationSettings>(
        OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW, window_iter);
    settings->DeferPaint();
    animation_settings.push_back(std::move(settings));
  }

  if (!animation_settings.empty()) {
    animation_settings.front()->AddObserver(new AnimationObserver{
        base::BindOnce(&OverviewItem::OnItemSpawnedAnimationCompleted,
                       weak_ptr_factory_.GetWeakPtr())});
  }
  SetTransform(window, target_transform);
  transform_window_.SetOpacity(kTargetScaler);

  if (cannot_snap_widget_) {
    aura::Window* cannot_snap_window = cannot_snap_widget_->GetNativeWindow();
    cannot_snap_window->layer()->SetOpacity(kInitialScaler);
    ScopedOverviewAnimationSettings label_animation_settings(
        OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW, cannot_snap_window);
    cannot_snap_window->layer()->SetOpacity(kTargetScaler);
  }
}

void OverviewItem::SetItemBounds(const gfx::RectF& target_bounds,
                                 OverviewAnimationType animation_type,
                                 bool is_first_update) {
  aura::Window* window = GetWindow();
  DCHECK(root_window_ == window->GetRootWindow());
  // Do not set transform for drop target, set bounds instead.
  if (overview_grid_->IsDropTargetWindow(window)) {
    window->SetBoundsInScreen(
        gfx::ToEnclosedRect(GetWindowTargetBoundsWithInsets()),
        WindowState::Get(window)->GetDisplay());
    window->SetTransform(gfx::Transform());
    return;
  }

  gfx::RectF screen_rect = gfx::RectF(GetTargetBoundsInScreen());

  // Avoid division by zero by ensuring screen bounds is not empty.
  gfx::SizeF screen_size(screen_rect.size());
  screen_size.SetToMax(gfx::SizeF(1.f, 1.f));
  screen_rect.set_size(screen_size);

  const int top_view_inset = transform_window_.GetTopInset();
  gfx::RectF transformed_bounds = target_bounds;
  // Update |transformed_bounds| to match the unclipped size of the window, so
  // we transform the window to the correct size.
  if (unclipped_size_)
    transformed_bounds.set_size(gfx::SizeF(*unclipped_size_));

  gfx::RectF overview_item_bounds =
      transform_window_.ShrinkRectToFitPreservingAspectRatio(
          screen_rect, transformed_bounds, top_view_inset, kHeaderHeightDp);

  const gfx::Transform transform =
      gfx::TransformBetweenRects(screen_rect, overview_item_bounds);

  if (is_first_update &&
      animation_type == OVERVIEW_ANIMATION_SPAWN_ITEM_IN_OVERVIEW) {
    PerformItemSpawnedAnimation(window, transform);
    return;
  }

  {
    ScopedOverviewTransformWindow::ScopedAnimationSettings animation_settings;
    transform_window_.BeginScopedAnimation(animation_type, &animation_settings);
    if (animation_type ==
            OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_IN_OVERVIEW &&
        !animation_settings.empty()) {
      animation_settings.front()->AddObserver(new AnimationObserver{
          base::BindOnce(&OverviewItem::OnItemBoundsAnimationStarted,
                         weak_ptr_factory_.GetWeakPtr()),
          base::BindOnce(&OverviewItem::OnItemBoundsAnimationEnded,
                         weak_ptr_factory_.GetWeakPtr())});
    }
    SetTransform(window, transform);
  }

  transform_window_.SetClipping(unclipped_size_
                                    ? GetWindowTargetBoundsWithInsets().size()
                                    : gfx::SizeF());
}

void OverviewItem::CreateWindowLabel() {
  views::Widget::InitParams params;
  params.type = views::Widget::InitParams::TYPE_POPUP;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.visible_on_all_workspaces = true;
  params.layer_type = ui::LAYER_NOT_DRAWN;
  params.name = "OverviewModeLabel";
  params.activatable =
      views::Widget::InitParams::Activatable::ACTIVATABLE_DEFAULT;
  params.accept_events = true;
  params.parent = transform_window_.window()->parent();
  params.init_properties_container.SetProperty(kHideInDeskMiniViewKey, true);

  item_widget_ = std::make_unique<views::Widget>();
  item_widget_->set_focus_on_creation(false);
  item_widget_->Init(std::move(params));
  aura::Window* widget_window = item_widget_->GetNativeWindow();
  widget_window->parent()->StackChildBelow(widget_window, GetWindow());

  shadow_ = std::make_unique<ui::Shadow>();
  shadow_->Init(kShadowElevation);
  item_widget_->GetLayer()->Add(shadow_->layer());

  close_button_ = new OverviewCloseButton(this);
  caption_container_view_ = new CaptionContainerView(
      this, GetWindow(), transform_window_.IsMinimized(), close_button_);
  item_widget_->SetContentsView(caption_container_view_);
  item_widget_->Show();
  item_widget_->SetOpacity(0.f);
  item_widget_->GetLayer()->SetMasksToBounds(false);
}

void OverviewItem::UpdateHeaderLayout(OverviewAnimationType animation_type) {
  aura::Window* widget_window = item_widget_->GetNativeWindow();
  ScopedOverviewAnimationSettings animation_settings(animation_type,
                                                     widget_window);
  // Create a start animation observer if this is an enter overview layout
  // animation.
  if (animation_type == OVERVIEW_ANIMATION_LAYOUT_OVERVIEW_ITEMS_ON_ENTER) {
    auto enter_observer = std::make_unique<EnterAnimationObserver>();
    animation_settings.AddObserver(enter_observer.get());
    Shell::Get()->overview_controller()->AddEnterAnimationObserver(
        std::move(enter_observer));
  }

  gfx::RectF item_bounds = target_bounds_;
  ::wm::TranslateRectFromScreen(root_window_, &item_bounds);
  const gfx::Point origin = gfx::ToRoundedPoint(item_bounds.origin());
  item_bounds.set_origin(gfx::PointF());
  item_bounds.Inset(-kWindowMargin, -kWindowMargin);
  widget_window->SetBounds(gfx::ToEnclosedRect(item_bounds));

  gfx::Transform label_transform;
  label_transform.Translate(origin.x(), origin.y());
  widget_window->SetTransform(label_transform);
}

void OverviewItem::AnimateOpacity(float opacity,
                                  OverviewAnimationType animation_type) {
  DCHECK_GE(opacity, 0.f);
  DCHECK_LE(opacity, 1.f);
  ScopedOverviewTransformWindow::ScopedAnimationSettings animation_settings;
  transform_window_.BeginScopedAnimation(animation_type, &animation_settings);
  transform_window_.SetOpacity(opacity);

  ScopedOverviewAnimationSettings animation_settings_label(
      animation_type, item_widget_->GetNativeWindow());
  item_widget_->SetOpacity(opacity);

  if (cannot_snap_widget_) {
    aura::Window* cannot_snap_widget_window =
        cannot_snap_widget_->GetNativeWindow();
    ScopedOverviewAnimationSettings animation_settings_label(
        animation_type, cannot_snap_widget_window);
    cannot_snap_widget_window->layer()->SetOpacity(opacity);
  }
}

void OverviewItem::HandlePressEvent(const gfx::PointF& location_in_screen,
                                    bool from_touch_gesture) {
  // We allow switching finger while dragging, but do not allow dragging two
  // or more items.
  if (overview_session_->window_drag_controller() &&
      overview_session_->window_drag_controller()->item()) {
    return;
  }

  StartDrag();
  overview_session_->InitiateDrag(this, location_in_screen,
                                  /*is_touch_dragging=*/from_touch_gesture);
}

void OverviewItem::HandleReleaseEvent(const gfx::PointF& location_in_screen) {
  if (!IsDragItem())
    return;

  overview_session_->CompleteDrag(this, location_in_screen);
}

void OverviewItem::HandleDragEvent(const gfx::PointF& location_in_screen) {
  if (!IsDragItem())
    return;

  overview_session_->Drag(this, location_in_screen);
}

void OverviewItem::HandleLongPressEvent(const gfx::PointF& location_in_screen) {
  if (!IsDragItem())
    return;

  if (ShouldAllowSplitView() || desks_util::ShouldDesksBarBeCreated())
    overview_session_->StartNormalDragMode(location_in_screen);
}

void OverviewItem::HandleFlingStartEvent(const gfx::PointF& location_in_screen,
                                         float velocity_x,
                                         float velocity_y) {
  overview_session_->Fling(this, location_in_screen, velocity_x, velocity_y);
}

void OverviewItem::HandleTapEvent() {
  if (!IsDragItem())
    return;

  overview_session_->ActivateDraggedWindow();
}

void OverviewItem::HandleGestureEndEvent() {
  if (!IsDragItem())
    return;

  overview_session_->ResetDraggedWindowGesture();
}

void OverviewItem::StartDrag() {
  aura::Window* widget_window = item_widget_->GetNativeWindow();
  aura::Window* window = GetWindow();
  if (widget_window && widget_window->parent() == window->parent()) {
    // TODO(xdai): This might not work if there is an always on top window.
    // See crbug.com/733760.
    widget_window->parent()->StackChildAtTop(window);
    widget_window->parent()->StackChildBelow(widget_window, window);
  }
}

aura::Window::Windows OverviewItem::GetWindowsForHomeGesture() {
  aura::Window::Windows windows = {item_widget_->GetNativeWindow()};
  if (!transform_window_.IsMinimized()) {
    for (auto* window : GetTransientTreeIterator(GetWindow()))
      windows.push_back(window);
  }
  if (cannot_snap_widget_)
    windows.push_back(cannot_snap_widget_->GetNativeWindow());
  return windows;
}

}  // namespace ash
