// 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/workspace/multi_window_resize_controller.h"

#include "ash/screen_ash.h"
#include "ash/shell.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/coordinate_conversion.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/workspace/workspace_event_handler.h"
#include "ash/wm/workspace/workspace_window_resizer.h"
#include "grit/ash_resources.h"
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/root_window.h"
#include "ui/aura/window.h"
#include "ui/aura/window_delegate.h"
#include "ui/base/hit_test.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/screen.h"
#include "ui/views/corewm/compound_event_filter.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

using aura::Window;

namespace ash {
namespace internal {

namespace {

// Delay before showing.
const int kShowDelayMS = 400;

// Delay before hiding.
const int kHideDelayMS = 500;

// Padding from the bottom/right edge the resize widget is shown at.
const int kResizeWidgetPadding = 15;

bool ContainsX(Window* window, int x) {
  return window->bounds().x() <= x && window->bounds().right() >= x;
}

bool ContainsY(Window* window, int y) {
  return window->bounds().y() <= y && window->bounds().bottom() >= y;
}

bool Intersects(int x1, int max_1, int x2, int max_2) {
  return x2 <= max_1 && max_2 > x1;
}

}  // namespace

// View contained in the widget. Passes along mouse events to the
// MultiWindowResizeController so that it can start/stop the resize loop.
class MultiWindowResizeController::ResizeView : public views::View {
 public:
  explicit ResizeView(MultiWindowResizeController* controller,
                      Direction direction)
      : controller_(controller),
        direction_(direction),
        image_(NULL) {
    ResourceBundle& rb = ResourceBundle::GetSharedInstance();
    int image_id =
        direction == TOP_BOTTOM ? IDR_AURA_MULTI_WINDOW_RESIZE_H :
                                  IDR_AURA_MULTI_WINDOW_RESIZE_V;
    image_ = rb.GetImageNamed(image_id).ToImageSkia();
  }

  // views::View overrides:
  virtual gfx::Size GetPreferredSize() OVERRIDE {
    return gfx::Size(image_->width(), image_->height());
  }
  virtual void OnPaint(gfx::Canvas* canvas) OVERRIDE {
    canvas->DrawImageInt(*image_, 0, 0);
  }
  virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE {
    gfx::Point location(event.location());
    views::View::ConvertPointToScreen(this, &location);
    controller_->StartResize(location);
    return true;
  }
  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE {
    gfx::Point location(event.location());
    views::View::ConvertPointToScreen(this, &location);
    controller_->Resize(location, event.flags());
    return true;
  }
  virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE {
    controller_->CompleteResize(event.flags());
  }
  virtual void OnMouseCaptureLost() OVERRIDE {
    controller_->CancelResize();
  }
  virtual gfx::NativeCursor GetCursor(
      const ui::MouseEvent& event) OVERRIDE {
    int component = (direction_ == LEFT_RIGHT) ? HTRIGHT : HTBOTTOM;
    return views::corewm::CompoundEventFilter::CursorForWindowComponent(
        component);
  }

 private:
  MultiWindowResizeController* controller_;
  const Direction direction_;
  const gfx::ImageSkia* image_;

  DISALLOW_COPY_AND_ASSIGN(ResizeView);
};

// MouseWatcherHost implementation for MultiWindowResizeController. Forwards
// Contains() to MultiWindowResizeController.
class MultiWindowResizeController::ResizeMouseWatcherHost :
   public views::MouseWatcherHost {
 public:
  ResizeMouseWatcherHost(MultiWindowResizeController* host) : host_(host) {}

  // MouseWatcherHost overrides:
  virtual bool Contains(const gfx::Point& point_in_screen,
                        MouseEventType type) OVERRIDE {
    return host_->IsOverWindows(point_in_screen);
  }

 private:
  MultiWindowResizeController* host_;

  DISALLOW_COPY_AND_ASSIGN(ResizeMouseWatcherHost);
};

MultiWindowResizeController::ResizeWindows::ResizeWindows()
    : window1(NULL),
      window2(NULL),
      direction(TOP_BOTTOM){
}

MultiWindowResizeController::ResizeWindows::~ResizeWindows() {
}

bool MultiWindowResizeController::ResizeWindows::Equals(
    const ResizeWindows& other) const {
  return window1 == other.window1 &&
      window2 == other.window2 &&
      direction == other.direction;
}

MultiWindowResizeController::MultiWindowResizeController() {
}

MultiWindowResizeController::~MultiWindowResizeController() {
  window_resizer_.reset();
  Hide();
}

void MultiWindowResizeController::Show(Window* window,
                                       int component,
                                       const gfx::Point& point_in_window) {
  // When the resize widget is showing we ignore Show() requests. Instead we
  // only care about mouse movements from MouseWatcher. This is necessary as
  // WorkspaceEventHandler only sees mouse movements over the windows, not all
  // windows or over the desktop.
  if (resize_widget_)
    return;

  ResizeWindows windows(DetermineWindows(window, component, point_in_window));
  if (IsShowing()) {
    if (windows_.Equals(windows))
      return;  // Over the same windows.
    DelayedHide();
  }

  if (!windows.is_valid())
    return;
  Hide();
  windows_ = windows;
  windows_.window1->AddObserver(this);
  windows_.window2->AddObserver(this);
  show_location_in_parent_ = point_in_window;
  Window::ConvertPointToTarget(
      window, window->parent(), &show_location_in_parent_);
  if (show_timer_.IsRunning())
    return;
  show_timer_.Start(
      FROM_HERE, base::TimeDelta::FromMilliseconds(kShowDelayMS),
      this, &MultiWindowResizeController::ShowIfValidMouseLocation);
}

void MultiWindowResizeController::Hide() {
  hide_timer_.Stop();
  if (window_resizer_)
    return;  // Ignore hides while actively resizing.

  if (windows_.window1) {
    windows_.window1->RemoveObserver(this);
    windows_.window1 = NULL;
  }
  if (windows_.window2) {
    windows_.window2->RemoveObserver(this);
    windows_.window2 = NULL;
  }

  show_timer_.Stop();

  if (!resize_widget_)
    return;

  for (size_t i = 0; i < windows_.other_windows.size(); ++i)
    windows_.other_windows[i]->RemoveObserver(this);
  mouse_watcher_.reset();
  resize_widget_.reset();
  windows_ = ResizeWindows();
}

void MultiWindowResizeController::MouseMovedOutOfHost() {
  Hide();
}

void MultiWindowResizeController::OnWindowDestroying(
    aura::Window* window) {
  // Have to explicitly reset the WindowResizer, otherwise Hide() does nothing.
  window_resizer_.reset();
  Hide();
}

MultiWindowResizeController::ResizeWindows
MultiWindowResizeController::DetermineWindowsFromScreenPoint(
    aura::Window* window) const {
  gfx::Point mouse_location(
      gfx::Screen::GetScreenFor(window)->GetCursorScreenPoint());
  wm::ConvertPointFromScreen(window, &mouse_location);
  const int component =
      window->delegate()->GetNonClientComponent(mouse_location);
  return DetermineWindows(window, component, mouse_location);
}

MultiWindowResizeController::ResizeWindows
MultiWindowResizeController::DetermineWindows(
    Window* window,
    int window_component,
    const gfx::Point& point) const {
  ResizeWindows result;
  gfx::Point point_in_parent(point);
  Window::ConvertPointToTarget(window, window->parent(), &point_in_parent);
  switch (window_component) {
    case HTRIGHT:
      result.direction = LEFT_RIGHT;
      result.window1 = window;
      result.window2 = FindWindowByEdge(
          window, HTLEFT, window->bounds().right(), point_in_parent.y());
      break;
    case HTLEFT:
      result.direction = LEFT_RIGHT;
      result.window1 = FindWindowByEdge(
          window, HTRIGHT, window->bounds().x(), point_in_parent.y());
      result.window2 = window;
      break;
    case HTTOP:
      result.direction = TOP_BOTTOM;
      result.window1 = FindWindowByEdge(
          window, HTBOTTOM, point_in_parent.x(), window->bounds().y());
      result.window2 = window;
      break;
    case HTBOTTOM:
      result.direction = TOP_BOTTOM;
      result.window1 = window;
      result.window2 = FindWindowByEdge(
          window, HTTOP, point_in_parent.x(), window->bounds().bottom());
      break;
    default:
      break;
  }
  return result;
}

Window* MultiWindowResizeController::FindWindowByEdge(
    Window* window_to_ignore,
    int edge_want,
    int x,
    int y) const {
  Window* parent = window_to_ignore->parent();
  const Window::Windows& windows(parent->children());
  for (Window::Windows::const_reverse_iterator i = windows.rbegin();
       i != windows.rend(); ++i) {
    Window* window = *i;
    if (window == window_to_ignore || !window->IsVisible())
      continue;
    switch (edge_want) {
      case HTLEFT:
        if (ContainsY(window, y) && window->bounds().x() == x)
          return window;
        break;
      case HTRIGHT:
        if (ContainsY(window, y) && window->bounds().right() == x)
          return window;
        break;
      case HTTOP:
        if (ContainsX(window, x) && window->bounds().y() == y)
          return window;
        break;
      case HTBOTTOM:
        if (ContainsX(window, x) && window->bounds().bottom() == y)
          return window;
        break;
      default:
        NOTREACHED();
    }
    // Window doesn't contain the edge, but if window contains |point|
    // it's obscuring any other window that could be at the location.
    if (window->bounds().Contains(x, y))
      return NULL;
  }
  return NULL;
}

aura::Window* MultiWindowResizeController::FindWindowTouching(
    aura::Window* window,
    Direction direction) const {
  int right = window->bounds().right();
  int bottom = window->bounds().bottom();
  Window* parent = window->parent();
  const Window::Windows& windows(parent->children());
  for (Window::Windows::const_reverse_iterator i = windows.rbegin();
       i != windows.rend(); ++i) {
    Window* other = *i;
    if (other == window || !other->IsVisible())
      continue;
    switch (direction) {
      case TOP_BOTTOM:
        if (other->bounds().y() == bottom &&
            Intersects(other->bounds().x(), other->bounds().right(),
                       window->bounds().x(), window->bounds().right())) {
          return other;
        }
        break;
      case LEFT_RIGHT:
        if (other->bounds().x() == right &&
            Intersects(other->bounds().y(), other->bounds().bottom(),
                       window->bounds().y(), window->bounds().bottom())) {
          return other;
        }
        break;
      default:
        NOTREACHED();
    }
  }
  return NULL;
}

void MultiWindowResizeController::FindWindowsTouching(
    aura::Window* start,
    Direction direction,
    std::vector<aura::Window*>* others) const {
  while (start) {
    start = FindWindowTouching(start, direction);
    if (start)
      others->push_back(start);
  }
}

void MultiWindowResizeController::DelayedHide() {
  if (hide_timer_.IsRunning())
    return;

  hide_timer_.Start(FROM_HERE,
                    base::TimeDelta::FromMilliseconds(kHideDelayMS),
                    this, &MultiWindowResizeController::Hide);
}

void MultiWindowResizeController::ShowIfValidMouseLocation() {
  if (DetermineWindowsFromScreenPoint(windows_.window1).Equals(windows_) ||
      DetermineWindowsFromScreenPoint(windows_.window2).Equals(windows_)) {
    ShowNow();
  } else {
    Hide();
  }
}

void MultiWindowResizeController::ShowNow() {
  DCHECK(!resize_widget_.get());
  DCHECK(windows_.is_valid());
  show_timer_.Stop();
  resize_widget_.reset(new views::Widget);
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.parent = Shell::GetContainer(
      Shell::GetTargetRootWindow(),
      internal::kShellWindowId_AlwaysOnTopContainer);
  params.can_activate = false;
  ResizeView* view = new ResizeView(this, windows_.direction);
  resize_widget_->set_focus_on_creation(false);
  resize_widget_->Init(params);
  views::corewm::SetWindowVisibilityAnimationType(
      resize_widget_->GetNativeWindow(),
      views::corewm::WINDOW_VISIBILITY_ANIMATION_TYPE_FADE);
  resize_widget_->GetNativeWindow()->SetName("MultiWindowResizeController");
  resize_widget_->SetContentsView(view);
  show_bounds_in_screen_ = ScreenAsh::ConvertRectToScreen(
      windows_.window1->parent(),
      CalculateResizeWidgetBounds(show_location_in_parent_));
  resize_widget_->SetBounds(show_bounds_in_screen_);
  resize_widget_->Show();
  mouse_watcher_.reset(new views::MouseWatcher(
                           new ResizeMouseWatcherHost(this),
                           this));
  mouse_watcher_->set_notify_on_exit_time(
      base::TimeDelta::FromMilliseconds(kHideDelayMS));
  mouse_watcher_->Start();
}

bool MultiWindowResizeController::IsShowing() const {
  return resize_widget_.get() || show_timer_.IsRunning();
}

void MultiWindowResizeController::StartResize(
    const gfx::Point& location_in_screen) {
  DCHECK(!window_resizer_.get());
  DCHECK(windows_.is_valid());
  hide_timer_.Stop();
  gfx::Point location_in_parent(location_in_screen);
  aura::client::GetScreenPositionClient(windows_.window2->GetRootWindow())->
      ConvertPointFromScreen(windows_.window2->parent(), &location_in_parent);
  std::vector<aura::Window*> windows;
  windows.push_back(windows_.window2);
  DCHECK(windows_.other_windows.empty());
  FindWindowsTouching(windows_.window2, windows_.direction,
                      &windows_.other_windows);
  for (size_t i = 0; i < windows_.other_windows.size(); ++i) {
    windows_.other_windows[i]->AddObserver(this);
    windows.push_back(windows_.other_windows[i]);
  }
  int component = windows_.direction == LEFT_RIGHT ? HTRIGHT : HTBOTTOM;
  window_resizer_.reset(WorkspaceWindowResizer::Create(
      windows_.window1,
      location_in_parent,
      component,
      aura::client::WINDOW_MOVE_SOURCE_MOUSE,
      windows));
}

void MultiWindowResizeController::Resize(const gfx::Point& location_in_screen,
                                         int event_flags) {
  gfx::Point location_in_parent(location_in_screen);
  aura::client::GetScreenPositionClient(windows_.window1->GetRootWindow())->
      ConvertPointFromScreen(windows_.window1->parent(), &location_in_parent);
  window_resizer_->Drag(location_in_parent, event_flags);
  gfx::Rect bounds = ScreenAsh::ConvertRectToScreen(
      windows_.window1->parent(),
      CalculateResizeWidgetBounds(location_in_parent));

  if (windows_.direction == LEFT_RIGHT)
    bounds.set_y(show_bounds_in_screen_.y());
  else
    bounds.set_x(show_bounds_in_screen_.x());
  resize_widget_->SetBounds(bounds);
}

void MultiWindowResizeController::CompleteResize(int event_flags) {
  window_resizer_->CompleteDrag(event_flags);
  window_resizer_.reset();

  // Mouse may still be over resizer, if not hide.
  gfx::Point screen_loc = Shell::GetScreen()->GetCursorScreenPoint();
  if (!resize_widget_->GetWindowBoundsInScreen().Contains(screen_loc)) {
    Hide();
  } else {
    // If the mouse is over the resizer we need to remove observers on any of
    // the |other_windows|. If we start another resize we'll recalculate the
    // |other_windows| and invoke AddObserver() as necessary.
    for (size_t i = 0; i < windows_.other_windows.size(); ++i)
      windows_.other_windows[i]->RemoveObserver(this);
    windows_.other_windows.clear();
  }
}

void MultiWindowResizeController::CancelResize() {
  if (!window_resizer_)
    return;  // Happens if window was destroyed and we nuked the WindowResizer.
  window_resizer_->RevertDrag();
  window_resizer_.reset();
  Hide();
}

gfx::Rect MultiWindowResizeController::CalculateResizeWidgetBounds(
    const gfx::Point& location_in_parent) const {
  gfx::Size pref = resize_widget_->GetContentsView()->GetPreferredSize();
  int x = 0, y = 0;
  if (windows_.direction == LEFT_RIGHT) {
    x = windows_.window1->bounds().right() - pref.width() / 2;
    y = location_in_parent.y() + kResizeWidgetPadding;
    if (y + pref.height() / 2 > windows_.window1->bounds().bottom() &&
        y + pref.height() / 2 > windows_.window2->bounds().bottom()) {
      y = location_in_parent.y() - kResizeWidgetPadding - pref.height();
    }
  } else {
    x = location_in_parent.x() + kResizeWidgetPadding;
    if (x + pref.height() / 2 > windows_.window1->bounds().right() &&
        x + pref.height() / 2 > windows_.window2->bounds().right()) {
      x = location_in_parent.x() - kResizeWidgetPadding - pref.width();
    }
    y = windows_.window1->bounds().bottom() - pref.height() / 2;
  }
  return gfx::Rect(x, y, pref.width(), pref.height());
}

bool MultiWindowResizeController::IsOverWindows(
    const gfx::Point& location_in_screen) const {
  if (window_resizer_)
    return true;  // Ignore hides while actively resizing.

  if (resize_widget_->GetWindowBoundsInScreen().Contains(location_in_screen))
    return true;

  int hit1, hit2;
  if (windows_.direction == TOP_BOTTOM) {
    hit1 = HTBOTTOM;
    hit2 = HTTOP;
  } else {
    hit1 = HTRIGHT;
    hit2 = HTLEFT;
  }

  return IsOverWindow(windows_.window1, location_in_screen, hit1) ||
      IsOverWindow(windows_.window2, location_in_screen, hit2);
}

bool MultiWindowResizeController::IsOverWindow(
    aura::Window* window,
    const gfx::Point& location_in_screen,
    int component) const {
  if (!window->delegate())
    return false;

  gfx::Point window_loc(location_in_screen);
  aura::Window::ConvertPointToTarget(
      window->GetRootWindow(), window, &window_loc);
  return window->HitTest(window_loc) &&
      window->delegate()->GetNonClientComponent(window_loc) == component;
}

}  // namespace internal
}  // namespace ash
