// Copyright 2014 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/app_list/views/search_result_tile_item_view.h"

#include "ash/app_list/model/app_list_view_state.h"
#include "ash/app_list/model/search/search_result.h"
#include "base/i18n/number_formatting.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/user_metrics.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/accessibility/ax_node_data.h"
#include "ui/app_list/app_list_constants.h"
#include "ui/app_list/app_list_features.h"
#include "ui/app_list/app_list_view_delegate.h"
#include "ui/app_list/pagination_model.h"
#include "ui/app_list/vector_icons/vector_icons.h"
#include "ui/app_list/views/search_result_container_view.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/canvas_image_source.h"
#include "ui/gfx/image/image_skia_operations.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/background.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/focus/focus_manager.h"

namespace app_list {

namespace {

constexpr int kSearchTileWidth = 80;
constexpr int kSearchTileTopPadding = 4;
constexpr int kSearchTitleSpacing = 5;
constexpr int kSearchPriceSize = 37;
constexpr int kSearchRatingSize = 26;
constexpr int kSearchRatingStarSize = 12;
constexpr int kSearchRatingStarHorizontalSpacing = 1;
constexpr int kSearchRatingStarVerticalSpacing = 2;

constexpr int kIconSelectedSize = 56;
constexpr int kIconSelectedCornerRadius = 4;
// Icon selected color, #000 8%.
constexpr int kIconSelectedColor = SkColorSetARGBMacro(0x14, 0x00, 0x00, 0x00);

constexpr SkColor kSearchTitleColor =
    SkColorSetARGBMacro(0xDF, 0x00, 0x00, 0x00);
constexpr SkColor kSearchAppRatingColor =
    SkColorSetARGBMacro(0x8F, 0x00, 0x00, 0x00);
constexpr SkColor kSearchAppPriceColor =
    SkColorSetARGBMacro(0xFF, 0x0F, 0x9D, 0x58);
constexpr SkColor kSearchRatingStarColor =
    SkColorSetARGBMacro(0x8F, 0x00, 0x00, 0x00);

// The background image source for badge.
class BadgeBackgroundImageSource : public gfx::CanvasImageSource {
 public:
  explicit BadgeBackgroundImageSource(int size)
      : CanvasImageSource(gfx::Size(size, size), false),
        radius_(static_cast<float>(size / 2)) {}
  ~BadgeBackgroundImageSource() override = default;

 private:
  // gfx::CanvasImageSource overrides:
  void Draw(gfx::Canvas* canvas) override {
    cc::PaintFlags flags;
    flags.setColor(SK_ColorWHITE);
    flags.setAntiAlias(true);
    flags.setStyle(cc::PaintFlags::kFill_Style);
    canvas->DrawCircle(gfx::PointF(radius_, radius_), radius_, flags);
  }

  const float radius_;

  DISALLOW_COPY_AND_ASSIGN(BadgeBackgroundImageSource);
};

}  // namespace

SearchResultTileItemView::SearchResultTileItemView(
    SearchResultContainerView* result_container,
    AppListViewDelegate* view_delegate,
    PaginationModel* pagination_model)
    : views::Button(this),
      result_container_(result_container),
      view_delegate_(view_delegate),
      pagination_model_(pagination_model),
      is_play_store_app_search_enabled_(
          features::IsPlayStoreAppSearchEnabled()),
      weak_ptr_factory_(this) {
  SetFocusBehavior(FocusBehavior::ALWAYS);

  // When |item_| is null, the tile is invisible. Calling SetSearchResult with a
  // non-null item makes the tile visible.
  SetVisible(false);

  // Prevent the icon view from interfering with our mouse events.
  icon_ = new views::ImageView;
  icon_->set_can_process_events_within_subtree(false);
  icon_->SetVerticalAlignment(views::ImageView::LEADING);
  AddChildView(icon_);

  if (is_play_store_app_search_enabled_) {
    badge_ = new views::ImageView;
    badge_->set_can_process_events_within_subtree(false);
    badge_->SetVerticalAlignment(views::ImageView::LEADING);
    badge_->SetVisible(false);
    AddChildView(badge_);
  }

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  title_ = new views::Label;
  title_->SetAutoColorReadabilityEnabled(false);
  title_->SetEnabledColor(kGridTitleColor);
  title_->SetFontList(rb.GetFontList(kItemTextFontStyle));
  title_->SetHorizontalAlignment(gfx::ALIGN_CENTER);
  title_->SetHandlesTooltips(false);
  AddChildView(title_);

  if (is_play_store_app_search_enabled_) {
    const gfx::FontList& font = AppListAppTitleFont();
    rating_ = new views::Label;
    rating_->SetEnabledColor(kSearchAppRatingColor);
    rating_->SetFontList(font);
    rating_->SetLineHeight(font.GetHeight());
    rating_->SetHorizontalAlignment(gfx::ALIGN_RIGHT);
    rating_->SetVisible(false);
    AddChildView(rating_);

    rating_star_ = new views::ImageView;
    rating_star_->set_can_process_events_within_subtree(false);
    rating_star_->SetVerticalAlignment(views::ImageView::LEADING);
    rating_star_->SetImage(gfx::CreateVectorIcon(
        kIcBadgeRatingIcon, kSearchRatingStarSize, kSearchRatingStarColor));
    rating_star_->SetVisible(false);
    AddChildView(rating_star_);

    price_ = new views::Label;
    price_->SetEnabledColor(kSearchAppPriceColor);
    price_->SetFontList(font);
    price_->SetLineHeight(font.GetHeight());
    price_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    price_->SetVisible(false);
    AddChildView(price_);
  }

  set_context_menu_controller(this);
}

SearchResultTileItemView::~SearchResultTileItemView() {
  if (item_)
    item_->RemoveObserver(this);
}

void SearchResultTileItemView::SetSearchResult(SearchResult* item) {
  // Handle the case where this may be called from a nested run loop while its
  // context menu is showing. This cancels the menu (it's for the old item).
  context_menu_runner_.reset();

  SetVisible(!!item);

  SearchResult* old_item = item_;
  if (old_item)
    old_item->RemoveObserver(this);

  item_ = item;

  if (!item)
    return;

  item_->AddObserver(this);

  SetTitle(item_->title());
  SetRating(item_->rating());
  SetPrice(item_->formatted_price());

  const gfx::FontList& font = AppListAppTitleFont();
  if (IsSuggestedAppTile()) {
    title_->SetFontList(font);
    title_->SetLineHeight(font.GetHeight());
    title_->SetEnabledColor(kGridTitleColor);
  } else {
    DCHECK_EQ(SearchResult::DISPLAY_TILE, item_->display_type());
    // Set solid color background to avoid broken text. See crbug.com/746563.
    if (rating_) {
      rating_->SetBackground(
          views::CreateSolidBackground(kCardBackgroundColor));
    }
    if (price_) {
      price_->SetBackground(views::CreateSolidBackground(kCardBackgroundColor));
    }
    title_->SetBackground(views::CreateSolidBackground(kCardBackgroundColor));
    title_->SetFontList(font);
    title_->SetLineHeight(font.GetHeight());
    title_->SetEnabledColor(kSearchTitleColor);
  }

  title_->SetMaxLines(2);
  title_->SetMultiLine(item_->display_type() == SearchResult::DISPLAY_TILE &&
                       item_->result_type() ==
                           SearchResult::RESULT_INSTALLED_APP);

  // Only refresh the icon if it's different from the old one. This prevents
  // flickering.
  // If the new icon is null, it's being decoded asynchronously. Not updating it
  // now to prevent flickering from showing an empty icon while decoding.
  if (!item->icon().isNull() &&
      (!old_item || !item->icon().BackedBySameObjectAs(old_item->icon()))) {
    OnIconChanged();
  }
  if (!old_item ||
      !item->badge_icon().BackedBySameObjectAs(old_item->badge_icon())) {
    OnBadgeIconChanged();
  }

  base::string16 accessible_name = title_->text();
  if (rating_ && rating_->visible()) {
    accessible_name +=
        base::UTF8ToUTF16(", ") +
        l10n_util::GetStringFUTF16(IDS_APP_ACCESSIBILITY_STAR_RATING_ARC,
                                   rating_->text());
  }
  if (price_ && price_->visible())
    accessible_name += base::UTF8ToUTF16(", ") + price_->text();
  SetAccessibleName(accessible_name);
}

void SearchResultTileItemView::SetParentBackgroundColor(SkColor color) {
  parent_background_color_ = color;
  UpdateBackgroundColor();
}

void SearchResultTileItemView::OnContextMenuClosed(
    const base::TimeTicks& open_time) {
  base::TimeDelta user_journey_time = base::TimeTicks::Now() - open_time;
  if (IsSuggestedAppTile()) {
    if (view_delegate_->GetModel()->state_fullscreen() ==
        AppListViewState::PEEKING) {
      UMA_HISTOGRAM_TIMES("Apps.ContextMenuUserJourneyTime.SuggestedAppPeeking",
                          user_journey_time);
    } else {
      UMA_HISTOGRAM_TIMES(
          "Apps.ContextMenuUserJourneyTime.SuggestedAppFullscreen",
          user_journey_time);
    }
  } else {
    UMA_HISTOGRAM_TIMES("Apps.ContextMenuUserJourneyTime.SearchResult",
                        user_journey_time);
  }
}

void SearchResultTileItemView::ButtonPressed(views::Button* sender,
                                             const ui::Event& event) {
  if (IsSuggestedAppTile())
    LogAppLaunch();

  view_delegate_->OpenSearchResult(item_, event.flags());
}

void SearchResultTileItemView::GetAccessibleNodeData(
    ui::AXNodeData* node_data) {
  views::Button::GetAccessibleNodeData(node_data);
  // Specify |ui::AX_ATTR_DESCRIPTION| with an empty string, so that long
  // truncated names are not read twice.
  // Details of this issue:
  // - The Play Store app's name is shown in a label |title_|.
  // - If the name is too long, it'll get truncated and the full name will
  //   go to the label's tooltip.
  // - SearchResultTileItemView uses that label's tooltip as its tooltip.
  // - If a view doesn't have |ui::AX_ATTR_DESCRIPTION| defined in the
  //   |AXNodeData|, |AXViewObjWrapper::Serialize| will use the tooltip text
  //   as its description.
  // - We're customizing this view's accessible name, so it get focused
  //   ChromeVox will read its accessible name and then its description.
  node_data->AddStringAttribute(ui::AX_ATTR_DESCRIPTION, "");
}

bool SearchResultTileItemView::OnKeyPressed(const ui::KeyEvent& event) {
  // Return early if |item_| was deleted due to the search result list changing.
  // see crbug.com/801142
  if (!item_)
    return true;

  if (event.key_code() == ui::VKEY_RETURN) {
    if (IsSuggestedAppTile())
      LogAppLaunch();

    view_delegate_->OpenSearchResult(item_, event.flags());
    return true;
  }

  return false;
}

void SearchResultTileItemView::OnFocus() {
  if (pagination_model_ && IsSuggestedAppTile() &&
      view_delegate_->GetModel()->state() == AppListModel::STATE_APPS) {
    // Go back to first page when app in suggestions container is focused.
    pagination_model_->SelectPage(0, false);
  } else if (!IsSuggestedAppTile()) {
    ScrollRectToVisible(GetLocalBounds());
  }
  UpdateBackgroundColor();
}

void SearchResultTileItemView::OnBlur() {
  UpdateBackgroundColor();
}

void SearchResultTileItemView::StateChanged(ButtonState old_state) {
  UpdateBackgroundColor();
}

void SearchResultTileItemView::PaintButtonContents(gfx::Canvas* canvas) {
  if (!item_ || !HasFocus())
    return;

  gfx::Rect rect(GetContentsBounds());
  cc::PaintFlags flags;
  flags.setAntiAlias(true);
  flags.setStyle(cc::PaintFlags::kFill_Style);
  if (IsSuggestedAppTile()) {
    rect.Inset((rect.width() - kGridSelectedSize) / 2,
               (rect.height() - kGridSelectedSize) / 2);
    flags.setColor(kGridSelectedColor);
    canvas->DrawRoundRect(gfx::RectF(rect), kGridSelectedCornerRadius, flags);
  } else {
    DCHECK(item_->display_type() == SearchResult::DISPLAY_TILE);
    const int kLeftRightPadding = (rect.width() - kIconSelectedSize) / 2;
    rect.Inset(kLeftRightPadding, 0);
    rect.set_height(kIconSelectedSize);
    flags.setColor(kIconSelectedColor);
    canvas->DrawRoundRect(gfx::RectF(rect), kIconSelectedCornerRadius, flags);
  }
}

void SearchResultTileItemView::OnIconChanged() {
  SetIcon(item_->icon());
  Layout();
}

void SearchResultTileItemView::OnBadgeIconChanged() {
  SetBadgeIcon(item_->badge_icon());
  Layout();
}

void SearchResultTileItemView::OnRatingChanged() {
  SetRating(item_->rating());
}

void SearchResultTileItemView::OnFormattedPriceChanged() {
  SetPrice(item_->formatted_price());
}

void SearchResultTileItemView::OnResultDestroying() {
  // The menu comes from |item_|. If we're showing a menu we need to cancel it.
  context_menu_runner_.reset();

  if (item_)
    item_->RemoveObserver(this);

  SetSearchResult(nullptr);
}

void SearchResultTileItemView::ShowContextMenuForView(
    views::View* source,
    const gfx::Point& point,
    ui::MenuSourceType source_type) {
  // |item_| could be null when result list is changing.
  if (!item_)
    return;

  ui::MenuModel* menu_model = item_->GetContextMenuModel();
  if (!menu_model)
    return;

  if (IsSuggestedAppTile()) {
    if (view_delegate_->GetModel()->state_fullscreen() ==
        AppListViewState::PEEKING) {
      UMA_HISTOGRAM_ENUMERATION(
          "Apps.ContextMenuShowSource.SuggestedAppPeeking", source_type,
          ui::MenuSourceType::MENU_SOURCE_TYPE_LAST);
    } else {
      UMA_HISTOGRAM_ENUMERATION(
          "Apps.ContextMenuShowSource.SuggestedAppFullscreen", source_type,
          ui::MenuSourceType::MENU_SOURCE_TYPE_LAST);
    }
  } else {
    UMA_HISTOGRAM_ENUMERATION("Apps.ContextMenuShowSource.SearchResult",
                              source_type,
                              ui::MenuSourceType::MENU_SOURCE_TYPE_LAST);
  }

  // TODO(warx): This is broken (https://crbug.com/795994).
  if (!HasFocus())
    result_container_->ClearSelectedIndex();

  context_menu_runner_.reset(new views::MenuRunner(
      menu_model, views::MenuRunner::HAS_MNEMONICS,
      base::Bind(&SearchResultTileItemView::OnContextMenuClosed,
                 weak_ptr_factory_.GetWeakPtr(), base::TimeTicks::Now())));
  context_menu_runner_->RunMenuAt(GetWidget(), nullptr,
                                  gfx::Rect(point, gfx::Size()),
                                  views::MENU_ANCHOR_TOPLEFT, source_type);
}

void SearchResultTileItemView::SetIcon(const gfx::ImageSkia& icon) {
  icon_->SetImage(icon);
}

void SearchResultTileItemView::SetBadgeIcon(const gfx::ImageSkia& badge_icon) {
  if (!badge_)
    return;

  if (badge_icon.isNull()) {
    badge_->SetVisible(false);
    return;
  }

  const int size = kBadgeBackgroundRadius * 2;
  gfx::ImageSkia background(std::make_unique<BadgeBackgroundImageSource>(size),
                            gfx::Size(size, size));
  gfx::ImageSkia icon_with_background =
      gfx::ImageSkiaOperations::CreateSuperimposedImage(background, badge_icon);

  gfx::ShadowValues shadow_values;
  shadow_values.push_back(
      gfx::ShadowValue(gfx::Vector2d(0, 1), 0, SkColorSetARGB(0x33, 0, 0, 0)));
  shadow_values.push_back(
      gfx::ShadowValue(gfx::Vector2d(0, 1), 2, SkColorSetARGB(0x33, 0, 0, 0)));
  badge_->SetImage(gfx::ImageSkiaOperations::CreateImageWithDropShadow(
      icon_with_background, shadow_values));
  badge_->SetVisible(true);
}

void SearchResultTileItemView::SetTitle(const base::string16& title) {
  title_->SetText(title);
}

void SearchResultTileItemView::SetRating(float rating) {
  if (!rating_)
    return;

  if (rating < 0) {
    rating_->SetVisible(false);
    rating_star_->SetVisible(false);
    return;
  }

  rating_->SetText(base::FormatDouble(rating, 1));
  rating_->SetVisible(true);
  rating_star_->SetVisible(true);
}

void SearchResultTileItemView::SetPrice(const base::string16& price) {
  if (!price_)
    return;

  if (price.empty()) {
    price_->SetVisible(false);
    return;
  }

  price_->SetText(price);
  price_->SetVisible(true);
}

bool SearchResultTileItemView::IsSuggestedAppTile() const {
  return item_ && item_->display_type() == SearchResult::DISPLAY_RECOMMENDATION;
}

void SearchResultTileItemView::LogAppLaunch() const {
  // Only log the app launch if the class is being used as a suggested app.
  if (!IsSuggestedAppTile())
    return;

  UMA_HISTOGRAM_BOOLEAN(kAppListAppLaunchedFullscreen,
                        true /* suggested app */);
  base::RecordAction(base::UserMetricsAction("AppList_OpenSuggestedApp"));
}

void SearchResultTileItemView::UpdateBackgroundColor() {
  // Tell the label what color it will be drawn onto. It will use whether the
  // background color is opaque or transparent to decide whether to use subpixel
  // rendering. Does not actually set the label's background color.
  title_->SetBackgroundColor(parent_background_color_);
  SchedulePaint();
}

void SearchResultTileItemView::Layout() {
  gfx::Rect rect(GetContentsBounds());
  if (rect.IsEmpty() || !item_)
    return;

  if (IsSuggestedAppTile()) {
    rect.Inset(0, kGridIconTopPadding, 0, 0);
    icon_->SetBoundsRect(rect);

    rect.Inset(kGridTitleHorizontalPadding,
               kGridIconDimension + kGridTitleSpacing,
               kGridTitleHorizontalPadding, 0);
    rect.set_height(title_->GetPreferredSize().height());
    title_->SetBoundsRect(rect);
  } else {
    DCHECK(item_->display_type() == SearchResult::DISPLAY_TILE);
    rect.Inset(0, kSearchTileTopPadding, 0, 0);
    icon_->SetBoundsRect(rect);

    if (badge_) {
      gfx::Rect badge_rect(rect);
      gfx::Size icon_size = icon_->GetImage().size();
      badge_rect.Offset(
          (icon_size.width() - kAppBadgeIconSize) / 2,
          icon_size.height() - kBadgeBackgroundRadius - kAppBadgeIconSize / 2);
      badge_->SetBoundsRect(badge_rect);
    }

    rect.Inset(0, kGridIconDimension + kSearchTitleSpacing, 0, 0);
    rect.set_height(title_->GetPreferredSize().height());
    title_->SetBoundsRect(rect);

    if (rating_) {
      gfx::Rect rating_rect(rect);
      rating_rect.Inset(0, title_->GetPreferredSize().height(), 0, 0);
      rating_rect.set_size(rating_->GetPreferredSize());
      rating_rect.set_width(kSearchRatingSize);
      rating_->SetBoundsRect(rating_rect);
    }

    if (rating_star_) {
      gfx::Rect rating_star_rect(rect);
      rating_star_rect.Inset(
          kSearchRatingSize + kSearchRatingStarHorizontalSpacing,
          title_->GetPreferredSize().height() +
              kSearchRatingStarVerticalSpacing,
          0, 0);
      rating_star_rect.set_size(rating_star_->GetPreferredSize());
      rating_star_->SetBoundsRect(rating_star_rect);
    }

    if (price_) {
      gfx::Rect price_rect(rect);
      price_rect.Inset(rect.width() - kSearchPriceSize,
                       title_->GetPreferredSize().height(), 0, 0);
      price_rect.set_size(price_->GetPreferredSize());
      price_->SetBoundsRect(price_rect);
    }
  }
}

const char* SearchResultTileItemView::GetClassName() const {
  return "SearchResultTileItemView";
}

gfx::Size SearchResultTileItemView::CalculatePreferredSize() const {
  if (!item_)
    return gfx::Size();

  if (IsSuggestedAppTile())
    return gfx::Size(kGridTileWidth, kGridTileHeight);

  DCHECK(item_->display_type() == SearchResult::DISPLAY_TILE);
  return gfx::Size(kSearchTileWidth, kSearchTileHeight);
}

bool SearchResultTileItemView::GetTooltipText(const gfx::Point& p,
                                              base::string16* tooltip) const {
  // Use the label to generate a tooltip, so that it will consider its text
  // truncation in making the tooltip. We do not want the label itself to have a
  // tooltip, so we only temporarily enable it to get the tooltip text from the
  // label, then disable it again.
  title_->SetHandlesTooltips(true);
  bool handled = title_->GetTooltipText(p, tooltip);
  title_->SetHandlesTooltips(false);
  return handled;
}

}  // namespace app_list
