// Copyright 2017 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/splitview/split_view_divider.h"

#include <memory>

#include "ash/display/screen_orientation_controller.h"
#include "ash/public/cpp/ash_constants.h"
#include "ash/public/cpp/shell_window_ids.h"
#include "ash/screen_util.h"
#include "ash/shell.h"
#include "ash/wm/overview/rounded_rect_view.h"
#include "ash/wm/splitview/split_view_controller.h"
#include "ash/wm/splitview/split_view_utils.h"
#include "ash/wm/window_util.h"
#include "base/sequenced_task_runner.h"
#include "base/stl_util.h"
#include "ui/aura/scoped_window_targeter.h"
#include "ui/aura/window_targeter.h"
#include "ui/compositor/layer.h"
#include "ui/compositor/scoped_layer_animation_settings.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/animation/tween.h"
#include "ui/gfx/canvas.h"
#include "ui/views/view.h"
#include "ui/views/view_targeter_delegate.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"
#include "ui/wm/core/coordinate_conversion.h"
#include "ui/wm/core/transient_window_manager.h"
#include "ui/wm/core/window_util.h"
#include "ui/wm/public/activation_client.h"

namespace ash {

namespace {

// The length of short side of the black bar of the divider in dp.
constexpr int kDividerShortSideLength = 8;
constexpr int kDividerEnlargedShortSideLength = 16;

// The length of the white bar of the divider in dp.
constexpr int kWhiteBarShortSideLength = 2;
constexpr int kWhiteBarLongSideLength = 16;
constexpr int kWhiteBarRadius = 4;
constexpr int kWhiteBarCornerRadius = 1;

constexpr SkColor kDividerBackgroundColor = SK_ColorBLACK;
constexpr SkColor kWhiteBarBackgroundColor = SK_ColorWHITE;
constexpr int kDividerBoundsChangeDurationMs = 250;
constexpr int kWhiteBarBoundsChangeDurationMs = 150;

// The distance to the divider edge in which a touch gesture will be considered
// as a valid event on the divider.
constexpr int kDividerEdgeInsetForTouch = 8;

// The window targeter that is installed on the always on top container window
// when the split view mode is active.
class AlwaysOnTopWindowTargeter : public aura::WindowTargeter {
 public:
  explicit AlwaysOnTopWindowTargeter(aura::Window* divider_window)
      : divider_window_(divider_window) {}
  ~AlwaysOnTopWindowTargeter() override = default;

 private:
  bool GetHitTestRects(aura::Window* target,
                       gfx::Rect* hit_test_rect_mouse,
                       gfx::Rect* hit_test_rect_touch) const override {
    if (target == divider_window_) {
      *hit_test_rect_mouse = *hit_test_rect_touch = gfx::Rect(target->bounds());
      hit_test_rect_touch->Inset(
          gfx::Insets(-kDividerEdgeInsetForTouch, -kDividerEdgeInsetForTouch));
      return true;
    }
    return aura::WindowTargeter::GetHitTestRects(target, hit_test_rect_mouse,
                                                 hit_test_rect_touch);
  }

  aura::Window* divider_window_;

  DISALLOW_COPY_AND_ASSIGN(AlwaysOnTopWindowTargeter);
};

// The white handler bar in the middle of the divider.
class DividerHandlerView : public RoundedRectView {
 public:
  DividerHandlerView(int corner_radius, SkColor background_color)
      : RoundedRectView(corner_radius, background_color) {}
  ~DividerHandlerView() override = default;

  // views::View:
  void OnPaint(gfx::Canvas* canvas) override {
    views::View::OnPaint(canvas);
    // It's needed to avoid artifacts when tapping on the divider quickly.
    canvas->DrawColor(SK_ColorTRANSPARENT, SkBlendMode::kSrc);
    RoundedRectView::OnPaint(canvas);
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(DividerHandlerView);
};

// The divider view class. Passes the mouse/gesture events to the controller.
class DividerView : public views::View,
                    public views::ViewTargeterDelegate,
                    public gfx::AnimationDelegate {
 public:
  explicit DividerView(SplitViewDivider* divider)
      : controller_(Shell::Get()->split_view_controller()),
        divider_(divider),
        white_bar_animation_(this) {
    divider_view_ = new views::View();
    divider_view_->SetPaintToLayer(ui::LAYER_SOLID_COLOR);
    divider_view_->layer()->SetColor(kDividerBackgroundColor);

    divider_handler_view_ =
        new DividerHandlerView(kWhiteBarCornerRadius, kWhiteBarBackgroundColor);
    divider_handler_view_->SetPaintToLayer();

    AddChildView(divider_view_);
    AddChildView(divider_handler_view_);

    SetEventTargeter(
        std::unique_ptr<views::ViewTargeter>(new views::ViewTargeter(this)));
    white_bar_animation_.SetSlideDuration(kWhiteBarBoundsChangeDurationMs);
    white_bar_animation_.SetTweenType(gfx::Tween::EASE_IN);
  }
  ~DividerView() override { white_bar_animation_.Stop(); }

  // views::View:
  void Layout() override {
    divider_view_->SetBoundsRect(GetLocalBounds());
    UpdateWhiteHandlerBounds();
  }

  bool OnMousePressed(const ui::MouseEvent& event) override {
    gfx::Point location(event.location());
    views::View::ConvertPointToScreen(this, &location);
    controller_->StartResize(location);
    OnResizeStatusChanged();
    return true;
  }

  bool OnMouseDragged(const ui::MouseEvent& event) override {
    gfx::Point location(event.location());
    views::View::ConvertPointToScreen(this, &location);
    controller_->Resize(location);
    return true;
  }

  void OnMouseReleased(const ui::MouseEvent& event) override {
    gfx::Point location(event.location());
    views::View::ConvertPointToScreen(this, &location);
    controller_->EndResize(location);
    OnResizeStatusChanged();
    if (event.GetClickCount() == 2)
      controller_->SwapWindows();
  }

  void OnGestureEvent(ui::GestureEvent* event) override {
    gfx::Point location(event->location());
    views::View::ConvertPointToScreen(this, &location);
    switch (event->type()) {
      case ui::ET_GESTURE_TAP:
        if (event->details().tap_count() == 2)
          controller_->SwapWindows();
        break;
      case ui::ET_GESTURE_TAP_DOWN:
      case ui::ET_GESTURE_SCROLL_BEGIN:
        controller_->StartResize(location);
        OnResizeStatusChanged();
        break;
      case ui::ET_GESTURE_SCROLL_UPDATE:
        controller_->Resize(location);
        break;
      case ui::ET_GESTURE_END:
        controller_->EndResize(location);
        OnResizeStatusChanged();
        break;
      default:
        break;
    }
    event->SetHandled();
  }

  // views::ViewTargeterDelegate:
  bool DoesIntersectRect(const views::View* target,
                         const gfx::Rect& rect) const override {
    DCHECK_EQ(target, this);
    return true;
  }

  // gfx::AnimationDelegate:
  void AnimationEnded(const gfx::Animation* animation) override {
    UpdateWhiteHandlerBounds();
  }

  void AnimationProgressed(const gfx::Animation* animation) override {
    UpdateWhiteHandlerBounds();
  }

  void AnimationCanceled(const gfx::Animation* animation) override {
    UpdateWhiteHandlerBounds();
  }

 private:
  void OnResizeStatusChanged() {
    // It's possible that when this function is called, split view mode has
    // been ended, and the divider widget is to be deleted soon. In this case
    // no need to update the divider layout and do the animation.
    if (!controller_->IsSplitViewModeActive())
      return;

    // Do the white handler bar enlarge/shrink animation when starting/ending
    // dragging.
    if (controller_->is_resizing())
      white_bar_animation_.Show();
    else
      white_bar_animation_.Hide();

    // Do the divider enlarge/shrink animation when starting/ending dragging.
    divider_view_->SetBoundsRect(GetLocalBounds());
    const gfx::Rect old_bounds =
        divider_->GetDividerBoundsInScreen(/*is_dragging=*/false);
    const gfx::Rect new_bounds =
        divider_->GetDividerBoundsInScreen(controller_->is_resizing());
    gfx::Transform transform;
    transform.Translate(new_bounds.x() - old_bounds.x(),
                        new_bounds.y() - old_bounds.y());
    transform.Scale(
        static_cast<float>(new_bounds.width()) / old_bounds.width(),
        static_cast<float>(new_bounds.height()) / old_bounds.height());
    ui::ScopedLayerAnimationSettings settings(
        divider_view_->layer()->GetAnimator());
    settings.SetTransitionDuration(
        base::TimeDelta::FromMilliseconds(kDividerBoundsChangeDurationMs));
    settings.SetTweenType(gfx::Tween::FAST_OUT_SLOW_IN);
    settings.SetPreemptionStrategy(
        ui::LayerAnimator::IMMEDIATELY_ANIMATE_TO_NEW_TARGET);
    divider_view_->SetTransform(transform);
  }

  // Returns the expected bounds of the white divider handler.
  void UpdateWhiteHandlerBounds() {
    // Calculate the width/height/radius for the rounded rectangle.
    int width, height, radius;
    const int expected_width_unselected = IsCurrentScreenOrientationLandscape()
                                              ? kWhiteBarShortSideLength
                                              : kWhiteBarLongSideLength;
    const int expected_height_unselected = IsCurrentScreenOrientationLandscape()
                                               ? kWhiteBarLongSideLength
                                               : kWhiteBarShortSideLength;
    if (white_bar_animation_.is_animating()) {
      width = white_bar_animation_.CurrentValueBetween(
          expected_width_unselected, kWhiteBarRadius * 2);
      height = white_bar_animation_.CurrentValueBetween(
          expected_height_unselected, kWhiteBarRadius * 2);
      radius = white_bar_animation_.CurrentValueBetween(kWhiteBarCornerRadius,
                                                        kWhiteBarRadius);
    } else {
      if (controller_->is_resizing()) {
        width = kWhiteBarRadius * 2;
        height = kWhiteBarRadius * 2;
        radius = kWhiteBarRadius;
      } else {
        width = expected_width_unselected;
        height = expected_height_unselected;
        radius = kWhiteBarCornerRadius;
      }
    }

    gfx::Rect white_bar_bounds(GetLocalBounds());
    white_bar_bounds.ClampToCenteredSize(gfx::Size(width, height));
    divider_handler_view_->SetCornerRadius(radius);
    divider_handler_view_->SetBoundsRect(white_bar_bounds);
  }

  views::View* divider_view_ = nullptr;
  DividerHandlerView* divider_handler_view_ = nullptr;
  SplitViewController* controller_;
  SplitViewDivider* divider_;
  gfx::SlideAnimation white_bar_animation_;

  DISALLOW_COPY_AND_ASSIGN(DividerView);
};

}  // namespace

SplitViewDivider::SplitViewDivider(SplitViewController* controller,
                                   aura::Window* root_window)
    : controller_(controller) {
  Shell::Get()->activation_client()->AddObserver(this);
  CreateDividerWidget(root_window);

  aura::Window* always_on_top_container =
      Shell::GetContainer(root_window, kShellWindowId_AlwaysOnTopContainer);
  split_view_window_targeter_ = std::make_unique<aura::ScopedWindowTargeter>(
      always_on_top_container, std::make_unique<AlwaysOnTopWindowTargeter>(
                                   divider_widget_->GetNativeWindow()));
}

SplitViewDivider::~SplitViewDivider() {
  Shell::Get()->activation_client()->RemoveObserver(this);
  divider_widget_->Close();
  split_view_window_targeter_.reset();
  for (auto* iter : observed_windows_)
    iter->RemoveObserver(this);
  observed_windows_.clear();
}

// static
gfx::Size SplitViewDivider::GetDividerSize(
    const gfx::Rect& work_area_bounds,
    OrientationLockType screen_orientation,
    bool is_dragging) {
  if (IsLandscapeOrientation(screen_orientation)) {
    return is_dragging
               ? gfx::Size(kDividerEnlargedShortSideLength,
                           work_area_bounds.height())
               : gfx::Size(kDividerShortSideLength, work_area_bounds.height());
  } else {
    return is_dragging
               ? gfx::Size(work_area_bounds.width(),
                           kDividerEnlargedShortSideLength)
               : gfx::Size(work_area_bounds.width(), kDividerShortSideLength);
  }
}

// static
gfx::Rect SplitViewDivider::GetDividerBoundsInScreen(
    const gfx::Rect& work_area_bounds_in_screen,
    OrientationLockType screen_orientation,
    int divider_position,
    bool is_dragging) {
  const gfx::Size divider_size = GetDividerSize(
      work_area_bounds_in_screen, screen_orientation, is_dragging);
  int dragging_diff =
      (kDividerEnlargedShortSideLength - kDividerShortSideLength) / 2;
  switch (screen_orientation) {
    case OrientationLockType::kLandscapePrimary:
    case OrientationLockType::kLandscapeSecondary:
      return is_dragging
                 ? gfx::Rect(work_area_bounds_in_screen.x() + divider_position -
                                 dragging_diff,
                             work_area_bounds_in_screen.y(),
                             divider_size.width(), divider_size.height())
                 : gfx::Rect(work_area_bounds_in_screen.x() + divider_position,
                             work_area_bounds_in_screen.y(),
                             divider_size.width(), divider_size.height());
    case OrientationLockType::kPortraitPrimary:
    case OrientationLockType::kPortraitSecondary:
      return is_dragging
                 ? gfx::Rect(work_area_bounds_in_screen.x(),
                             work_area_bounds_in_screen.y() + divider_position -
                                 (kDividerEnlargedShortSideLength -
                                  kDividerShortSideLength) /
                                     2,
                             divider_size.width(), divider_size.height())
                 : gfx::Rect(work_area_bounds_in_screen.x(),
                             work_area_bounds_in_screen.y() + divider_position,
                             divider_size.width(), divider_size.height());
    default:
      NOTREACHED();
      return gfx::Rect();
  }
}

void SplitViewDivider::UpdateDividerBounds() {
  divider_widget_->SetBounds(GetDividerBoundsInScreen(/*is_dragging=*/false));
}

gfx::Rect SplitViewDivider::GetDividerBoundsInScreen(bool is_dragging) {
  aura::Window* root_window =
      divider_widget_->GetNativeWindow()->GetRootWindow();
  const gfx::Rect work_area_bounds_in_screen =
      screen_util::GetDisplayWorkAreaBoundsInScreenForDefaultContainer(
          root_window);
  const int divider_position = controller_->divider_position();
  const OrientationLockType screen_orientation = GetCurrentScreenOrientation();
  return GetDividerBoundsInScreen(work_area_bounds_in_screen,
                                  screen_orientation, divider_position,
                                  is_dragging);
}

void SplitViewDivider::AddObservedWindow(aura::Window* window) {
  if (!base::ContainsValue(observed_windows_, window)) {
    window->AddObserver(this);
    ::wm::TransientWindowManager::GetOrCreate(window)->AddObserver(this);
    observed_windows_.push_back(window);
  }
}

void SplitViewDivider::RemoveObservedWindow(aura::Window* window) {
  auto iter =
      std::find(observed_windows_.begin(), observed_windows_.end(), window);
  if (iter != observed_windows_.end()) {
    window->RemoveObserver(this);
    ::wm::TransientWindowManager::GetOrCreate(window)->RemoveObserver(this);
    observed_windows_.erase(iter);
  }
}

void SplitViewDivider::OnWindowDragStarted(aura::Window* dragged_window) {
  is_dragging_window_ = true;
  SetAlwaysOnTop(false);
  // Make sure |divider_widget_| is placed below the dragged window.
  dragged_window->parent()->StackChildBelow(divider_widget_->GetNativeWindow(),
                                            dragged_window);
}

void SplitViewDivider::OnWindowDragEnded() {
  is_dragging_window_ = false;
  SetAlwaysOnTop(true);
}

void SplitViewDivider::OnWindowDestroying(aura::Window* window) {
  RemoveObservedWindow(window);
}

void SplitViewDivider::OnWindowBoundsChanged(aura::Window* window,
                                             const gfx::Rect& old_bounds,
                                             const gfx::Rect& new_bounds,
                                             ui::PropertyChangeReason reason) {
  // We only care about the bounds change of windows in
  // |transient_windows_observer_|.
  if (!transient_windows_observer_.IsObserving(window))
    return;

  // |window|'s transient parent must be one of the windows in
  // |observed_windows_|.
  aura::Window* transient_parent = nullptr;
  for (auto* observed_window : observed_windows_) {
    if (::wm::HasTransientAncestor(window, observed_window)) {
      transient_parent = observed_window;
      break;
    }
  }
  DCHECK(transient_parent);

  gfx::Rect transient_bounds = window->GetBoundsInScreen();
  transient_bounds.AdjustToFit(transient_parent->GetBoundsInScreen());
  window->SetBoundsInScreen(
      transient_bounds,
      display::Screen::GetScreen()->GetDisplayNearestWindow(window));
}

void SplitViewDivider::OnWindowActivated(ActivationReason reason,
                                         aura::Window* gained_active,
                                         aura::Window* lost_active) {
  if (!is_dragging_window_ &&
      (!gained_active ||
       base::ContainsValue(observed_windows_, gained_active))) {
    SetAlwaysOnTop(true);
  } else {
    // If |gained_active| is not one of the observed windows, or there is one
    // window that is currently being dragged, |divider_widget_| should not
    // be placed on top.
    SetAlwaysOnTop(false);
  }
}

void SplitViewDivider::OnTransientChildAdded(aura::Window* window,
                                             aura::Window* transient) {
  // For now, we only care about dialog bubbles type transient child. We may
  // observe other types transient child window as well if need arises in the
  // future.
  views::Widget* widget = views::Widget::GetWidgetForNativeWindow(transient);
  if (!widget || !widget->widget_delegate()->AsBubbleDialogDelegate())
    return;

  // At this moment, the transient window may not have the valid bounds yet.
  // Start observe the transient window.
  transient_windows_observer_.Add(transient);
}

void SplitViewDivider::OnTransientChildRemoved(aura::Window* window,
                                               aura::Window* transient) {
  if (transient_windows_observer_.IsObserving(transient))
    transient_windows_observer_.Remove(transient);
}

void SplitViewDivider::CreateDividerWidget(aura::Window* root_window) {
  DCHECK(!divider_widget_);
  // Native widget owns this widget.
  divider_widget_ = new views::Widget;
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
  params.opacity = views::Widget::InitParams::OPAQUE_WINDOW;
  params.activatable = views::Widget::InitParams::ACTIVATABLE_NO;
  params.parent =
      Shell::GetContainer(root_window, kShellWindowId_AlwaysOnTopContainer);
  DividerView* divider_view = new DividerView(this);
  divider_widget_->set_focus_on_creation(false);
  divider_widget_->Init(params);
  divider_widget_->SetContentsView(divider_view);
  divider_widget_->SetBounds(GetDividerBoundsInScreen(false /* is_dragging */));
  divider_widget_->Show();
}

void SplitViewDivider::SetAlwaysOnTop(bool on_top) {
  if (on_top) {
    divider_widget_->SetAlwaysOnTop(true);

    // Special handling when put divider into always_on_top container. We want
    // to put it at the bottom so it won't block other always_on_top windows.
    aura::Window* always_on_top_container =
        Shell::GetContainer(divider_widget_->GetNativeWindow()->GetRootWindow(),
                            kShellWindowId_AlwaysOnTopContainer);
    always_on_top_container->StackChildAtBottom(
        divider_widget_->GetNativeWindow());
  } else {
    divider_widget_->SetAlwaysOnTop(false);
  }
}

}  // namespace ash
