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

#include <memory>

#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/extensions/hosted_app_browser_controller.h"
#include "chrome/browser/ui/layout_constants.h"
#include "chrome/browser/ui/omnibox/omnibox_theme.h"
#include "chrome/browser/ui/page_info/page_info_dialog.h"
#include "chrome/browser/ui/views/chrome_typography.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/frame/hosted_app_button_container.h"
#include "components/url_formatter/url_formatter.h"
#include "components/vector_icons/vector_icons.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_entry.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/color_palette.h"
#include "ui/gfx/color_utils.h"
#include "ui/gfx/paint_vector_icon.h"
#include "ui/strings/grit/ui_strings.h"
#include "ui/views/background.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/button/image_button_factory.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/style/typography.h"
#include "ui/views/style/typography_provider.h"
#include "ui/views/view_properties.h"
#include "url/gurl.h"

#if defined(OS_CHROMEOS)
#include "ash/public/cpp/ash_constants.h"
#else
#include "chrome/browser/themes/theme_properties.h"
#endif

namespace {

constexpr SkColor kBackgroundColor = SK_ColorWHITE;

// The frame color is different on ChromeOS and other platforms because Ash
// specifies its own default frame color, which is not exposed through
// BrowserNonClientFrameView::GetFrameColor.
SkColor GetDefaultFrameColor() {
#if defined(OS_CHROMEOS)
  return ash::kDefaultFrameColor;
#else
  return ThemeProperties::GetDefaultColor(ThemeProperties::COLOR_FRAME, false);
#endif
}

views::ImageButton* CreateCloseButton(views::ButtonListener* listener,
                                      SkColor color) {
  views::ImageButton* close_button = CreateVectorImageButton(listener);
  SetImageFromVectorIconWithColor(close_button, vector_icons::kCloseRoundedIcon,
                                  color);
  close_button->SetTooltipText(l10n_util::GetStringUTF16(IDS_APP_CLOSE));
  close_button->SizeToPreferredSize();

  // Use a circular ink drop.
  auto highlight_path = std::make_unique<SkPath>();
  highlight_path->addOval(gfx::RectToSkRect(gfx::Rect(close_button->size())));
  close_button->SetProperty(views::kHighlightPathKey, highlight_path.release());

  return close_button;
}

void GoBackToApp(content::WebContents* web_contents) {
  Browser* browser = chrome::FindBrowserWithWebContents(web_contents);
  GURL launch_url = browser->hosted_app_controller()->GetAppLaunchURL();
  content::NavigationController& controller = web_contents->GetController();
  content::BrowserContext* context = web_contents->GetBrowserContext();

  content::NavigationEntry* entry = nullptr;
  int offset = 0;

  // Go back until we find an in scope url, or run out of urls.
  while ((entry = controller.GetEntryAtOffset(offset)) &&
         !extensions::IsSameScope(entry->GetURL(), launch_url, context)) {
    offset--;
  }

  // If there are no in scope urls, push the app's launch url and clear
  // the history.
  if (!entry) {
    content::NavigationController::LoadURLParams load(launch_url);
    load.should_clear_history_list = true;
    controller.LoadURLWithParams(load);
    return;
  }

  // Otherwise, go back to the first in scope url.
  controller.GoToOffset(offset);
}

}  // namespace

// Container view for laying out and rendering the title/origin of the current
// page.
class CustomTabBarTitleOriginView : public views::View {
 public:
  explicit CustomTabBarTitleOriginView(SkColor foreground_color,
                                       SkColor background_color) {
    title_label_ = new views::Label(
        base::string16(), views::style::TextContext::CONTEXT_DIALOG_TITLE);
    location_label_ = new views::Label(base::string16());

    title_label_->SetEnabledColor(foreground_color);
    title_label_->SetBackgroundColor(background_color);
    location_label_->SetEnabledColor(foreground_color);
    title_label_->SetBackgroundColor(background_color);

    AddChildView(title_label_);
    AddChildView(location_label_);

    auto layout = std::make_unique<views::BoxLayout>(
        views::BoxLayout::Orientation::kVertical, gfx::Insets(), 0);
    layout->set_cross_axis_alignment(
        views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_START);
    SetLayoutManager(std::move(layout));
  }

  void Update(base::string16 title, base::string16 location) {
    title_label_->SetText(title);
    location_label_->SetText(location);
  }

 private:
  views::Label* title_label_;
  views::Label* location_label_;
};

// static
const char CustomTabBarView::kViewClassName[] = "CustomTabBarView";

CustomTabBarView::CustomTabBarView(BrowserView* browser_view,
                                   LocationBarView::Delegate* delegate)
    : TabStripModelObserver(),
      delegate_(delegate),
      tab_strip_model_observer_(this) {
  Browser* browser = browser_view->browser();
  base::Optional<SkColor> optional_theme_color =
      browser->hosted_app_controller()->GetThemeColor();

  // If we have a theme color, use that, otherwise fall back to the default
  // frame color.
  title_bar_color_ = optional_theme_color.value_or(GetDefaultFrameColor());
  SetBackground(views::CreateSolidBackground(kBackgroundColor));

  constexpr SkColor kForegroundColor = gfx::kGoogleGrey900;

  const gfx::FontList& font_list = views::style::GetFont(
      CONTEXT_OMNIBOX_PRIMARY, views::style::STYLE_PRIMARY);

  close_button_ = CreateCloseButton(this, kForegroundColor);
  AddChildView(close_button_);

  location_icon_view_ = new LocationIconView(font_list, this);
  AddChildView(location_icon_view_);

  title_origin_view_ =
      new CustomTabBarTitleOriginView(kForegroundColor, kBackgroundColor);
  AddChildView(title_origin_view_);

  int padding = GetLayoutConstant(LayoutConstant::LOCATION_BAR_ELEMENT_PADDING);
  // The location icon already has some padding, so we subtract it from the
  // padding we're going to apply.
  int location_icon_padding =
      GetLayoutInsets(LayoutInset::LOCATION_BAR_ICON_INTERIOR_PADDING).left();
  gfx::Insets insets(padding, padding - location_icon_padding, padding,
                     padding);

  auto layout = std::make_unique<views::BoxLayout>(
      views::BoxLayout::Orientation::kHorizontal, insets, 0);
  layout->set_cross_axis_alignment(
      views::BoxLayout::CrossAxisAlignment::CROSS_AXIS_ALIGNMENT_CENTER);

  SetLayoutManager(std::move(layout));

  tab_strip_model_observer_.Add(browser->tab_strip_model());
}

CustomTabBarView::~CustomTabBarView() {}

void CustomTabBarView::TabChangedAt(content::WebContents* contents,
                                    int index,
                                    TabChangeType change_type) {
  if (!contents)
    return;

  content::NavigationEntry* entry = contents->GetController().GetVisibleEntry();
  base::string16 title, location;
  if (entry) {
    title = Browser::FormatTitleForDisplay(entry->GetTitleForDisplay());
    location = url_formatter::FormatUrl(
        entry->GetVirtualURL(), url_formatter::kFormatUrlOmitDefaults,
        net::UnescapeRule::NORMAL, nullptr, nullptr, nullptr);
  }

  title_origin_view_->Update(title, location);
  location_icon_view_->Update(/*suppress animations = */ false);

  last_title_ = title;
  last_location_ = location;

  Layout();
}

void CustomTabBarView::OnPaintBackground(gfx::Canvas* canvas) {
  views::View::OnPaintBackground(canvas);

  constexpr SkColor kSeparatorColor = SK_ColorBLACK;
  constexpr float kSeparatorOpacity = 0.15f;

  gfx::Rect bounds = GetLocalBounds();
  // Inset the bounds by 1 on the bottom, so we draw the bottom border inside
  // the custom tab bar.
  bounds.Inset(0, 0, 0, 1);

  // Custom tab/content separator (bottom border).
  canvas->DrawLine(bounds.bottom_left(), bounds.bottom_right(),
                   color_utils::AlphaBlend(kSeparatorColor, kBackgroundColor,
                                           kSeparatorOpacity));

  // Don't render the separator if there is already sufficient contrast between
  // the custom tab bar and the title bar.
  constexpr float kMaxContrastForSeparator = 1.1f;
  if (color_utils::GetContrastRatio(kBackgroundColor, title_bar_color_) >
      kMaxContrastForSeparator) {
    return;
  }

  // Frame/Custom tab separator (top border).
  canvas->DrawLine(bounds.origin(), bounds.top_right(),
                   color_utils::AlphaBlend(kSeparatorColor, title_bar_color_,
                                           kSeparatorOpacity));
}

content::WebContents* CustomTabBarView::GetWebContents() {
  return delegate_->GetWebContents();
}

bool CustomTabBarView::IsEditingOrEmpty() {
  return false;
}

void CustomTabBarView::OnLocationIconPressed(const ui::MouseEvent& event) {}

void CustomTabBarView::OnLocationIconDragged(const ui::MouseEvent& event) {}

bool CustomTabBarView::ShowPageInfoDialog() {
  return ::ShowPageInfoDialog(GetWebContents(),
                              bubble_anchor_util::Anchor::kCustomTabBar);
}

SkColor CustomTabBarView::GetSecurityChipColor(
    security_state::SecurityLevel security_level) const {
  return GetOmniboxSecurityChipColor(OmniboxTint::LIGHT, security_level);
}

gfx::ImageSkia CustomTabBarView::GetLocationIcon(
    LocationIconView::Delegate::IconFetchedCallback on_icon_fetched) const {
  return gfx::CreateVectorIcon(
      delegate_->GetLocationBarModel()->GetVectorIcon(),
      GetLayoutConstant(LOCATION_BAR_ICON_SIZE),
      GetSecurityChipColor(GetLocationBarModel()->GetSecurityLevel(false)));
}

SkColor CustomTabBarView::GetLocationIconInkDropColor() const {
  return GetNativeTheme()->GetSystemColor(
      ui::NativeTheme::kColorId_TextfieldDefaultColor);
}

const LocationBarModel* CustomTabBarView::GetLocationBarModel() const {
  return delegate_->GetLocationBarModel();
}

void CustomTabBarView::ButtonPressed(views::Button* sender,
                                     const ui::Event& event) {
  GoBackToApp(GetWebContents());
}
