// 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 "chrome/browser/ui/views/page_info/permission_selector_row.h"

#include "base/bind.h"
#include "base/i18n/rtl.h"
#include "base/macros.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/page_info/page_info_ui.h"
#include "chrome/browser/ui/page_info/permission_menu_model.h"
#include "chrome/browser/ui/views/accessibility/non_accessible_image_view.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "chrome/browser/ui/views/chrome_typography.h"
#include "chrome/browser/ui/views/page_info/page_info_bubble_view.h"
#include "components/strings/grit/components_strings.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/models/combobox_model.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/image/image.h"
#include "ui/views/controls/combobox/combobox.h"
#include "ui/views/controls/combobox/combobox_listener.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/view.h"
#include "ui/views/widget/widget.h"

namespace {

// The text context / style of the |PermissionSelectorRow| combobox and label.
constexpr int kPermissionRowTextContext = views::style::CONTEXT_LABEL;
constexpr int kPermissionRowTextStyle = views::style::STYLE_PRIMARY;

}  // namespace

namespace internal {

// This class adapts a |PermissionMenuModel| into a |ui::ComboboxModel| so that
// |PermissionCombobox| can use it.
class ComboboxModelAdapter : public ui::ComboboxModel {
 public:
  explicit ComboboxModelAdapter(PermissionMenuModel* model) : model_(model) {}
  ~ComboboxModelAdapter() override {}

  void OnPerformAction(int index);

  // Returns the checked index of the underlying PermissionMenuModel, of which
  // there must be exactly one. This is used to choose which index is selected
  // in the PermissionCombobox.
  int GetCheckedIndex();

  // ui::ComboboxModel:
  int GetItemCount() const override;
  base::string16 GetItemAt(int index) override;

 private:
  PermissionMenuModel* model_;
};

void ComboboxModelAdapter::OnPerformAction(int index) {
  int command_id = model_->GetCommandIdAt(index);
  model_->ExecuteCommand(command_id, 0);
}

int ComboboxModelAdapter::GetCheckedIndex() {
  int checked_index = -1;
  for (int i = 0; i < model_->GetItemCount(); ++i) {
    int command_id = model_->GetCommandIdAt(i);
    if (model_->IsCommandIdChecked(command_id)) {
      // This function keeps track of |checked_index| instead of returning early
      // here so that it can DCHECK that there's exactly one selected item,
      // which is not normally guaranteed by MenuModel, but *is* true of
      // PermissionMenuModel.
      DCHECK_EQ(checked_index, -1);
      checked_index = i;
    }
  }
  return checked_index;
}

int ComboboxModelAdapter::GetItemCount() const {
  DCHECK(model_);
  return model_->GetItemCount();
}

base::string16 ComboboxModelAdapter::GetItemAt(int index) {
  return model_->GetLabelAt(index);
}

// The |PermissionCombobox| provides a combobox for selecting a permission type.
class PermissionCombobox : public views::Combobox,
                           public views::ComboboxListener {
 public:
  PermissionCombobox(ComboboxModelAdapter* model,
                     bool enabled,
                     bool use_default);
  ~PermissionCombobox() override;

  void UpdateSelectedIndex(bool use_default);

  void set_min_width(int width) { min_width_ = width; }

  // views::Combobox:
  gfx::Size CalculatePreferredSize() const override;

 private:
  // views::ComboboxListener:
  void OnPerformAction(Combobox* combobox) override;

  ComboboxModelAdapter* model_;

  // Minimum width for |PermissionCombobox|.
  int min_width_ = 0;

  DISALLOW_COPY_AND_ASSIGN(PermissionCombobox);
};

PermissionCombobox::PermissionCombobox(ComboboxModelAdapter* model,
                                       bool enabled,
                                       bool use_default)
    : views::Combobox(model), model_(model) {
  set_listener(this);
  SetEnabled(enabled);
  UpdateSelectedIndex(use_default);
  set_size_to_largest_label(false);
}

PermissionCombobox::~PermissionCombobox() {}

void PermissionCombobox::UpdateSelectedIndex(bool use_default) {
  int index = model_->GetCheckedIndex();
  if (use_default && index == -1) {
    index = 0;
  }
  SetSelectedIndex(index);
}

gfx::Size PermissionCombobox::CalculatePreferredSize() const {
  gfx::Size preferred_size = Combobox::CalculatePreferredSize();
  preferred_size.SetToMax(gfx::Size(min_width_, 0));
  return preferred_size;
}

void PermissionCombobox::OnPerformAction(Combobox* combobox) {
  model_->OnPerformAction(combobox->GetSelectedIndex());
}

}  // namespace internal

///////////////////////////////////////////////////////////////////////////////
// PermissionSelectorRow
///////////////////////////////////////////////////////////////////////////////

PermissionSelectorRow::PermissionSelectorRow(
    Profile* profile,
    const GURL& url,
    const PageInfoUI::PermissionInfo& permission,
    views::GridLayout* layout)
    : profile_(profile), icon_(nullptr), combobox_(nullptr) {
  const int list_item_padding = ChromeLayoutProvider::Get()->GetDistanceMetric(
                                    DISTANCE_CONTROL_LIST_VERTICAL) /
                                2;
  layout->StartRowWithPadding(1.0, PageInfoBubbleView::kPermissionColumnSetId,
                              views::GridLayout::kFixedSize, list_item_padding);

  // Create the permission icon and label.
  icon_ = new NonAccessibleImageView();
  layout->AddView(icon_);
  // Create the label that displays the permission type.
  label_ =
      new views::Label(PageInfoUI::PermissionTypeToUIString(permission.type),
                       CONTEXT_BODY_TEXT_LARGE);
  icon_->SetImage(
      PageInfoUI::GetPermissionIcon(permission, label_->enabled_color()));
  layout->AddView(label_);
  // Create the menu model.
  menu_model_.reset(new PermissionMenuModel(
      profile, url, permission,
      base::Bind(&PermissionSelectorRow::PermissionChanged,
                 base::Unretained(this))));

  // Create the permission combobox.
  InitializeComboboxView(layout, permission);

  // Show the permission decision reason, if it was not the user.
  base::string16 reason =
      PageInfoUI::PermissionDecisionReasonToUIString(profile, permission, url);
  if (!reason.empty()) {
    layout->StartRow(1.0, PageInfoBubbleView::kPermissionColumnSetId);
    layout->SkipColumns(1);
    views::Label* secondary_label = new views::Label(reason);
    secondary_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    secondary_label->SetEnabledColor(PageInfoUI::GetSecondaryTextColor());
    // The |secondary_label| should wrap when it's too long instead of
    // stretching its parent view horizontally, but also ensure long strings
    // aren't wrapped too early.
    int preferred_width = secondary_label->GetPreferredSize().width();
    secondary_label->SetMultiLine(true);

    views::ColumnSet* column_set =
        layout->GetColumnSet(PageInfoBubbleView::kPermissionColumnSetId);
    DCHECK(column_set);
    // Secondary labels in Harmony may not overlap into space shared with the
    // combobox column.
    const int column_span = 1;

    // Long labels that cannot fit in the existing space under the permission
    // label should be allowed to use up to |kMaxSecondaryLabelWidth| for
    // display.
    constexpr int kMaxSecondaryLabelWidth = 140;
    if (preferred_width > kMaxSecondaryLabelWidth) {
      layout->AddView(secondary_label, column_span, 1.0,
                      views::GridLayout::LEADING, views::GridLayout::CENTER,
                      kMaxSecondaryLabelWidth, 0);
    } else {
      layout->AddView(secondary_label, column_span, 1.0,
                      views::GridLayout::FILL, views::GridLayout::CENTER);
    }
  }
  layout->AddPaddingRow(views::GridLayout::kFixedSize,
                        CalculatePaddingBeneathPermissionRow(!reason.empty()));
}

PermissionSelectorRow::~PermissionSelectorRow() {
  // Gross. On paper the Combobox and the ComboboxModelAdapter are both owned by
  // this class, but actually, the Combobox is owned by View and will be
  // destroyed in ~View(), which runs *after* ~PermissionSelectorRow() is done,
  // which means the Combobox gets destroyed after its ComboboxModel, which
  // causes an explosion when the Combobox attempts to stop observing the
  // ComboboxModel. This hack ensures the Combobox is deleted before its
  // ComboboxModel.
  delete combobox_;
}

int PermissionSelectorRow::CalculatePaddingBeneathPermissionRow(
    bool has_reason) {
  const int list_item_padding = ChromeLayoutProvider::Get()->GetDistanceMetric(
                                    DISTANCE_CONTROL_LIST_VERTICAL) /
                                2;
  if (!has_reason)
    return list_item_padding;

  const int combobox_height = MinHeightForPermissionRow();
  // Match the amount of padding above the |PermissionSelectorRow| title text
  // here by calculating its full height of this |PermissionSelectorRow| and
  // subtracting the line height, then dividing everything by two. Note it is
  // assumed the combobox is the tallest part of the row.
  return (list_item_padding * 2 + combobox_height -
          views::style::GetLineHeight(kPermissionRowTextContext,
                                      kPermissionRowTextStyle)) /
         2;
}

int PermissionSelectorRow::MinHeightForPermissionRow() {
  return ChromeLayoutProvider::Get()->GetControlHeightForFont(
      kPermissionRowTextContext, kPermissionRowTextStyle,
      combobox_->GetFontList());
}

void PermissionSelectorRow::AddObserver(
    PermissionSelectorRowObserver* observer) {
  observer_list_.AddObserver(observer);
}

void PermissionSelectorRow::InitializeComboboxView(
    views::GridLayout* layout,
    const PageInfoUI::PermissionInfo& permission) {
  bool button_enabled =
      permission.source == content_settings::SETTING_SOURCE_USER;
  combobox_model_adapter_.reset(
      new internal::ComboboxModelAdapter(menu_model_.get()));
  combobox_ = new internal::PermissionCombobox(combobox_model_adapter_.get(),
                                               button_enabled, true);
  combobox_->SetEnabled(button_enabled);
  combobox_->SetTooltipText(l10n_util::GetStringFUTF16(
      IDS_PAGE_INFO_SELECTOR_TOOLTIP,
      PageInfoUI::PermissionTypeToUIString(permission.type)));
  layout->AddView(combobox_);
}

void PermissionSelectorRow::PermissionChanged(
    const PageInfoUI::PermissionInfo& permission) {
  // Change the permission icon to reflect the selected setting.
  icon_->SetImage(
      PageInfoUI::GetPermissionIcon(permission, label_->enabled_color()));

  bool use_default = permission.setting == CONTENT_SETTING_DEFAULT;
  auto* combobox = static_cast<internal::PermissionCombobox*>(combobox_);
  combobox->UpdateSelectedIndex(use_default);

  for (PermissionSelectorRowObserver& observer : observer_list_) {
    observer.OnPermissionChanged(permission);
  }
}

int PermissionSelectorRow::GetComboboxWidth() const {
  return combobox_->Combobox::GetPreferredSize().width();
}

void PermissionSelectorRow::SetMinComboboxWidth(int width) {
  auto* combobox = static_cast<internal::PermissionCombobox*>(combobox_);
  combobox->set_min_width(width);
}
