// 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 "ui/views/controls/tabbed_pane/tabbed_pane.h"

#include "base/logging.h"
#include "ui/accessibility/ax_view_state.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/font_list.h"
#include "ui/views/controls/label.h"
#include "ui/views/controls/tabbed_pane/tabbed_pane_listener.h"
#include "ui/views/layout/layout_manager.h"
#include "ui/views/widget/widget.h"

namespace {

// TODO(markusheintz|msw): Use NativeTheme colors.
const SkColor kTabTitleColor_Inactive = SkColorSetRGB(0x64, 0x64, 0x64);
const SkColor kTabTitleColor_Active = SK_ColorBLACK;
const SkColor kTabTitleColor_Hovered = SK_ColorBLACK;
const SkColor kTabBorderColor = SkColorSetRGB(0xC8, 0xC8, 0xC8);
const SkScalar kTabBorderThickness = 1.0f;

}  // namespace

namespace views {

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

// The tab view shown in the tab strip.
class Tab : public View {
 public:
  Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents);
  virtual ~Tab();

  View* contents() const { return contents_; }

  bool selected() const { return contents_->visible(); }
  void SetSelected(bool selected);

  // Overridden from View:
  virtual bool OnMousePressed(const ui::MouseEvent& event) override;
  virtual void OnMouseEntered(const ui::MouseEvent& event) override;
  virtual void OnMouseExited(const ui::MouseEvent& event) override;
  virtual void OnGestureEvent(ui::GestureEvent* event) override;
  virtual gfx::Size GetPreferredSize() const override;
  virtual void Layout() override;

 private:
  enum TabState {
    TAB_INACTIVE,
    TAB_ACTIVE,
    TAB_HOVERED,
  };

  void SetState(TabState tab_state);

  TabbedPane* tabbed_pane_;
  Label* title_;
  gfx::Size preferred_title_size_;
  TabState tab_state_;
  // The content view associated with this tab.
  View* contents_;

  DISALLOW_COPY_AND_ASSIGN(Tab);
};

// The tab strip shown above the tab contents.
class TabStrip : public View {
 public:
  explicit TabStrip(TabbedPane* tabbed_pane);
  virtual ~TabStrip();

  // Overridden from View:
  virtual gfx::Size GetPreferredSize() const override;
  virtual void Layout() override;
  virtual void OnPaint(gfx::Canvas* canvas) override;

 private:
  TabbedPane* tabbed_pane_;

  DISALLOW_COPY_AND_ASSIGN(TabStrip);
};

Tab::Tab(TabbedPane* tabbed_pane, const base::string16& title, View* contents)
    : tabbed_pane_(tabbed_pane),
      title_(new Label(title,
                       ui::ResourceBundle::GetSharedInstance().GetFontList(
                           ui::ResourceBundle::BoldFont))),
      tab_state_(TAB_ACTIVE),
      contents_(contents) {
  // Calculate this now while the font list is guaranteed to be bold.
  preferred_title_size_ = title_->GetPreferredSize();

  SetState(TAB_INACTIVE);
  AddChildView(title_);
}

Tab::~Tab() {}

void Tab::SetSelected(bool selected) {
  contents_->SetVisible(selected);
  SetState(selected ? TAB_ACTIVE : TAB_INACTIVE);
}

bool Tab::OnMousePressed(const ui::MouseEvent& event) {
  if (event.IsOnlyLeftMouseButton() &&
      GetLocalBounds().Contains(event.location()))
    tabbed_pane_->SelectTab(this);
  return true;
}

void Tab::OnMouseEntered(const ui::MouseEvent& event) {
  SetState(selected() ? TAB_ACTIVE : TAB_HOVERED);
}

void Tab::OnMouseExited(const ui::MouseEvent& event) {
  SetState(selected() ? TAB_ACTIVE : TAB_INACTIVE);
}

void Tab::OnGestureEvent(ui::GestureEvent* event) {
  switch (event->type()) {
    case ui::ET_GESTURE_TAP_DOWN:
      // Fallthrough.
    case ui::ET_GESTURE_TAP:
      // SelectTab also sets the right tab color.
      tabbed_pane_->SelectTab(this);
      break;
    case ui::ET_GESTURE_TAP_CANCEL:
      SetState(selected() ? TAB_ACTIVE : TAB_INACTIVE);
      break;
    default:
      break;
  }
  event->SetHandled();
}

gfx::Size Tab::GetPreferredSize() const {
  gfx::Size size(preferred_title_size_);
  size.Enlarge(21, 9);
  const int kTabMinWidth = 54;
  if (size.width() < kTabMinWidth)
    size.set_width(kTabMinWidth);
  return size;
}

void Tab::Layout() {
  gfx::Rect bounds = GetLocalBounds();
  bounds.Inset(0, 1, 0, 0);
  bounds.ClampToCenteredSize(preferred_title_size_);
  title_->SetBoundsRect(bounds);
}

void Tab::SetState(TabState tab_state) {
  if (tab_state == tab_state_)
    return;
  tab_state_ = tab_state;

  ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
  switch (tab_state) {
    case TAB_INACTIVE:
      title_->SetEnabledColor(kTabTitleColor_Inactive);
      title_->SetFontList(rb.GetFontList(ui::ResourceBundle::BaseFont));
      break;
    case TAB_ACTIVE:
      title_->SetEnabledColor(kTabTitleColor_Active);
      title_->SetFontList(rb.GetFontList(ui::ResourceBundle::BoldFont));
      break;
    case TAB_HOVERED:
      title_->SetEnabledColor(kTabTitleColor_Hovered);
      title_->SetFontList(rb.GetFontList(ui::ResourceBundle::BaseFont));
      break;
  }
  SchedulePaint();
}

TabStrip::TabStrip(TabbedPane* tabbed_pane) : tabbed_pane_(tabbed_pane) {}

TabStrip::~TabStrip() {}

gfx::Size TabStrip::GetPreferredSize() const {
  gfx::Size size;
  for (int i = 0; i < child_count(); ++i) {
    const gfx::Size child_size = child_at(i)->GetPreferredSize();
    size.SetSize(size.width() + child_size.width(),
                 std::max(size.height(), child_size.height()));
  }
  return size;
}

void TabStrip::Layout() {
  const int kTabOffset = 9;
  int x = kTabOffset;  // Layout tabs with an offset to the tabstrip border.
  for (int i = 0; i < child_count(); ++i) {
    gfx::Size ps = child_at(i)->GetPreferredSize();
    child_at(i)->SetBounds(x, 0, ps.width(), ps.height());
    x = child_at(i)->bounds().right();
  }
}

void TabStrip::OnPaint(gfx::Canvas* canvas) {
  OnPaintBackground(canvas);

  // Draw the TabStrip border.
  SkPaint paint;
  paint.setColor(kTabBorderColor);
  paint.setStrokeWidth(kTabBorderThickness);
  SkScalar line_y = SkIntToScalar(height()) - (kTabBorderThickness / 2);
  SkScalar line_end = SkIntToScalar(width());
  int selected_tab_index = tabbed_pane_->selected_tab_index();
  if (selected_tab_index >= 0) {
    Tab* selected_tab = tabbed_pane_->GetTabAt(selected_tab_index);
    SkPath path;
    SkScalar tab_height =
        SkIntToScalar(selected_tab->height()) - kTabBorderThickness;
    SkScalar tab_width =
        SkIntToScalar(selected_tab->width()) - kTabBorderThickness;
    SkScalar tab_start = SkIntToScalar(selected_tab->GetMirroredX());
    path.moveTo(0, line_y);
    path.rLineTo(tab_start, 0);
    path.rLineTo(0, -tab_height);
    path.rLineTo(tab_width, 0);
    path.rLineTo(0, tab_height);
    path.lineTo(line_end, line_y);

    SkPaint paint;
    paint.setStyle(SkPaint::kStroke_Style);
    paint.setColor(kTabBorderColor);
    paint.setStrokeWidth(kTabBorderThickness);
    canvas->DrawPath(path, paint);
  } else {
    canvas->sk_canvas()->drawLine(0, line_y, line_end, line_y, paint);
  }
}

TabbedPane::TabbedPane()
  : listener_(NULL),
    tab_strip_(new TabStrip(this)),
    contents_(new View()),
    selected_tab_index_(-1) {
  SetFocusable(true);
  AddChildView(tab_strip_);
  AddChildView(contents_);
}

TabbedPane::~TabbedPane() {}

int TabbedPane::GetTabCount() {
  DCHECK_EQ(tab_strip_->child_count(), contents_->child_count());
  return contents_->child_count();
}

View* TabbedPane::GetSelectedTab() {
  return selected_tab_index() < 0 ?
      NULL : GetTabAt(selected_tab_index())->contents();
}

void TabbedPane::AddTab(const base::string16& title, View* contents) {
  AddTabAtIndex(tab_strip_->child_count(), title, contents);
}

void TabbedPane::AddTabAtIndex(int index,
                               const base::string16& title,
                               View* contents) {
  DCHECK(index >= 0 && index <= GetTabCount());
  contents->SetVisible(false);

  tab_strip_->AddChildViewAt(new Tab(this, title, contents), index);
  contents_->AddChildViewAt(contents, index);
  if (selected_tab_index() < 0)
    SelectTabAt(index);

  PreferredSizeChanged();
}

void TabbedPane::SelectTabAt(int index) {
  DCHECK(index >= 0 && index < GetTabCount());
  if (index == selected_tab_index())
    return;

  if (selected_tab_index() >= 0)
    GetTabAt(selected_tab_index())->SetSelected(false);

  selected_tab_index_ = index;
  Tab* tab = GetTabAt(index);
  tab->SetSelected(true);
  tab_strip_->SchedulePaint();

  FocusManager* focus_manager = tab->contents()->GetFocusManager();
  if (focus_manager) {
    const View* focused_view = focus_manager->GetFocusedView();
    if (focused_view && contents_->Contains(focused_view) &&
        !tab->contents()->Contains(focused_view))
      focus_manager->SetFocusedView(tab->contents());
  }

  if (listener())
    listener()->TabSelectedAt(index);
}

void TabbedPane::SelectTab(Tab* tab) {
  const int index = tab_strip_->GetIndexOf(tab);
  if (index >= 0)
    SelectTabAt(index);
}

gfx::Size TabbedPane::GetPreferredSize() const {
  gfx::Size size;
  for (int i = 0; i < contents_->child_count(); ++i)
    size.SetToMax(contents_->child_at(i)->GetPreferredSize());
  size.Enlarge(0, tab_strip_->GetPreferredSize().height());
  return size;
}

Tab* TabbedPane::GetTabAt(int index) {
  return static_cast<Tab*>(tab_strip_->child_at(index));
}

void TabbedPane::Layout() {
  const gfx::Size size = tab_strip_->GetPreferredSize();
  tab_strip_->SetBounds(0, 0, width(), size.height());
  contents_->SetBounds(0, tab_strip_->bounds().bottom(), width(),
                       std::max(0, height() - size.height()));
  for (int i = 0; i < contents_->child_count(); ++i)
    contents_->child_at(i)->SetSize(contents_->size());
}

void TabbedPane::ViewHierarchyChanged(
    const ViewHierarchyChangedDetails& details) {
  if (details.is_add) {
    // Support navigating tabs by Ctrl+Tab and Ctrl+Shift+Tab.
    AddAccelerator(ui::Accelerator(ui::VKEY_TAB,
                                   ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN));
    AddAccelerator(ui::Accelerator(ui::VKEY_TAB, ui::EF_CONTROL_DOWN));
  }
}

bool TabbedPane::AcceleratorPressed(const ui::Accelerator& accelerator) {
  // Handle Ctrl+Tab and Ctrl+Shift+Tab navigation of pages.
  DCHECK(accelerator.key_code() == ui::VKEY_TAB && accelerator.IsCtrlDown());
  const int tab_count = GetTabCount();
  if (tab_count <= 1)
    return false;
  const int increment = accelerator.IsShiftDown() ? -1 : 1;
  int next_tab_index = (selected_tab_index() + increment) % tab_count;
  // Wrap around.
  if (next_tab_index < 0)
    next_tab_index += tab_count;
  SelectTabAt(next_tab_index);
  return true;
}

const char* TabbedPane::GetClassName() const {
  return kViewClassName;
}

void TabbedPane::OnFocus() {
  View::OnFocus();

  View* selected_tab = GetSelectedTab();
  if (selected_tab) {
    selected_tab->NotifyAccessibilityEvent(
        ui::AX_EVENT_FOCUS, true);
  }
}

void TabbedPane::GetAccessibleState(ui::AXViewState* state) {
  state->role = ui::AX_ROLE_TAB_LIST;
}

}  // namespace views
