// Copyright 2018 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/media/media_notification_view.h"

#include "ash/media/media_notification_constants.h"
#include "ash/media/media_notification_controller.h"
#include "ash/shell.h"
#include "base/stl_util.h"
#include "components/vector_icons/vector_icons.h"
#include "services/media_session/public/mojom/media_session.mojom.h"
#include "ui/gfx/font.h"
#include "ui/gfx/font_list.h"
#include "ui/message_center/message_center.h"
#include "ui/message_center/public/cpp/message_center_constants.h"
#include "ui/message_center/views/notification_control_buttons_view.h"
#include "ui/message_center/views/notification_header_view.h"
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/style/typography.h"

namespace ash {

using media_session::mojom::MediaSessionAction;

namespace {

// The right padding is 1/5th the size of the notification.
constexpr int kRightMarginSize = message_center::kNotificationWidth / 5;

// The right padding is 1/3rd the size of the notification when the
// notification is expanded.
constexpr int kRightMarginExpandedSize = message_center::kNotificationWidth / 3;

// Dimensions.
constexpr int kDefaultMarginSize = 16;
constexpr int kMediaButtonIconSize = 24;

SkColor GetMediaNotificationColor(const views::View& view) {
  return views::style::GetColor(view, views::style::CONTEXT_LABEL,
                                views::style::STYLE_PRIMARY);
}

bool ShouldShowActionWhenCollapsed(MediaSessionAction action) {
  return action == MediaSessionAction::kPlay ||
         action == MediaSessionAction::kPause ||
         action == MediaSessionAction::kNextTrack ||
         action == MediaSessionAction::kPreviousTrack;
}

}  // namespace

MediaNotificationView::MediaNotificationView(
    const message_center::Notification& notification)
    : message_center::MessageView(notification) {
  SetLayoutManager(std::make_unique<views::BoxLayout>(
      views::BoxLayout::kVertical, gfx::Insets(), 0));

  // |controls_button_view_| has the common notification control buttons.
  control_buttons_view_ =
      std::make_unique<message_center::NotificationControlButtonsView>(this);
  control_buttons_view_->set_owned_by_client();

  // |header_row_| contains app_icon, app_name, control buttons, etc.
  header_row_ = new message_center::NotificationHeaderView(
      control_buttons_view_.get(), this);
  header_row_->SetExpandButtonEnabled(true);
  header_row_->SetAppName(
      message_center::MessageCenter::Get()->GetSystemNotificationAppName());
  AddChildView(header_row_);

  // |main_row_| holds the main content of the notification.
  main_row_ = new views::View();
  AddChildView(main_row_);

  // |title_artist_row_| contains the title and artist labels.
  title_artist_row_ = new views::View();
  auto* title_artist_row_layout =
      title_artist_row_->SetLayoutManager(std::make_unique<views::BoxLayout>(
          views::BoxLayout::kVertical, gfx::Insets(), 0));
  title_artist_row_layout->set_main_axis_alignment(
      views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
  title_artist_row_layout->set_cross_axis_alignment(
      views::BoxLayout::CROSS_AXIS_ALIGNMENT_START);
  title_artist_row_->SetVisible(false);
  main_row_->AddChildView(title_artist_row_);

  title_label_ = new views::Label(base::string16(), views::style::CONTEXT_LABEL,
                                  views::style::STYLE_PRIMARY);
  const gfx::FontList& base_font_list = views::Label::GetDefaultFontList();
  title_label_->SetFontList(base_font_list.Derive(
      0, gfx::Font::FontStyle::NORMAL, gfx::Font::Weight::SEMIBOLD));
  title_label_->SetVisible(false);
  title_artist_row_->AddChildView(title_label_);

  artist_label_ =
      new views::Label(base::string16(), views::style::CONTEXT_LABEL,
                       views::style::STYLE_PRIMARY);
  artist_label_->SetVisible(false);
  title_artist_row_->AddChildView(artist_label_);

  // |button_row_| contains the buttons for controlling playback.
  button_row_ = new views::View();
  auto* button_row_layout =
      button_row_->SetLayoutManager(std::make_unique<views::BoxLayout>(
          views::BoxLayout::kHorizontal, gfx::Insets(), 0));
  button_row_layout->set_main_axis_alignment(
      views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
  button_row_layout->set_cross_axis_alignment(
      views::BoxLayout::CROSS_AXIS_ALIGNMENT_STRETCH);
  button_row_layout->SetDefaultFlex(1);
  main_row_->AddChildView(button_row_);

  CreateMediaButton(vector_icons::kMediaPreviousTrackIcon,
                    MediaSessionAction::kPreviousTrack);
  CreateMediaButton(vector_icons::kMediaSeekBackwardIcon,
                    MediaSessionAction::kSeekBackward);

  // |play_pause_button_| toggles playback.
  play_pause_button_ = views::CreateVectorToggleImageButton(this);
  play_pause_button_->set_tag(static_cast<int>(MediaSessionAction::kPlay));
  SkColor play_button_color = GetMediaNotificationColor(*play_pause_button_);
  views::SetImageFromVectorIcon(play_pause_button_,
                                vector_icons::kPlayArrowIcon,
                                kMediaButtonIconSize, play_button_color);
  views::SetToggledImageFromVectorIcon(play_pause_button_,
                                       vector_icons::kPauseIcon,
                                       kMediaButtonIconSize, play_button_color);
  button_row_->AddChildView(play_pause_button_);

  CreateMediaButton(vector_icons::kMediaSeekForwardIcon,
                    MediaSessionAction::kSeekForward);
  CreateMediaButton(vector_icons::kMediaNextTrackIcon,
                    MediaSessionAction::kNextTrack);

  // TODO(beccahughes): Add remaining UI for notification.

  UpdateControlButtonsVisibilityWithNotification(notification);
  UpdateCornerRadius(message_center::kNotificationCornerRadius,
                     message_center::kNotificationCornerRadius);
  UpdateViewForExpandedState();

  Shell::Get()->media_notification_controller()->SetView(notification_id(),
                                                         this);
}

MediaNotificationView::~MediaNotificationView() {
  Shell::Get()->media_notification_controller()->SetView(notification_id(),
                                                         nullptr);
}

void MediaNotificationView::UpdateWithNotification(
    const message_center::Notification& notification) {
  MessageView::UpdateWithNotification(notification);

  UpdateControlButtonsVisibilityWithNotification(notification);
  Layout();
  SchedulePaint();
}

message_center::NotificationControlButtonsView*
MediaNotificationView::GetControlButtonsView() const {
  return control_buttons_view_.get();
}

void MediaNotificationView::SetExpanded(bool expanded) {
  if (expanded_ == expanded)
    return;

  expanded_ = expanded;

  UpdateViewForExpandedState();
  PreferredSizeChanged();
}

void MediaNotificationView::OnMouseEvent(ui::MouseEvent* event) {
  switch (event->type()) {
    case ui::ET_MOUSE_ENTERED:
    case ui::ET_MOUSE_EXITED:
      UpdateControlButtonsVisibility();
      break;
    default:
      break;
  }

  View::OnMouseEvent(event);
}

void MediaNotificationView::ButtonPressed(views::Button* sender,
                                          const ui::Event& event) {
  if (sender == header_row_) {
    SetExpanded(!expanded_);
    return;
  }

  if (sender->parent() == button_row_) {
    message_center::MessageCenter::Get()->ClickOnNotificationButton(
        notification_id(), sender->tag());
    return;
  }

  NOTREACHED();
}

void MediaNotificationView::UpdateWithMediaSessionInfo(
    const media_session::mojom::MediaSessionInfoPtr& session_info) {
  bool playing = session_info->playback_state ==
                 media_session::mojom::MediaPlaybackState::kPlaying;
  play_pause_button_->SetToggled(playing);

  MediaSessionAction action =
      playing ? MediaSessionAction::kPause : MediaSessionAction::kPlay;
  play_pause_button_->set_tag(static_cast<int>(action));
  play_pause_button_->SetVisible(IsActionButtonVisible(action));
  PreferredSizeChanged();
}

void MediaNotificationView::UpdateWithMediaMetadata(
    const media_session::MediaMetadata& metadata) {
  if (metadata.title.empty() && metadata.artist.empty()) {
    title_artist_row_->SetVisible(false);
    return;
  }

  title_artist_row_->SetVisible(true);

  title_label_->SetText(metadata.title);
  title_label_->SetVisible(!metadata.title.empty());

  artist_label_->SetText(metadata.artist);
  artist_label_->SetVisible(!metadata.artist.empty());
}

void MediaNotificationView::UpdateWithMediaActions(
    const std::set<media_session::mojom::MediaSessionAction>& actions) {
  enabled_actions_ = actions;
  UpdateActionButtonsVisibility();
  PreferredSizeChanged();
}

void MediaNotificationView::UpdateControlButtonsVisibilityWithNotification(
    const message_center::Notification& notification) {
  // Media notifications do not use the settings and snooze buttons.
  DCHECK(!notification.should_show_settings_button());
  DCHECK(!notification.should_show_snooze_button());

  control_buttons_view_->ShowCloseButton(!notification.pinned());
  UpdateControlButtonsVisibility();
}

bool MediaNotificationView::IsActionButtonVisible(
    MediaSessionAction action) const {
  // Not all media sessions support the same actions.
  bool visible = base::ContainsKey(enabled_actions_, action);

  // We should reduce the number of action buttons we show when we are
  // collapsed.
  // TODO(beccahughes): Use priority based ranking here
  if (!expanded_ && visible)
    visible = ShouldShowActionWhenCollapsed(action);

  return visible;
}

void MediaNotificationView::UpdateActionButtonsVisibility() {
  for (int i = 0; i < button_row_->child_count(); ++i) {
    views::Button* action_button =
        views::Button::AsButton(button_row_->child_at(i));

    action_button->SetVisible(IsActionButtonVisible(
        static_cast<MediaSessionAction>(action_button->tag())));
  }
}

void MediaNotificationView::UpdateViewForExpandedState() {
  // Adjust the layout of the |main_row_| based on the expanded state. If the
  // notification is expanded then the buttons should be below the title/artist
  // information. If it is collapsed then the buttons will be to the right.
  if (expanded_) {
    main_row_
        ->SetLayoutManager(std::make_unique<views::BoxLayout>(
            views::BoxLayout::kVertical,
            gfx::Insets(kDefaultMarginSize, kDefaultMarginSize,
                        kDefaultMarginSize, kRightMarginExpandedSize),
            kDefaultMarginSize))
        ->SetDefaultFlex(1);
  } else {
    main_row_
        ->SetLayoutManager(std::make_unique<views::BoxLayout>(
            views::BoxLayout::kHorizontal,
            gfx::Insets(0, kDefaultMarginSize, kDefaultMarginSize,
                        kRightMarginSize),
            kDefaultMarginSize, true))
        ->SetDefaultFlex(1);
  }

  header_row_->SetExpanded(expanded_);

  UpdateActionButtonsVisibility();
}

void MediaNotificationView::CreateMediaButton(const gfx::VectorIcon& icon,
                                              MediaSessionAction action) {
  views::ImageButton* button = views::CreateVectorImageButton(this);
  button->set_tag(static_cast<int>(action));
  views::SetImageFromVectorIcon(button, icon, kMediaButtonIconSize,
                                GetMediaNotificationColor(*button));
  button_row_->AddChildView(button);
}

}  // namespace ash
