// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/projector/projector_annotation_tray.h"

#include "ash/constants/ash_pref_names.h"
#include "ash/constants/tray_background_view_catalog.h"
#include "ash/projector/projector_controller_impl.h"
#include "ash/projector/ui/projector_color_button.h"
#include "ash/public/cpp/projector/annotator_tool.h"
#include "ash/public/cpp/shelf_config.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/shelf/shelf.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/style/ash_color_provider.h"
#include "ash/system/tray/hover_highlight_view.h"
#include "ash/system/tray/tray_bubble_wrapper.h"
#include "ash/system/tray/tray_container.h"
#include "ash/system/tray/tray_popup_utils.h"
#include "ash/system/tray/tray_utils.h"
#include "chromeos/constants/chromeos_features.h"
#include "components/prefs/pref_service.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/metadata/metadata_impl_macros.h"
#include "ui/base/models/image_model.h"
#include "ui/chromeos/styles/cros_tokens_color_mappings.h"
#include "ui/compositor/layer.h"
#include "ui/events/event.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/separator.h"
#include "ui/views/layout/box_layout.h"

namespace ash {

namespace {

// Margins between the title view and the edges around it (dp).
constexpr int kPaddingBetweenBottomAndLastTrayItem = 4;

// Width of the bubble itself (dp).
constexpr int kBubbleWidth = 196;

// Insets for the views (dp).
constexpr auto kPenViewPadding = gfx::Insets::TLBR(4, 16, 0, 16);

// Spacing between buttons (dp).
constexpr int kButtonsPadding = 12;

// Size of menu rows.
constexpr int kMenuRowHeight = 48;

// Color selection buttons.
constexpr int kColorButtonColorViewSize = 16;
constexpr int kColorButtonViewRadius = 28;

constexpr SkColor kPenColors[] = {
    kProjectorMagentaPenColor, kProjectorBluePenColor, kProjectorYellowPenColor,
    kProjectorRedPenColor};

// TODO(b/201664243): Use AnnotatorToolType.
enum ProjectorTool { kToolNone, kToolPen };

bool IsAnnotatorEnabled() {
  auto* controller = Shell::Get()->projector_controller();
  // `controller` may not be available yet as the `ProjectorAnnotationTray`
  // is created before it.
  return controller ? controller->IsAnnotatorEnabled() : false;
}

ProjectorTool GetCurrentTool() {
  return IsAnnotatorEnabled() ? kToolPen : kToolNone;
}

const gfx::VectorIcon& GetIconForTool(ProjectorTool tool, SkColor color) {
  switch (tool) {
    case kToolNone:
      return kPaletteTrayIconProjectorIcon;
    case kToolPen:
      switch (color) {
        case kProjectorMagentaPenColor:
          return kPaletteTrayIconProjectorMagentaIcon;
        case kProjectorBluePenColor:
          return kPaletteTrayIconProjectorBlueIcon;
        case kProjectorRedPenColor:
          return kPaletteTrayIconProjectorRedIcon;
        case kProjectorYellowPenColor:
          return kPaletteTrayIconProjectorYellowIcon;
      }
  }

  NOTREACHED();
  return kPaletteTrayIconProjectorIcon;
}

}  // namespace

ProjectorAnnotationTray::ProjectorAnnotationTray(Shelf* shelf)
    : TrayBackgroundView(shelf,
                         TrayBackgroundViewCatalogName::kProjectorAnnotation),
      image_view_(
          tray_container()->AddChildView(std::make_unique<views::ImageView>())),
      pen_view_(nullptr) {
  SetCallback(base::BindRepeating(&ProjectorAnnotationTray::OnTrayButtonPressed,
                                  base::Unretained(this)));

  // Right click should show the bubble. In tablet mode, long press is
  // synonymous with right click, gesture long press must be intercepted via
  // `OnGestureEvent()` override, as `views::Button` forces long press to show a
  // contextual menu.
  SetTriggerableEventFlags(ui::EF_LEFT_MOUSE_BUTTON |
                           ui::EF_RIGHT_MOUSE_BUTTON);

  image_view_->SetTooltipText(GetTooltip());
  image_view_->SetHorizontalAlignment(views::ImageView::Alignment::kCenter);
  image_view_->SetVerticalAlignment(views::ImageView::Alignment::kCenter);
  image_view_->SetPreferredSize(gfx::Size(kTrayItemSize, kTrayItemSize));
  ResetTray();

  session_observer_.Observe(Shell::Get()->session_controller());
}

ProjectorAnnotationTray::~ProjectorAnnotationTray() = default;

void ProjectorAnnotationTray::OnGestureEvent(ui::GestureEvent* event) {
  // Long Press typically is used to show a contextual menu, but because in
  // tablet mode tapping the pod is used to toggle a feature, long press is the
  // only available way to show the bubble.
  // TODO(crbug/1374368): Put this where we handle other button activations,
  // once the `views::Button` code allows it.
  if (event->details().type() != ui::ET_GESTURE_LONG_PRESS) {
    TrayBackgroundView::OnGestureEvent(event);
    return;
  }

  ShowBubble();
}

void ProjectorAnnotationTray::ClickedOutsideBubble() {
  CloseBubble();
}

void ProjectorAnnotationTray::UpdateTrayItemColor(bool is_active) {
  SetIconImage(is_active);
}

std::u16string ProjectorAnnotationTray::GetAccessibleNameForTray() {
  std::u16string enabled_state = l10n_util::GetStringUTF16(
      GetCurrentTool() == kToolNone
          ? IDS_ASH_STATUS_AREA_PROJECTOR_ANNOTATION_TRAY_OFF_STATE
          : IDS_ASH_STATUS_AREA_PROJECTOR_ANNOTATION_TRAY_ON_STATE);
  return l10n_util::GetStringFUTF16(
      IDS_ASH_STATUS_AREA_PROJECTOR_ANNOTATION_TRAY_ACCESSIBLE_TITLE,
      enabled_state);
}

void ProjectorAnnotationTray::HandleLocaleChange() {}

void ProjectorAnnotationTray::HideBubbleWithView(
    const TrayBubbleView* bubble_view) {
  if (bubble_->bubble_view() == bubble_view)
    CloseBubble();
}

void ProjectorAnnotationTray::CloseBubble() {
  pen_view_ = nullptr;
  bubble_.reset();
  // Annotator can be enabled after closing the bubble so set the activity state
  // according to it.
  SetIsActive(IsAnnotatorEnabled());
  shelf()->UpdateAutoHideState();
}

void ProjectorAnnotationTray::ShowBubble() {
  if (bubble_)
    return;

  DCHECK(tray_container());

  TrayBubbleView::InitParams init_params = CreateInitParamsForTrayBubble(this);
  init_params.preferred_width = kBubbleWidth;

  // Create and customize bubble view.
  auto bubble_view = std::make_unique<TrayBubbleView>(init_params);
  bubble_view->SetBorder(views::CreateEmptyBorder(
      gfx::Insets::TLBR(0, 0, kPaddingBetweenBottomAndLastTrayItem, 0)));

  // Add drawing tools
  {
    auto* marker_view_container =
        bubble_view->AddChildView(std::make_unique<views::View>());

    auto box_layout = std::make_unique<views::BoxLayout>(
        views::BoxLayout::Orientation::kHorizontal, kPenViewPadding,
        kButtonsPadding);
    box_layout->set_cross_axis_alignment(
        views::BoxLayout::CrossAxisAlignment::kCenter);
    box_layout->set_minimum_cross_axis_size(kMenuRowHeight);
    marker_view_container->SetLayoutManager(std::move(box_layout));

    for (SkColor color : kPenColors) {
      auto* color_button = marker_view_container->AddChildView(
          std::make_unique<ProjectorColorButton>(
              base::BindRepeating(&ProjectorAnnotationTray::OnPenColorPressed,
                                  base::Unretained(this), color),
              color, kColorButtonColorViewSize, kColorButtonViewRadius,
              l10n_util::GetStringUTF16(GetAccessibleNameForColor(color))));
      color_button->SetToggled(current_pen_color_ == color);
    }
  }

  // Show the bubble.
  bubble_ = std::make_unique<TrayBubbleWrapper>(this);
  bubble_->ShowBubble(std::move(bubble_view));
  SetIsActive(true);
}

TrayBubbleView* ProjectorAnnotationTray::GetBubbleView() {
  return bubble_ ? bubble_->bubble_view() : nullptr;
}

views::Widget* ProjectorAnnotationTray::GetBubbleWidget() const {
  return bubble_ ? bubble_->GetBubbleWidget() : nullptr;
}

void ProjectorAnnotationTray::OnThemeChanged() {
  TrayBackgroundView::OnThemeChanged();
  UpdateIcon();
}

void ProjectorAnnotationTray::HideBubble(const TrayBubbleView* bubble_view) {
  CloseBubble();
}

void ProjectorAnnotationTray::OnActiveUserPrefServiceChanged(
    PrefService* pref_service) {
  const uint64_t color =
      pref_service->GetUint64(prefs::kProjectorAnnotatorLastUsedMarkerColor);
  current_pen_color_ = !color ? kProjectorDefaultPenColor : color;
}

void ProjectorAnnotationTray::HideAnnotationTray() {
  SetVisiblePreferred(false);
  UpdateIcon();
  PrefService* pref_service =
      Shell::Get()->session_controller()->GetActivePrefService();
  pref_service->SetUint64(prefs::kProjectorAnnotatorLastUsedMarkerColor,
                          current_pen_color_);
  ResetTray();
}

void ProjectorAnnotationTray::OnTrayButtonPressed(const ui::Event& event) {
  // NOTE: Long press not supported via the `views::Button` callback, it
  // is handled via OnGestureEvent override.
  if (event.IsMouseEvent() && event.AsMouseEvent()->IsRightMouseButton()) {
    ShowBubble();
    return;
  }

  ToggleAnnotator();
}

void ProjectorAnnotationTray::SetTrayEnabled(bool enabled) {
  SetEnabled(enabled);
  if (enabled)
    return;

  // For disabled state, set icon color to kIconColorPrimary with 30% opacity.
  SkColor disabled_icon_color =
      SkColorSetA(AshColorProvider::Get()->GetContentLayerColor(
                      AshColorProvider::ContentLayerType::kIconColorPrimary),
                  0x4D);
  image_view_->SetImage(gfx::CreateVectorIcon(kPaletteTrayIconProjectorIcon,
                                              disabled_icon_color));
  image_view_->SetTooltipText(l10n_util::GetStringUTF16(
      IDS_ASH_STATUS_AREA_PROJECTOR_ANNOTATION_TRAY_UNAVAILABLE));
}

void ProjectorAnnotationTray::ToggleAnnotator() {
  if (GetCurrentTool() == kToolNone) {
    EnableAnnotatorWithPenColor();
  } else {
    DeactivateActiveTool();
  }
  if (bubble_) {
    CloseBubble();
  }
  UpdateIcon();
}

void ProjectorAnnotationTray::EnableAnnotatorWithPenColor() {
  auto* controller = Shell::Get()->projector_controller();
  DCHECK(controller);
  AnnotatorTool tool;
  tool.color = current_pen_color_;
  controller->SetAnnotatorTool(tool);
  controller->EnableAnnotatorTool();
}

void ProjectorAnnotationTray::DeactivateActiveTool() {
  auto* controller = Shell::Get()->projector_controller();
  DCHECK(controller);
  controller->ResetTools();
}

void ProjectorAnnotationTray::UpdateIcon() {
  bool annotator_toggled = false;
  if (is_active() != IsAnnotatorEnabled()) {
    SetIsActive(IsAnnotatorEnabled());
    annotator_toggled = true;
  }
  // Only sets the image if Jelly is not enabled or if the annotator was not
  // toggled, since `UpdateTrayItemColor()` will be called in `SetIsActive()` to
  // set the image for Jelly only when active state changes.
  if (!chromeos::features::IsJellyEnabled()) {
    image_view_->SetImage(gfx::CreateVectorIcon(
        GetIconForTool(GetCurrentTool(), current_pen_color_),
        AshColorProvider::Get()->GetContentLayerColor(
            AshColorProvider::ContentLayerType::kIconColorPrimary)));
  } else if (!annotator_toggled) {
    SetIconImage(is_active());
  }
  image_view_->SetTooltipText(GetTooltip());
}

void ProjectorAnnotationTray::OnPenColorPressed(SkColor color) {
  current_pen_color_ = color;
  EnableAnnotatorWithPenColor();
  CloseBubble();
  UpdateIcon();
}

int ProjectorAnnotationTray::GetAccessibleNameForColor(SkColor color) {
  switch (color) {
    case kProjectorRedPenColor:
      return IDS_RED_COLOR_BUTTON;
    case kProjectorBluePenColor:
      return IDS_BLUE_COLOR_BUTTON;
    case kProjectorYellowPenColor:
      return IDS_YELLOW_COLOR_BUTTON;
    case kProjectorMagentaPenColor:
      return IDS_MAGENTA_COLOR_BUTTON;
  }
  NOTREACHED();
  return IDS_RED_COLOR_BUTTON;
}

void ProjectorAnnotationTray::ResetTray() {
  // Disable the tray icon. It is enabled once the ink canvas is initialized.
  SetEnabled(false);
}

std::u16string ProjectorAnnotationTray::GetTooltip() {
  std::u16string enabled_state = l10n_util::GetStringUTF16(
      GetCurrentTool() == kToolNone
          ? IDS_ASH_STATUS_AREA_PROJECTOR_ANNOTATION_TRAY_OFF_STATE
          : IDS_ASH_STATUS_AREA_PROJECTOR_ANNOTATION_TRAY_ON_STATE);
  return l10n_util::GetStringFUTF16(
      IDS_ASH_STATUS_AREA_PROJECTOR_ANNOTATION_TRAY_TOOLTIP, enabled_state);
}

void ProjectorAnnotationTray::SetIconImage(bool is_active) {
  DCHECK(chromeos::features::IsJellyEnabled());
  image_view_->SetImage(ui::ImageModel::FromVectorIcon(
      GetIconForTool(GetCurrentTool(), current_pen_color_),
      is_active ? cros_tokens::kCrosSysSystemOnPrimaryContainer
                : cros_tokens::kCrosSysOnSurface));
}

BEGIN_METADATA(ProjectorAnnotationTray)
END_METADATA

}  // namespace ash
