// 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 "ash/system/tray_caps_lock.h"

#include <memory>

#include "ash/accessibility/accessibility_controller.h"
#include "ash/ime/ime_controller.h"
#include "ash/metrics/user_metrics_recorder.h"
#include "ash/public/cpp/config.h"
#include "ash/resources/vector_icons/vector_icons.h"
#include "ash/session/session_controller.h"
#include "ash/shell.h"
#include "ash/strings/grit/ash_strings.h"
#include "ash/system/caps_lock_notification_controller.h"
#include "ash/system/tray/actionable_view.h"
#include "ash/system/tray/tray_constants.h"
#include "ash/system/tray/tray_popup_item_style.h"
#include "ash/system/tray/tray_popup_utils.h"
#include "ash/system/tray/tri_view.h"
#include "base/sys_info.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/gfx/image/image.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/views/border.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/widget/widget.h"

namespace ash {
namespace {

// Padding used to position the caption in the caps lock default view row.
const int kCaptionRightPadding = 6;

bool IsCapsLockEnabled() {
  return Shell::Get()->ime_controller()->IsCapsLockEnabled();
}

}  // namespace

class CapsLockDefaultView : public ActionableView {
 public:
  CapsLockDefaultView()
      : ActionableView(nullptr, TrayPopupInkDropStyle::FILL_BOUNDS),
        text_label_(TrayPopupUtils::CreateDefaultLabel()),
        shortcut_label_(TrayPopupUtils::CreateDefaultLabel()) {
    shortcut_label_->SetEnabled(false);

    TriView* tri_view(TrayPopupUtils::CreateDefaultRowView());
    SetLayoutManager(std::make_unique<views::FillLayout>());
    AddChildView(tri_view);

    auto* image = TrayPopupUtils::CreateMainImageView();
    image->SetEnabled(enabled());
    TrayPopupItemStyle default_view_style(
        TrayPopupItemStyle::FontStyle::DEFAULT_VIEW_LABEL);
    image->SetImage(gfx::CreateVectorIcon(kSystemMenuCapsLockIcon,
                                          default_view_style.GetIconColor()));
    default_view_style.SetupLabel(text_label_);

    TrayPopupItemStyle caption_style(TrayPopupItemStyle::FontStyle::CAPTION);
    caption_style.SetupLabel(shortcut_label_);

    SetInkDropMode(InkDropHostView::InkDropMode::ON);

    tri_view->AddView(TriView::Container::START, image);
    tri_view->AddView(TriView::Container::CENTER, text_label_);
    tri_view->AddView(TriView::Container::END, shortcut_label_);
    tri_view->SetContainerBorder(
        TriView::Container::END,
        views::CreateEmptyBorder(
            0, 0, 0, kCaptionRightPadding + kTrayPopupLabelRightPadding));
  }

  ~CapsLockDefaultView() override = default;

  // Updates the label text and the shortcut text.
  void Update(bool caps_lock_enabled) {
    const int text_string_id = caps_lock_enabled
                                   ? IDS_ASH_STATUS_TRAY_CAPS_LOCK_ENABLED
                                   : IDS_ASH_STATUS_TRAY_CAPS_LOCK_DISABLED;
    text_label_->SetText(l10n_util::GetStringUTF16(text_string_id));

    int shortcut_string_id = 0;
    const bool search_mapped_to_caps_lock =
        CapsLockNotificationController::IsSearchKeyMappedToCapsLock();
    if (caps_lock_enabled) {
      shortcut_string_id =
          search_mapped_to_caps_lock
              ? IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_SEARCH_OR_SHIFT
              : IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_ALT_SEARCH_OR_SHIFT;
    } else {
      shortcut_string_id =
          search_mapped_to_caps_lock
              ? IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_SEARCH
              : IDS_ASH_STATUS_TRAY_CAPS_LOCK_SHORTCUT_ALT_SEARCH;
    }
    shortcut_label_->SetText(l10n_util::GetStringUTF16(shortcut_string_id));

    Layout();
  }

 private:
  void GetAccessibleNodeData(ui::AXNodeData* node_data) override {
    node_data->role = ax::mojom::Role::kButton;
    node_data->SetName(text_label_->text());
  }

  // ActionableView:
  bool PerformAction(const ui::Event& event) override {
    bool new_state = !IsCapsLockEnabled();
    Shell::Get()->ime_controller()->SetCapsLockEnabled(new_state);
    Shell::Get()->metrics()->RecordUserMetricsAction(
        new_state ? UMA_STATUS_AREA_CAPS_LOCK_ENABLED_BY_CLICK
                  : UMA_STATUS_AREA_CAPS_LOCK_DISABLED_BY_CLICK);
    return true;
  }

  // It indicates whether the Caps Lock is on or off.
  views::Label* text_label_;

  // It indicates the shortcut can be used to turn on or turn off Caps Lock.
  views::Label* shortcut_label_;

  DISALLOW_COPY_AND_ASSIGN(CapsLockDefaultView);
};

TrayCapsLock::TrayCapsLock(SystemTray* system_tray)
    : TrayImageItem(system_tray, kSystemTrayCapsLockIcon, UMA_CAPS_LOCK),
      default_(nullptr),
      caps_lock_enabled_(IsCapsLockEnabled()) {
  Shell::Get()->ime_controller()->AddObserver(this);
}

TrayCapsLock::~TrayCapsLock() {
  Shell::Get()->ime_controller()->RemoveObserver(this);
}

void TrayCapsLock::OnCapsLockChanged(bool enabled) {
  caps_lock_enabled_ = enabled;

  if (tray_view())
    tray_view()->SetVisible(caps_lock_enabled_);

  if (default_)
    default_->Update(caps_lock_enabled_);
}

bool TrayCapsLock::GetInitialVisibility() {
  return IsCapsLockEnabled();
}

views::View* TrayCapsLock::CreateDefaultView(LoginStatus status) {
  if (!caps_lock_enabled_)
    return nullptr;
  DCHECK(!default_);
  default_ = new CapsLockDefaultView;
  default_->Update(caps_lock_enabled_);
  return default_;
}

void TrayCapsLock::OnDefaultViewDestroyed() {
  default_ = nullptr;
}

}  // namespace ash
