// 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 "ui/message_center/views/message_center_bubble.h"

#include "ui/base/l10n/l10n_util.h"
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/views/message_center_view.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"

namespace message_center {

// ContentsView ////////////////////////////////////////////////////////////////

// Handles changes in MessageCenterView sizes.
class ContentsView : public views::View {
 public:
  explicit ContentsView(MessageCenterBubble* bubble, views::View* contents);
  virtual ~ContentsView();

  // Overridden from views::View:
  virtual int GetHeightForWidth(int width) const OVERRIDE;

 protected:
  // Overridden from views::View:
  virtual void ChildPreferredSizeChanged(View* child) OVERRIDE;

 private:
  base::WeakPtr<MessageCenterBubble> bubble_;

  DISALLOW_COPY_AND_ASSIGN(ContentsView);
};

ContentsView::ContentsView(MessageCenterBubble* bubble, views::View* contents)
    : bubble_(bubble->AsWeakPtr()) {
  SetLayoutManager(new views::FillLayout());
  AddChildView(contents);
}

ContentsView::~ContentsView() {
}

int ContentsView::GetHeightForWidth(int width) const {
  DCHECK_EQ(1, child_count());
  int contents_width = std::max(width - GetInsets().width(), 0);
  int contents_height = child_at(0)->GetHeightForWidth(contents_width);
  return contents_height + GetInsets().height();
}

void ContentsView::ChildPreferredSizeChanged(View* child) {
  // TODO(dharcourt): Reduce the amount of updating this requires.
  if (bubble_.get())
    bubble_->bubble_view()->UpdateBubble();
}

// MessageCenterBubble /////////////////////////////////////////////////////////

MessageCenterBubble::MessageCenterBubble(MessageCenter* message_center,
                                         MessageCenterTray* tray,
                                         bool first_item_has_no_margin)
    : MessageBubbleBase(message_center, tray),
      message_center_view_(NULL),
      initially_settings_visible_(false),
      first_item_has_no_margin_(first_item_has_no_margin),
      title_(l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_FOOTER_TITLE)) {
}

MessageCenterBubble::~MessageCenterBubble() {
}

void MessageCenterBubble::SetSettingsVisible() {
  if (message_center_view_)
    message_center_view_->SetSettingsVisible(true);
  else
    initially_settings_visible_ = true;
}

views::TrayBubbleView::InitParams MessageCenterBubble::GetInitParams(
    views::TrayBubbleView::AnchorAlignment anchor_alignment) {
  views::TrayBubbleView::InitParams init_params =
      GetDefaultInitParams(anchor_alignment);
  init_params.min_width += kMarginBetweenItems * 2;
  init_params.max_width += kMarginBetweenItems * 2;
  init_params.max_height = max_height();
  init_params.can_activate = true;
  init_params.first_item_has_no_margin = first_item_has_no_margin_;
  return init_params;
}

void MessageCenterBubble::InitializeContents(
    views::TrayBubbleView* new_bubble_view) {
  set_bubble_view(new_bubble_view);
  bubble_view()->GetWidget()->AddObserver(this);
  message_center_view_ = new MessageCenterView(
      message_center(),
      tray(),
      max_height(),
      initially_settings_visible_,
      false, /* MessageCenterBubble should be used only on ChromeOS.
              Message center is never shown top down in ChromeOS. */
      title_);
  bubble_view()->AddChildView(new ContentsView(this, message_center_view_));
  // Resize the content of the bubble view to the given bubble size. This is
  // necessary in case of the bubble border forcing a bigger size then the
  // |new_bubble_view| actually wants. See crbug.com/169390.
  bubble_view()->Layout();
  UpdateBubbleView();
}

void MessageCenterBubble::OnBubbleViewDestroyed() {
  message_center_view_ = NULL;
}

void MessageCenterBubble::UpdateBubbleView() {
  if (!bubble_view())
    return;  // Could get called after view is closed
  const NotificationList::Notifications& notifications =
      message_center()->GetVisibleNotifications();
  message_center_view_->SetNotifications(notifications);
  bubble_view()->GetWidget()->Show();
  bubble_view()->UpdateBubble();
}

void MessageCenterBubble::OnWidgetClosing(views::Widget* widget) {
  bubble_view()->GetWidget()->RemoveObserver(this);
  if (message_center_view_)
    message_center_view_->SetIsClosing(true);
}

void MessageCenterBubble::OnMouseEnteredView() {
}

void MessageCenterBubble::OnMouseExitedView() {
}

size_t MessageCenterBubble::NumMessageViewsForTest() const {
  return message_center_view_->NumMessageViewsForTest();
}

}  // namespace message_center
