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

#include "ash/shell.h"
#include "ash/shell_delegate.h"
#include "ash/shell_window_ids.h"
#include "ash/wm/caption_buttons/frame_maximize_button.h"
#include "ash/wm/window_animations.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/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/animation/animation.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 gfx::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::GetTargetRootWindow(),
      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 gfx::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
