// 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/shelf/overflow_bubble_view.h"

#include <algorithm>

#include "ash/public/cpp/shell_window_ids.h"
#include "ash/shelf/shelf.h"
#include "ash/shelf/shelf_constants.h"
#include "ash/shelf/shelf_view.h"
#include "ash/shelf/shelf_widget.h"
#include "ash/shell.h"
#include "ash/wm/window_util.h"
#include "base/i18n/rtl.h"
#include "ui/display/display.h"
#include "ui/display/screen.h"
#include "ui/events/event.h"
#include "ui/gfx/geometry/insets.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace {

// Padding at the two ends of the bubble.
constexpr int kEndPadding = 16;

// Distance between overflow bubble and the main shelf.
constexpr int kDistanceToMainShelf = 4;

// Minimum margin around the bubble so that it doesn't hug the screen edges.
constexpr int kMinimumMargin = 8;

}  // namespace

OverflowBubbleView::OverflowBubbleView(ShelfView* shelf_view,
                                       views::View* anchor,
                                       SkColor background_color)
    : ShelfBubble(anchor, shelf_view->shelf()->alignment(), background_color),
      shelf_(shelf_view->shelf()),
      shelf_view_(shelf_view),
      background_animator_(SHELF_BACKGROUND_DEFAULT,
                           // Don't pass the Shelf so the translucent color is
                           // always used.
                           nullptr,
                           Shell::Get()->wallpaper_controller()) {
  DCHECK(shelf_);

  set_border_radius(ShelfConstants::shelf_size() / 2);
  background_animator_.AddObserver(this);
  SetArrow(views::BubbleBorder::NONE);
  SetBackground(nullptr);
  set_shadow(views::BubbleBorder::NO_ASSETS);
  set_close_on_deactivate(false);
  set_accept_events(true);

  if (shelf_->IsHorizontalAlignment())
    set_margins(gfx::Insets(0, kEndPadding));
  else
    set_margins(gfx::Insets(kEndPadding, 0));

  // Makes bubble view has a layer and clip its children layers.
  SetPaintToLayer();
  layer()->SetFillsBoundsOpaquely(false);
  layer()->SetMasksToBounds(true);

  CreateBubble();

  AddChildView(shelf_view_);
}

OverflowBubbleView::~OverflowBubbleView() {
  background_animator_.RemoveObserver(this);
}

bool OverflowBubbleView::ProcessGestureEvent(const ui::GestureEvent& event) {
  // Handle scroll-related events, but don't do anything special for begin and
  // end.
  if (event.type() == ui::ET_GESTURE_SCROLL_BEGIN ||
      event.type() == ui::ET_GESTURE_SCROLL_END) {
    return true;
  }
  if (event.type() != ui::ET_GESTURE_SCROLL_UPDATE)
    return false;

  if (shelf_->IsHorizontalAlignment())
    ScrollByXOffset(static_cast<int>(-event.details().scroll_x()));
  else
    ScrollByYOffset(static_cast<int>(-event.details().scroll_y()));
  return true;
}

int OverflowBubbleView::ScrollByXOffset(int x_offset) {
  const gfx::Rect visible_bounds(GetContentsBounds());
  const gfx::Size contents_size(shelf_view_->GetPreferredSize());

  DCHECK_GE(contents_size.width(), visible_bounds.width());
  const int old_x = scroll_offset_.x();
  const int x = std::min(contents_size.width() - visible_bounds.width(),
                         std::max(0, old_x + x_offset));
  scroll_offset_.set_x(x);
  Layout();
  return x - old_x;
}

int OverflowBubbleView::ScrollByYOffset(int y_offset) {
  const gfx::Rect visible_bounds(GetContentsBounds());
  const gfx::Size contents_size(shelf_view_->GetPreferredSize());

  DCHECK_GE(contents_size.height(), visible_bounds.height());
  const int old_y = scroll_offset_.y();
  const int y = std::min(contents_size.height() - visible_bounds.height(),
                         std::max(0, old_y + y_offset));
  scroll_offset_.set_y(y);
  Layout();
  return y - old_y;
}

gfx::Size OverflowBubbleView::CalculatePreferredSize() const {
  gfx::Size preferred_size = shelf_view_->GetPreferredSize();

  const gfx::Rect monitor_rect =
      display::Screen::GetScreen()
          ->GetDisplayNearestPoint(GetAnchorRect().CenterPoint())
          .work_area();
  if (!monitor_rect.IsEmpty()) {
    if (shelf_->IsHorizontalAlignment()) {
      preferred_size.set_width(std::min(
          preferred_size.width(), monitor_rect.width() - 2 * kEndPadding));
    } else {
      preferred_size.set_height(std::min(
          preferred_size.height(), monitor_rect.height() - 2 * kEndPadding));
    }
  }

  return preferred_size;
}

void OverflowBubbleView::Layout() {
  shelf_view_->SetBoundsRect(
      gfx::Rect(gfx::PointAtOffsetFromOrigin(-scroll_offset_),
                shelf_view_->GetPreferredSize()));
}

void OverflowBubbleView::ChildPreferredSizeChanged(views::View* child) {
  // When contents size is changed, ContentsBounds should be updated before
  // calculating scroll offset.
  SizeToContents();

  // Ensures |shelf_view_| is still visible.
  if (shelf_->IsHorizontalAlignment())
    ScrollByXOffset(0);
  else
    ScrollByYOffset(0);
}

bool OverflowBubbleView::OnMouseWheel(const ui::MouseWheelEvent& event) {
  // The MouseWheelEvent was changed to support both X and Y offsets
  // recently, but the behavior of this function was retained to continue
  // using Y offsets only. Might be good to simply scroll in both
  // directions as in OverflowBubbleView::OnScrollEvent.
  if (shelf_->IsHorizontalAlignment())
    ScrollByXOffset(-event.y_offset());
  else
    ScrollByYOffset(-event.y_offset());

  return true;
}

void OverflowBubbleView::OnScrollEvent(ui::ScrollEvent* event) {
  if (shelf_->IsHorizontalAlignment())
    ScrollByXOffset(static_cast<int>(-event->x_offset()));
  else
    ScrollByYOffset(static_cast<int>(-event->y_offset()));
  event->SetHandled();
}

gfx::Rect OverflowBubbleView::GetBubbleBounds() {
  const gfx::Size content_size = GetPreferredSize();
  const gfx::Rect anchor_rect = GetAnchorRect();
  const int distance_to_overflow_button =
      kDistanceToMainShelf + (kShelfSize - kShelfControlSize) / 2;
  gfx::Rect monitor_rect =
      display::Screen::GetScreen()
          ->GetDisplayNearestPoint(anchor_rect.CenterPoint())
          .work_area();
  // Make sure no part of the bubble touches a screen edge.
  monitor_rect.Inset(gfx::Insets(kMinimumMargin));

  if (shelf_->IsHorizontalAlignment()) {
    gfx::Rect bounds(
        base::i18n::IsRTL()
            ? anchor_rect.x() - kEndPadding
            : anchor_rect.right() - content_size.width() - kEndPadding,
        anchor_rect.y() - distance_to_overflow_button - content_size.height(),
        content_size.width() + 2 * kEndPadding, content_size.height());
    if (bounds.x() < monitor_rect.x())
      bounds.Offset(monitor_rect.x() - bounds.x(), 0);
    if (bounds.right() > monitor_rect.right())
      bounds.set_width(monitor_rect.right() - bounds.x());
    return bounds;
  }
  gfx::Rect bounds(
      0, anchor_rect.bottom() - content_size.height() - kEndPadding,
      content_size.width(), content_size.height() + 2 * kEndPadding);
  if (shelf_->alignment() == SHELF_ALIGNMENT_LEFT)
    bounds.set_x(anchor_rect.right() + distance_to_overflow_button);
  else
    bounds.set_x(anchor_rect.x() - distance_to_overflow_button -
                 content_size.width());
  if (bounds.y() < monitor_rect.y())
    bounds.Offset(0, monitor_rect.y() - bounds.y());
  if (bounds.bottom() > monitor_rect.bottom())
    bounds.set_height(monitor_rect.bottom() - bounds.y());
  return bounds;
}

bool OverflowBubbleView::CanActivate() const {
  if (!GetWidget())
    return false;

  // Do not activate the bubble unless the current active window is the shelf
  // window.
  aura::Window* active_window = wm::GetActiveWindow();
  aura::Window* bubble_window = GetWidget()->GetNativeWindow();
  aura::Window* shelf_window = shelf_->shelf_widget()->GetNativeWindow();
  return active_window == bubble_window || active_window == shelf_window;
}

bool OverflowBubbleView::ShouldCloseOnPressDown() {
  return false;
}

bool OverflowBubbleView::ShouldCloseOnMouseExit() {
  return false;
}

void OverflowBubbleView::UpdateShelfBackground(SkColor color) {
  set_color(color);
}

}  // namespace ash
