// Copyright (c) 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 "ui/message_center/views/toast_contents_view.h"

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/gfx/animation/animation_delegate.h"
#include "ui/gfx/animation/slide_animation.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
#include "ui/message_center/message_center_style.h"
#include "ui/message_center/notification.h"
#include "ui/message_center/views/message_popup_collection.h"
#include "ui/message_center/views/message_view.h"
#include "ui/views/background.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"
#include "ui/views/widget/widget_delegate.h"

#if defined(OS_WIN) && defined(USE_ASH)
#include "ui/views/widget/desktop_aura/desktop_native_widget_aura.h"
#endif

namespace message_center {
namespace {

// The width of a toast before animated reveal and after closing.
const int kClosedToastWidth = 5;

// FadeIn/Out look a bit better if they are slightly longer then default slide.
const int kFadeInOutDuration = 200;

}  // namespace.

// static
gfx::Size ToastContentsView::GetToastSizeForView(views::View* view) {
  int width = kNotificationWidth + view->GetInsets().width();
  return gfx::Size(width, view->GetHeightForWidth(width));
}

ToastContentsView::ToastContentsView(
    const std::string& notification_id,
    base::WeakPtr<MessagePopupCollection> collection)
    : collection_(collection),
      id_(notification_id),
      is_animating_bounds_(false),
      is_closing_(false),
      closing_animation_(NULL) {
  set_notify_enter_exit_on_child(true);
  // Sets the transparent background. Then, when the message view is slid out,
  // the whole toast seems to slide although the actual bound of the widget
  // remains. This is hacky but easier to keep the consistency.
  set_background(views::Background::CreateSolidBackground(0, 0, 0, 0));

  fade_animation_.reset(new gfx::SlideAnimation(this));
  fade_animation_->SetSlideDuration(kFadeInOutDuration);

  CreateWidget(collection->parent());
}

// This is destroyed when the toast window closes.
ToastContentsView::~ToastContentsView() {
  if (collection_)
    collection_->ForgetToast(this);
}

void ToastContentsView::SetContents(MessageView* view,
                                    bool a11y_feedback_for_updates) {
  bool already_has_contents = child_count() > 0;
  RemoveAllChildViews(true);
  AddChildView(view);
  preferred_size_ = GetToastSizeForView(view);
  Layout();

  // If it has the contents already, this invocation means an update of the
  // popup toast, and the new contents should be read through a11y feature.
  // The notification type should be ALERT, otherwise the accessibility message
  // won't be read for this view which returns ROLE_WINDOW.
  if (already_has_contents && a11y_feedback_for_updates)
    NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, false);
}

void ToastContentsView::UpdateContents(const Notification& notification,
                                       bool a11y_feedback_for_updates) {
  DCHECK_GT(child_count(), 0);
  MessageView* message_view = static_cast<MessageView*>(child_at(0));
  message_view->UpdateWithNotification(notification);
  if (a11y_feedback_for_updates)
    NotifyAccessibilityEvent(ui::AX_EVENT_ALERT, false);
}

void ToastContentsView::RevealWithAnimation(gfx::Point origin) {
  // Place/move the toast widgets. Currently it stacks the widgets from the
  // right-bottom of the work area.
  // TODO(mukai): allow to specify the placement policy from outside of this
  // class. The policy should be specified from preference on Windows, or
  // the launcher alignment on ChromeOS.
  origin_ = gfx::Point(origin.x() - preferred_size_.width(),
                       origin.y() - preferred_size_.height());

  gfx::Rect stable_bounds(origin_, preferred_size_);

  SetBoundsInstantly(GetClosedToastBounds(stable_bounds));
  StartFadeIn();
  SetBoundsWithAnimation(stable_bounds);
}

void ToastContentsView::CloseWithAnimation() {
  if (is_closing_)
    return;
  is_closing_ = true;
  StartFadeOut();
}

void ToastContentsView::SetBoundsInstantly(gfx::Rect new_bounds) {
  if (new_bounds == bounds())
    return;

  origin_ = new_bounds.origin();
  if (!GetWidget())
    return;
  GetWidget()->SetBounds(new_bounds);
}

void ToastContentsView::SetBoundsWithAnimation(gfx::Rect new_bounds) {
  if (new_bounds == bounds())
    return;

  origin_ = new_bounds.origin();
  if (!GetWidget())
    return;

  // This picks up the current bounds, so if there was a previous animation
  // half-done, the next one will pick up from the current location.
  // This is the only place that should query current location of the Widget
  // on screen, the rest should refer to the bounds_.
  animated_bounds_start_ = GetWidget()->GetWindowBoundsInScreen();
  animated_bounds_end_ = new_bounds;

  if (collection_)
    collection_->IncrementDeferCounter();

  if (bounds_animation_.get())
    bounds_animation_->Stop();

  bounds_animation_.reset(new gfx::SlideAnimation(this));
  bounds_animation_->Show();
}

void ToastContentsView::StartFadeIn() {
  // The decrement is done in OnBoundsAnimationEndedOrCancelled callback.
  if (collection_)
    collection_->IncrementDeferCounter();
  fade_animation_->Stop();

  GetWidget()->SetOpacity(0);
  GetWidget()->ShowInactive();
  fade_animation_->Reset(0);
  fade_animation_->Show();
}

void ToastContentsView::StartFadeOut() {
  // The decrement is done in OnBoundsAnimationEndedOrCancelled callback.
  if (collection_)
    collection_->IncrementDeferCounter();
  fade_animation_->Stop();

  closing_animation_ = (is_closing_ ? fade_animation_.get() : NULL);
  fade_animation_->Reset(1);
  fade_animation_->Hide();
}

void ToastContentsView::OnBoundsAnimationEndedOrCancelled(
    const gfx::Animation* animation) {
  if (is_closing_ && closing_animation_ == animation && GetWidget()) {
    views::Widget* widget = GetWidget();

    // TODO(dewittj): This is a workaround to prevent a nasty bug where
    // closing a transparent widget doesn't actually remove the window,
    // causing entire areas of the screen to become unresponsive to clicks.
    // See crbug.com/243469
    widget->Hide();
#if defined(OS_WIN)
    widget->SetOpacity(0xFF);
#endif

    widget->Close();
  }

  // This cannot be called before GetWidget()->Close(). Decrementing defer count
  // will invoke update, which may invoke another close animation with
  // incrementing defer counter. Close() after such process will cause a
  // mismatch between increment/decrement. See crbug.com/238477
  if (collection_)
    collection_->DecrementDeferCounter();
}

// gfx::AnimationDelegate
void ToastContentsView::AnimationProgressed(const gfx::Animation* animation) {
  if (animation == bounds_animation_.get()) {
    gfx::Rect current(animation->CurrentValueBetween(
        animated_bounds_start_, animated_bounds_end_));
    GetWidget()->SetBounds(current);
  } else if (animation == fade_animation_.get()) {
    unsigned char opacity =
        static_cast<unsigned char>(fade_animation_->GetCurrentValue() * 255);
    GetWidget()->SetOpacity(opacity);
  }
}

void ToastContentsView::AnimationEnded(const gfx::Animation* animation) {
  OnBoundsAnimationEndedOrCancelled(animation);
}

void ToastContentsView::AnimationCanceled(
    const gfx::Animation* animation) {
  OnBoundsAnimationEndedOrCancelled(animation);
}

// views::WidgetDelegate
views::View* ToastContentsView::GetContentsView() {
  return this;
}

void ToastContentsView::WindowClosing() {
  if (!is_closing_ && collection_.get())
    collection_->ForgetToast(this);
}

bool ToastContentsView::CanActivate() const {
  return false;
}

void ToastContentsView::OnDisplayChanged() {
  views::Widget* widget = GetWidget();
  if (!widget)
    return;

  gfx::NativeView native_view = widget->GetNativeView();
  if (!native_view || !collection_.get())
    return;

  collection_->OnDisplayBoundsChanged(gfx::Screen::GetScreenFor(
      native_view)->GetDisplayNearestWindow(native_view));
}

void ToastContentsView::OnWorkAreaChanged() {
  views::Widget* widget = GetWidget();
  if (!widget)
    return;

  gfx::NativeView native_view = widget->GetNativeView();
  if (!native_view || !collection_.get())
    return;

  collection_->OnDisplayBoundsChanged(gfx::Screen::GetScreenFor(
      native_view)->GetDisplayNearestWindow(native_view));
}

// views::View
void ToastContentsView::OnMouseEntered(const ui::MouseEvent& event) {
  if (collection_)
    collection_->OnMouseEntered(this);
}

void ToastContentsView::OnMouseExited(const ui::MouseEvent& event) {
  if (collection_)
    collection_->OnMouseExited(this);
}

void ToastContentsView::Layout() {
  if (child_count() > 0) {
    child_at(0)->SetBounds(
        0, 0, preferred_size_.width(), preferred_size_.height());
  }
}

gfx::Size ToastContentsView::GetPreferredSize() {
  return child_count() ? GetToastSizeForView(child_at(0)) : gfx::Size();
}

void ToastContentsView::GetAccessibleState(ui::AXViewState* state) {
  if (child_count() > 0)
    child_at(0)->GetAccessibleState(state);
  state->role = ui::AX_ROLE_WINDOW;
}

void ToastContentsView::ClickOnNotification(
    const std::string& notification_id) {
  if (collection_)
    collection_->ClickOnNotification(notification_id);
}

void ToastContentsView::RemoveNotification(
    const std::string& notification_id,
    bool by_user) {
  if (collection_)
    collection_->RemoveNotification(notification_id, by_user);
}

scoped_ptr<ui::MenuModel> ToastContentsView::CreateMenuModel(
      const NotifierId& notifier_id,
      const base::string16& display_source) {
  // Should not reach, the context menu should be handled in
  // MessagePopupCollection.
  NOTREACHED();
  return scoped_ptr<ui::MenuModel>();
}

bool ToastContentsView::HasClickedListener(
    const std::string& notification_id) {
  if (!collection_)
    return false;
  return collection_->HasClickedListener(notification_id);
}

void ToastContentsView::ClickOnNotificationButton(
    const std::string& notification_id,
    int button_index) {
  if (collection_)
    collection_->ClickOnNotificationButton(notification_id, button_index);
}

void ToastContentsView::CreateWidget(gfx::NativeView parent) {
  views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
  params.keep_on_top = true;
  if (parent)
    params.parent = parent;
  else
    params.top_level = true;
  params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW;
  params.delegate = this;
  views::Widget* widget = new views::Widget();
  widget->set_focus_on_creation(false);

#if defined(OS_WIN) && defined(USE_ASH)
  // We want to ensure that this toast always goes to the native desktop,
  // not the Ash desktop (since there is already another toast contents view
  // there.
  if (!params.parent)
    params.native_widget = new views::DesktopNativeWidgetAura(widget);
#endif

  widget->Init(params);
}

gfx::Rect ToastContentsView::GetClosedToastBounds(gfx::Rect bounds) {
  return gfx::Rect(bounds.x() + bounds.width() - kClosedToastWidth,
                   bounds.y(),
                   kClosedToastWidth,
                   bounds.height());
}

}  // namespace message_center
