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

#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/window_animations.h"
#include "ash/wm/workspace/frame_maximize_button.h"
#include "base/timer/timer.h"
#include "grit/ash_resources.h"
#include "grit/ash_strings.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/aura/window.h"
#include "ui/base/animation/animation.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/path.h"
#include "ui/gfx/screen.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/bubble/bubble_frame_view.h"
#include "ui/views/controls/button/button.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/mouse_watcher.h"
#include "ui/views/widget/widget.h"

namespace {

// The spacing between two buttons.
const int kLayoutSpacing = -1;

// The background color.
const SkColor kBubbleBackgroundColor = 0xFF141414;

// The text color within the bubble.
const SkColor kBubbleTextColor = SK_ColorWHITE;

// The line width of the bubble.
const int kLineWidth = 1;

// The spacing for the top and bottom of the info label.
const int kLabelSpacing = 4;

// The pixel dimensions of the arrow.
const int kArrowHeight = 10;
const int kArrowWidth = 20;

// The animation offset in y for the bubble when appearing.
const int kBubbleAnimationOffsetY = 5;

class MaximizeBubbleBorder : public views::BubbleBorder {
 public:
  MaximizeBubbleBorder(views::View* content_view, views::View* anchor);

  virtual ~MaximizeBubbleBorder() {}

  // Get the mouse active area of the window.
  void GetMask(gfx::Path* mask);

  // Overridden from views::BubbleBorder to match the design specs.
  virtual gfx::Rect GetBounds(const gfx::Rect& position_relative_to,
                              const gfx::Size& contents_size) const OVERRIDE;

  // Overridden from views::Border.
  virtual void Paint(const views::View& view, gfx::Canvas* canvas) OVERRIDE;

 private:
  // Note: Animations can continue after then main window frame was destroyed.
  // To avoid this problem, the owning screen metrics get extracted upon
  // creation.
  gfx::Size anchor_size_;
  gfx::Point anchor_screen_origin_;
  views::View* content_view_;

  DISALLOW_COPY_AND_ASSIGN(MaximizeBubbleBorder);
};

MaximizeBubbleBorder::MaximizeBubbleBorder(views::View* content_view,
                                           views::View* anchor)
    : views::BubbleBorder(views::BubbleBorder::TOP_RIGHT,
                          views::BubbleBorder::NO_SHADOW,
                          kBubbleBackgroundColor),
      anchor_size_(anchor->size()),
      anchor_screen_origin_(0, 0),
      content_view_(content_view) {
  views::View::ConvertPointToScreen(anchor, &anchor_screen_origin_);
  set_alignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
}

void MaximizeBubbleBorder::GetMask(gfx::Path* mask) {
  gfx::Insets inset = GetInsets();
  // Note: Even though the tip could be added as activatable, it is left out
  // since it would not change the action behavior in any way plus it makes
  // more sense to keep the focus on the underlying button for clicks.
  int left = inset.left() - kLineWidth;
  int right = inset.left() + content_view_->width() + kLineWidth;
  int top = inset.top() - kLineWidth;
  int bottom = inset.top() + content_view_->height() + kLineWidth;
  mask->moveTo(left, top);
  mask->lineTo(right, top);
  mask->lineTo(right, bottom);
  mask->lineTo(left, bottom);
  mask->lineTo(left, top);
  mask->close();
}

gfx::Rect MaximizeBubbleBorder::GetBounds(
    const gfx::Rect& position_relative_to,
    const gfx::Size& contents_size) const {
  gfx::Size border_size(contents_size);
  gfx::Insets insets = GetInsets();
  border_size.Enlarge(insets.width(), insets.height());

  // Position the bubble to center the box on the anchor.
  int x = (-border_size.width() + anchor_size_.width()) / 2;
  // Position the bubble under the anchor, overlapping the arrow with it.
  int y = anchor_size_.height() - insets.top();

  gfx::Point view_origin(x + anchor_screen_origin_.x(),
                         y + anchor_screen_origin_.y());

  return gfx::Rect(view_origin, border_size);
}

void MaximizeBubbleBorder::Paint(const views::View& view, gfx::Canvas* canvas) {
  gfx::Insets inset = GetInsets();

  // Draw the border line around everything.
  int y = inset.top();
  // Top
  canvas->FillRect(gfx::Rect(inset.left(),
                             y - kLineWidth,
                             content_view_->width(),
                             kLineWidth),
                   kBubbleBackgroundColor);
  // Bottom
  canvas->FillRect(gfx::Rect(inset.left(),
                             y + content_view_->height(),
                             content_view_->width(),
                             kLineWidth),
                   kBubbleBackgroundColor);
  // Left
  canvas->FillRect(gfx::Rect(inset.left() - kLineWidth,
                             y - kLineWidth,
                             kLineWidth,
                             content_view_->height() + 2 * kLineWidth),
                   kBubbleBackgroundColor);
  // Right
  canvas->FillRect(gfx::Rect(inset.left() + content_view_->width(),
                             y - kLineWidth,
                             kLineWidth,
                             content_view_->height() + 2 * kLineWidth),
                   kBubbleBackgroundColor);

  // Draw the arrow afterwards covering the border.
  SkPath path;
  path.incReserve(4);
  // The center of the tip should be in the middle of the button.
  int tip_x = inset.left() + content_view_->width() / 2;
  int left_base_x = tip_x - kArrowWidth / 2;
  int left_base_y = y;
  int tip_y = left_base_y - kArrowHeight;
  path.moveTo(SkIntToScalar(left_base_x), SkIntToScalar(left_base_y));
  path.lineTo(SkIntToScalar(tip_x), SkIntToScalar(tip_y));
  path.lineTo(SkIntToScalar(left_base_x + kArrowWidth),
              SkIntToScalar(left_base_y));

  SkPaint paint;
  paint.setStyle(SkPaint::kFill_Style);
  paint.setColor(kBubbleBackgroundColor);
  canvas->DrawPath(path, paint);
}

}  // namespace

namespace ash {

class BubbleContentsButtonRow;
class BubbleContentsView;
class BubbleDialogButton;

// The mouse watcher host which makes sure that the bubble does not get closed
// while the mouse cursor is over the maximize button or the balloon content.
// Note: This object gets destroyed when the MouseWatcher gets destroyed.
class BubbleMouseWatcherHost: public views::MouseWatcherHost {
 public:
  explicit BubbleMouseWatcherHost(MaximizeBubbleController::Bubble* bubble)
      : bubble_(bubble) {}
  virtual ~BubbleMouseWatcherHost() {}

  // Implementation of MouseWatcherHost.
  virtual bool Contains(const gfx::Point& screen_point,
                        views::MouseWatcherHost::MouseEventType type) OVERRIDE;
 private:
  MaximizeBubbleController::Bubble* bubble_;

  DISALLOW_COPY_AND_ASSIGN(BubbleMouseWatcherHost);
};

// The class which creates and manages the bubble menu element.
// It creates a 'bubble border' and the content accordingly.
// Note: Since the SnapSizer will show animations on top of the maximize button
// this menu gets created as a separate window and the SnapSizer will be
// created underneath this window.
class MaximizeBubbleController::Bubble : public views::BubbleDelegateView,
                                         public views::MouseWatcherListener {
 public:
  explicit Bubble(MaximizeBubbleController* owner, int appearance_delay_ms_);
  virtual ~Bubble() {}

  // The window of the menu under which the SnapSizer will get created.
  aura::Window* GetBubbleWindow();

  // Overridden from views::BubbleDelegateView.
  virtual gfx::Rect GetAnchorRect() OVERRIDE;
  virtual void AnimationProgressed(const ui::Animation* animation) OVERRIDE;
  virtual bool CanActivate() const OVERRIDE { return false; }

  // Overridden from views::WidgetDelegateView.
  virtual bool WidgetHasHitTestMask() const OVERRIDE;
  virtual void GetWidgetHitTestMask(gfx::Path* mask) const OVERRIDE;

  // Implementation of MouseWatcherListener.
  virtual void MouseMovedOutOfHost() OVERRIDE;

  // Implementation of MouseWatcherHost.
  virtual bool Contains(const gfx::Point& screen_point,
                        views::MouseWatcherHost::MouseEventType type);

  // Overridden from views::View.
  virtual gfx::Size GetPreferredSize() OVERRIDE;

  // Overridden from views::Widget::Observer.
  virtual void OnWidgetDestroying(views::Widget* widget) OVERRIDE;

  // Called from the controller class to indicate that the menu should get
  // destroyed.
  virtual void ControllerRequestsCloseAndDelete();

  // Called from the owning class to change the menu content to the given
  // |snap_type| so that the user knows what is selected.
  void SetSnapType(SnapType snap_type);

  // Get the owning MaximizeBubbleController. This might return NULL in case
  // of an asynchronous shutdown.
  MaximizeBubbleController* controller() const { return owner_; }

  // Added for unit test: Retrieve the button for an action.
  // |state| can be either SNAP_LEFT, SNAP_RIGHT or SNAP_MINIMIZE.
  views::CustomButton* GetButtonForUnitTest(SnapType state);

 private:
  // True if the shut down has been initiated.
  bool shutting_down_;

  // Our owning class.
  MaximizeBubbleController* owner_;

  // The widget which contains our menu and the bubble border.
  views::Widget* bubble_widget_;

  // The content accessor of the menu.
  BubbleContentsView* contents_view_;

  // The bubble border.
  MaximizeBubbleBorder* bubble_border_;

  // The rectangle before the animation starts.
  gfx::Rect initial_position_;

  // The mouse watcher which takes care of out of window hover events.
  scoped_ptr<views::MouseWatcher> mouse_watcher_;

  // The fade delay - if 0 it will show / hide immediately.
  const int appearance_delay_ms_;

  DISALLOW_COPY_AND_ASSIGN(Bubble);
};

// A class that creates all buttons and put them into a view.
class BubbleContentsButtonRow : public views::View,
                                public views::ButtonListener {
 public:
  explicit BubbleContentsButtonRow(MaximizeBubbleController::Bubble* bubble);

  virtual ~BubbleContentsButtonRow() {}

  // Overridden from ButtonListener.
  virtual void ButtonPressed(views::Button* sender,
                             const ui::Event& event) OVERRIDE;
  // Called from BubbleDialogButton.
  void ButtonHovered(BubbleDialogButton* sender);

  // Added for unit test: Retrieve the button for an action.
  // |state| can be either SNAP_LEFT, SNAP_RIGHT or SNAP_MINIMIZE.
  views::CustomButton* GetButtonForUnitTest(SnapType state);

  MaximizeBubbleController::Bubble* bubble() { return bubble_; }

 private:
  // Functions to add the left and right maximize / restore buttons.
  void AddMaximizeLeftButton();
  void AddMaximizeRightButton();
  void AddMinimizeButton();

  // The owning object which gets notifications.
  MaximizeBubbleController::Bubble* bubble_;

  // The created buttons for our menu.
  BubbleDialogButton* left_button_;
  BubbleDialogButton* minimize_button_;
  BubbleDialogButton* right_button_;

  DISALLOW_COPY_AND_ASSIGN(BubbleContentsButtonRow);
};

// A class which creates the content of the bubble: The buttons, and the label.
class BubbleContentsView : public views::View {
 public:
  explicit BubbleContentsView(MaximizeBubbleController::Bubble* bubble);

  virtual ~BubbleContentsView() {}

  // Set the label content to reflect the currently selected |snap_type|.
  // This function can be executed through the frame maximize button as well as
  // through hover operations.
  void SetSnapType(SnapType snap_type);

  // Added for unit test: Retrieve the button for an action.
  // |state| can be either SNAP_LEFT, SNAP_RIGHT or SNAP_MINIMIZE.
  views::CustomButton* GetButtonForUnitTest(SnapType state) {
    return buttons_view_->GetButtonForUnitTest(state);
  }

 private:
  // The owning class.
  MaximizeBubbleController::Bubble* bubble_;

  // The object which owns all the buttons.
  BubbleContentsButtonRow* buttons_view_;

  // The label object which shows the user the selected action.
  views::Label* label_view_;

  DISALLOW_COPY_AND_ASSIGN(BubbleContentsView);
};

// The image button gets overridden to be able to capture mouse hover events.
// The constructor also assigns all button states and
class BubbleDialogButton : public views::ImageButton {
 public:
  explicit BubbleDialogButton(
      BubbleContentsButtonRow* button_row_listener,
      int normal_image,
      int hovered_image,
      int pressed_image);
  virtual ~BubbleDialogButton() {}

  // CustomButton overrides:
  virtual void OnMouseCaptureLost() OVERRIDE;
  virtual void OnMouseEntered(const ui::MouseEvent& event) OVERRIDE;
  virtual void OnMouseExited(const ui::MouseEvent& event) OVERRIDE;
  virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE;

 private:
  // The creating class which needs to get notified in case of a hover event.
  BubbleContentsButtonRow* button_row_;

  DISALLOW_COPY_AND_ASSIGN(BubbleDialogButton);
};

MaximizeBubbleController::Bubble::Bubble(
    MaximizeBubbleController* owner,
    int appearance_delay_ms)
    : views::BubbleDelegateView(owner->frame_maximize_button(),
                                views::BubbleBorder::TOP_RIGHT),
      shutting_down_(false),
      owner_(owner),
      bubble_widget_(NULL),
      contents_view_(NULL),
      bubble_border_(NULL),
      appearance_delay_ms_(appearance_delay_ms) {
  set_margins(gfx::Insets());

  // The window needs to be owned by the root so that the SnapSizer does not
  // cover it upon animation.
  aura::Window* parent = Shell::GetContainer(
      Shell::GetActiveRootWindow(),
      internal::kShellWindowId_ShelfContainer);
  set_parent_window(parent);

  set_notify_enter_exit_on_child(true);
  set_adjust_if_offscreen(false);
  SetPaintToLayer(true);
  set_color(kBubbleBackgroundColor);
  set_close_on_deactivate(false);
  set_background(
      views::Background::CreateSolidBackground(kBubbleBackgroundColor));

  SetLayoutManager(new views::BoxLayout(
      views::BoxLayout::kVertical, 0, 0, kLayoutSpacing));

  contents_view_ = new BubbleContentsView(this);
  AddChildView(contents_view_);

  // Note that the returned widget has an observer which points to our
  // functions.
  bubble_widget_ = views::BubbleDelegateView::CreateBubble(this);
  bubble_widget_->set_focus_on_creation(false);

  SetAlignment(views::BubbleBorder::ALIGN_EDGE_TO_ANCHOR_EDGE);
  bubble_widget_->non_client_view()->frame_view()->set_background(NULL);

  bubble_border_ = new MaximizeBubbleBorder(this, anchor_view());
  GetBubbleFrameView()->SetBubbleBorder(bubble_border_);
  GetBubbleFrameView()->set_background(NULL);

  // Recalculate size with new border.
  SizeToContents();

  if (!appearance_delay_ms_)
    GetWidget()->Show();
  else
    StartFade(true);

  ash::Shell::GetInstance()->delegate()->RecordUserMetricsAction(
      ash::UMA_WINDOW_MAXIMIZE_BUTTON_SHOW_BUBBLE);

  mouse_watcher_.reset(new views::MouseWatcher(
      new BubbleMouseWatcherHost(this),
      this));
  mouse_watcher_->Start();
}

bool BubbleMouseWatcherHost::Contains(
    const gfx::Point& screen_point,
    views::MouseWatcherHost::MouseEventType type) {
  return bubble_->Contains(screen_point, type);
}

aura::Window* MaximizeBubbleController::Bubble::GetBubbleWindow() {
  return bubble_widget_ ? bubble_widget_->GetNativeWindow() : NULL;
}

gfx::Rect MaximizeBubbleController::Bubble::GetAnchorRect() {
  if (!owner_)
    return gfx::Rect();

  gfx::Rect anchor_rect =
      owner_->frame_maximize_button()->GetBoundsInScreen();
  return anchor_rect;
}

void MaximizeBubbleController::Bubble::AnimationProgressed(
    const ui::Animation* animation) {
  // First do everything needed for the fade by calling the base function.
  BubbleDelegateView::AnimationProgressed(animation);
  // When fading in we are done.
  if (!shutting_down_)
    return;
  // Upon fade out an additional shift is required.
  int shift = animation->CurrentValueBetween(kBubbleAnimationOffsetY, 0);
  gfx::Rect rect = initial_position_;

  rect.set_y(rect.y() + shift);
  bubble_widget_->GetNativeWindow()->SetBounds(rect);
}

bool MaximizeBubbleController::Bubble::WidgetHasHitTestMask() const {
  return bubble_border_ != NULL;
}

void MaximizeBubbleController::Bubble::GetWidgetHitTestMask(
    gfx::Path* mask) const {
  DCHECK(mask);
  DCHECK(bubble_border_);
  bubble_border_->GetMask(mask);
}

void MaximizeBubbleController::Bubble::MouseMovedOutOfHost() {
  if (!owner_ || shutting_down_)
    return;
  // When we leave the bubble, we might be still be in gesture mode or over
  // the maximize button. So only close if none of the other cases apply.
  if (!owner_->frame_maximize_button()->is_snap_enabled()) {
    gfx::Point screen_location = Shell::GetScreen()->GetCursorScreenPoint();
    if (!owner_->frame_maximize_button()->GetBoundsInScreen().Contains(
        screen_location)) {
        owner_->RequestDestructionThroughOwner();
    }
  }
}

bool MaximizeBubbleController::Bubble::Contains(
    const gfx::Point& screen_point,
    views::MouseWatcherHost::MouseEventType type) {
  if (!owner_ || shutting_down_)
    return false;
  bool inside_button =
      owner_->frame_maximize_button()->GetBoundsInScreen().Contains(
          screen_point);
  if (!owner_->frame_maximize_button()->is_snap_enabled() && inside_button) {
    SetSnapType(controller()->maximize_type() == FRAME_STATE_FULL ?
        SNAP_RESTORE : SNAP_MAXIMIZE);
    return true;
  }
  // Check if either a gesture is taking place (=> bubble stays no matter what
  // the mouse does) or the mouse is over the maximize button or the bubble
  // content.
  return (owner_->frame_maximize_button()->is_snap_enabled() ||
          inside_button ||
          contents_view_->GetBoundsInScreen().Contains(screen_point));
}

gfx::Size MaximizeBubbleController::Bubble::GetPreferredSize() {
  return contents_view_->GetPreferredSize();
}

void MaximizeBubbleController::Bubble::OnWidgetDestroying(
    views::Widget* widget) {
  if (bubble_widget_ == widget) {
    mouse_watcher_->Stop();

    if (owner_) {
      // If the bubble destruction was triggered by some other external
      // influence then ourselves, the owner needs to be informed that the menu
      // is gone.
      shutting_down_ = true;
      owner_->RequestDestructionThroughOwner();
      owner_ = NULL;
    }
  }
  BubbleDelegateView::OnWidgetDestroying(widget);
}

void MaximizeBubbleController::Bubble::ControllerRequestsCloseAndDelete() {
  // This only gets called from the owning base class once it is deleted.
  if (shutting_down_)
    return;
  shutting_down_ = true;
  owner_ = NULL;

  // Close the widget asynchronously after the hide animation is finished.
  initial_position_ = bubble_widget_->GetNativeWindow()->bounds();
  if (!appearance_delay_ms_)
    bubble_widget_->CloseNow();
  else
    StartFade(false);
}

void MaximizeBubbleController::Bubble::SetSnapType(SnapType snap_type) {
  if (contents_view_)
    contents_view_->SetSnapType(snap_type);
}

views::CustomButton* MaximizeBubbleController::Bubble::GetButtonForUnitTest(
    SnapType state) {
  return contents_view_->GetButtonForUnitTest(state);
}

BubbleContentsButtonRow::BubbleContentsButtonRow(
    MaximizeBubbleController::Bubble* bubble)
    : bubble_(bubble),
      left_button_(NULL),
      minimize_button_(NULL),
      right_button_(NULL) {
  SetLayoutManager(new views::BoxLayout(
      views::BoxLayout::kHorizontal, 0, 0, kLayoutSpacing));
  set_background(
      views::Background::CreateSolidBackground(kBubbleBackgroundColor));

  if (base::i18n::IsRTL()) {
    AddMaximizeRightButton();
    AddMinimizeButton();
    AddMaximizeLeftButton();
  } else {
    AddMaximizeLeftButton();
    AddMinimizeButton();
    AddMaximizeRightButton();
  }
}

// Overridden from ButtonListener.
void BubbleContentsButtonRow::ButtonPressed(views::Button* sender,
                                            const ui::Event& event) {
  // While shutting down, the connection to the owner might already be broken.
  if (!bubble_->controller())
    return;
  if (sender == left_button_)
    bubble_->controller()->OnButtonClicked(
        bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_LEFT ?
            SNAP_RESTORE : SNAP_LEFT);
  else if (sender == minimize_button_)
    bubble_->controller()->OnButtonClicked(SNAP_MINIMIZE);
  else if (sender == right_button_)
    bubble_->controller()->OnButtonClicked(
        bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_RIGHT ?
            SNAP_RESTORE : SNAP_RIGHT);
  else
    NOTREACHED() << "Unknown button pressed.";
}

// Called from BubbleDialogButton.
void BubbleContentsButtonRow::ButtonHovered(BubbleDialogButton* sender) {
  // While shutting down, the connection to the owner might already be broken.
  if (!bubble_->controller())
    return;
  if (sender == left_button_)
    bubble_->controller()->OnButtonHover(
        bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_LEFT ?
            SNAP_RESTORE : SNAP_LEFT);
  else if (sender == minimize_button_)
    bubble_->controller()->OnButtonHover(SNAP_MINIMIZE);
  else if (sender == right_button_)
    bubble_->controller()->OnButtonHover(
        bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_RIGHT ?
            SNAP_RESTORE : SNAP_RIGHT);
  else
    bubble_->controller()->OnButtonHover(SNAP_NONE);
}

views::CustomButton* BubbleContentsButtonRow::GetButtonForUnitTest(
    SnapType state) {
  switch (state) {
    case SNAP_LEFT:
      return left_button_;
    case SNAP_MINIMIZE:
      return minimize_button_;
    case SNAP_RIGHT:
      return right_button_;
    default:
      NOTREACHED();
      return NULL;
  }
}

void BubbleContentsButtonRow::AddMaximizeLeftButton() {
  if (bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_LEFT) {
    left_button_ = new BubbleDialogButton(
        this,
        IDR_AURA_WINDOW_POSITION_LEFT_RESTORE,
        IDR_AURA_WINDOW_POSITION_LEFT_RESTORE_H,
        IDR_AURA_WINDOW_POSITION_LEFT_RESTORE_P);
  } else {
    left_button_ = new BubbleDialogButton(
        this,
        IDR_AURA_WINDOW_POSITION_LEFT,
        IDR_AURA_WINDOW_POSITION_LEFT_H,
        IDR_AURA_WINDOW_POSITION_LEFT_P);
  }
}

void BubbleContentsButtonRow::AddMaximizeRightButton() {
  if (bubble_->controller()->maximize_type() == FRAME_STATE_SNAP_RIGHT) {
    right_button_ = new BubbleDialogButton(
        this,
        IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE,
        IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE_H,
        IDR_AURA_WINDOW_POSITION_RIGHT_RESTORE_P);
  } else {
    right_button_ = new BubbleDialogButton(
        this,
        IDR_AURA_WINDOW_POSITION_RIGHT,
        IDR_AURA_WINDOW_POSITION_RIGHT_H,
        IDR_AURA_WINDOW_POSITION_RIGHT_P);
  }
}

void BubbleContentsButtonRow::AddMinimizeButton() {
  minimize_button_ = new BubbleDialogButton(
      this,
      IDR_AURA_WINDOW_POSITION_MIDDLE,
      IDR_AURA_WINDOW_POSITION_MIDDLE_H,
      IDR_AURA_WINDOW_POSITION_MIDDLE_P);
}

BubbleContentsView::BubbleContentsView(
    MaximizeBubbleController::Bubble* bubble)
    : bubble_(bubble),
      buttons_view_(NULL),
      label_view_(NULL) {
  SetLayoutManager(new views::BoxLayout(
      views::BoxLayout::kVertical, 0, 0, kLayoutSpacing));
  set_background(
      views::Background::CreateSolidBackground(kBubbleBackgroundColor));

  buttons_view_ = new BubbleContentsButtonRow(bubble);
  AddChildView(buttons_view_);

  label_view_ = new views::Label();
  SetSnapType(SNAP_NONE);
  label_view_->SetBackgroundColor(kBubbleBackgroundColor);
  label_view_->SetEnabledColor(kBubbleTextColor);
  label_view_->set_border(views::Border::CreateEmptyBorder(
      kLabelSpacing, 0, kLabelSpacing, 0));
  AddChildView(label_view_);
}

// Set the label content to reflect the currently selected |snap_type|.
// This function can be executed through the frame maximize button as well as
// through hover operations.
void BubbleContentsView::SetSnapType(SnapType snap_type) {
  if (!bubble_->controller())
    return;

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  int id = 0;
  switch (snap_type) {
    case SNAP_LEFT:
      id = IDS_ASH_SNAP_WINDOW_LEFT;
      break;
    case SNAP_RIGHT:
      id = IDS_ASH_SNAP_WINDOW_RIGHT;
      break;
    case SNAP_MAXIMIZE:
      DCHECK_NE(FRAME_STATE_FULL, bubble_->controller()->maximize_type());
      id = IDS_ASH_MAXIMIZE_WINDOW;
      break;
    case SNAP_MINIMIZE:
      id = IDS_ASH_MINIMIZE_WINDOW;
      break;
    case SNAP_RESTORE:
      DCHECK_NE(FRAME_STATE_NONE, bubble_->controller()->maximize_type());
      id = IDS_ASH_RESTORE_WINDOW;
      break;
    default:
      // If nothing is selected, we automatically select the click operation.
      id = bubble_->controller()->maximize_type() == FRAME_STATE_FULL ?
               IDS_ASH_RESTORE_WINDOW : IDS_ASH_MAXIMIZE_WINDOW;
      break;
  }
  label_view_->SetText(rb.GetLocalizedString(id));
}

MaximizeBubbleController::MaximizeBubbleController(
    FrameMaximizeButton* frame_maximize_button,
    MaximizeBubbleFrameState maximize_type,
    int appearance_delay_ms)
    : frame_maximize_button_(frame_maximize_button),
      bubble_(NULL),
      maximize_type_(maximize_type),
      appearance_delay_ms_(appearance_delay_ms) {
  // Create the task which will create the bubble delayed.
  base::OneShotTimer<MaximizeBubbleController>* new_timer =
      new base::OneShotTimer<MaximizeBubbleController>();
  // Note: Even if there was no delay time given, we need to have a timer.
  new_timer->Start(
      FROM_HERE,
      base::TimeDelta::FromMilliseconds(
          appearance_delay_ms_ ? appearance_delay_ms_ : 10),
      this,
      &MaximizeBubbleController::CreateBubble);
  timer_.reset(new_timer);
  if (!appearance_delay_ms_)
    CreateBubble();
}

MaximizeBubbleController::~MaximizeBubbleController() {
  // Note: The destructor only gets initiated through the owner.
  timer_.reset();
  if (bubble_) {
    bubble_->ControllerRequestsCloseAndDelete();
    bubble_ = NULL;
  }
}

void MaximizeBubbleController::SetSnapType(SnapType snap_type) {
  if (bubble_)
    bubble_->SetSnapType(snap_type);
}

aura::Window* MaximizeBubbleController::GetBubbleWindow() {
  return bubble_ ? bubble_->GetBubbleWindow() : NULL;
}

void MaximizeBubbleController::DelayCreation() {
  if (timer_.get() && timer_->IsRunning())
    timer_->Reset();
}

void MaximizeBubbleController::OnButtonClicked(SnapType snap_type) {
  frame_maximize_button_->ExecuteSnapAndCloseMenu(snap_type);
}

void MaximizeBubbleController::OnButtonHover(SnapType snap_type) {
  frame_maximize_button_->SnapButtonHovered(snap_type);
}

views::CustomButton* MaximizeBubbleController::GetButtonForUnitTest(
    SnapType state) {
  return bubble_ ? bubble_->GetButtonForUnitTest(state) : NULL;
}

void MaximizeBubbleController::RequestDestructionThroughOwner() {
  // Tell the parent to destroy us (if this didn't happen yet).
  if (timer_) {
    timer_.reset(NULL);
    // Informs the owner that the menu is gone and requests |this| destruction.
    frame_maximize_button_->DestroyMaximizeMenu();
    // Note: After this call |this| is destroyed.
  }
}

void MaximizeBubbleController::CreateBubble() {
  if (!bubble_)
    bubble_ = new Bubble(this, appearance_delay_ms_);

  timer_->Stop();
}

BubbleDialogButton::BubbleDialogButton(
    BubbleContentsButtonRow* button_row,
    int normal_image,
    int hovered_image,
    int pressed_image)
    : views::ImageButton(button_row),
      button_row_(button_row) {
  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  SetImage(views::CustomButton::STATE_NORMAL,
           rb.GetImageSkiaNamed(normal_image));
  SetImage(views::CustomButton::STATE_HOVERED,
           rb.GetImageSkiaNamed(hovered_image));
  SetImage(views::CustomButton::STATE_PRESSED,
           rb.GetImageSkiaNamed(pressed_image));
  button_row->AddChildView(this);
}

void BubbleDialogButton::OnMouseCaptureLost() {
  button_row_->ButtonHovered(NULL);
  views::ImageButton::OnMouseCaptureLost();
}

void BubbleDialogButton::OnMouseEntered(const ui::MouseEvent& event) {
  button_row_->ButtonHovered(this);
  views::ImageButton::OnMouseEntered(event);
}

void BubbleDialogButton::OnMouseExited(const ui::MouseEvent& event) {
  button_row_->ButtonHovered(NULL);
  views::ImageButton::OnMouseExited(event);
}

bool BubbleDialogButton::OnMouseDragged(const ui::MouseEvent& event) {
  if (!button_row_->bubble()->controller())
    return false;

  // Remove the phantom window when we leave the button.
  gfx::Point screen_location(event.location());
  View::ConvertPointToScreen(this, &screen_location);
  if (!GetBoundsInScreen().Contains(screen_location))
    button_row_->ButtonHovered(NULL);
  else
    button_row_->ButtonHovered(this);

  // Pass the event on to the normal handler.
  return views::ImageButton::OnMouseDragged(event);
}

}  // namespace ash
