// 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/table/table_view.h"

#include <map>

#include "base/auto_reset.h"
#include "base/i18n/rtl.h"
#include "ui/events/event.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/image/image_skia.h"
#include "ui/gfx/rect_conversions.h"
#include "ui/gfx/skia_util.h"
#include "ui/gfx/text_utils.h"
#include "ui/native_theme/native_theme.h"
#include "ui/views/controls/scroll_view.h"
#include "ui/views/controls/table/table_grouper.h"
#include "ui/views/controls/table/table_header.h"
#include "ui/views/controls/table/table_utils.h"
#include "ui/views/controls/table/table_view_observer.h"
#include "ui/views/controls/table/table_view_row_background_painter.h"

// Padding around the text (on each side).
static const int kTextVerticalPadding = 3;
static const int kTextHorizontalPadding = 6;

// Size of images.
static const int kImageSize = 16;

static const int kGroupingIndicatorSize = 6;

namespace views {

namespace {

// Returns result, unless ascending is false in which case -result is returned.
int SwapCompareResult(int result, bool ascending) {
  return ascending ? result : -result;
}

// Populates |model_index_to_range_start| based on the |grouper|.
void GetModelIndexToRangeStart(TableGrouper* grouper,
                               int row_count,
                               std::map<int, int>* model_index_to_range_start) {
  for (int model_index = 0; model_index < row_count;) {
    GroupRange range;
    grouper->GetGroupRange(model_index, &range);
    DCHECK_GT(range.length, 0);
    for (int range_counter = 0; range_counter < range.length; range_counter++)
      (*model_index_to_range_start)[range_counter + model_index] = model_index;
    model_index += range.length;
  }
}

// Returns the color id for the background of selected text. |has_focus|
// indicates if the table has focus.
ui::NativeTheme::ColorId text_background_color_id(bool has_focus) {
  return has_focus ?
      ui::NativeTheme::kColorId_TableSelectionBackgroundFocused :
      ui::NativeTheme::kColorId_TableSelectionBackgroundUnfocused;
}

// Returns the color id for text. |has_focus| indicates if the table has focus.
ui::NativeTheme::ColorId selected_text_color_id(bool has_focus) {
  return has_focus ? ui::NativeTheme::kColorId_TableSelectedText :
      ui::NativeTheme::kColorId_TableSelectedTextUnfocused;
}

} // namespace

// Used as the comparator to sort the contents of the table.
struct TableView::SortHelper {
  explicit SortHelper(TableView* table) : table(table) {}

  bool operator()(int model_index1, int model_index2) {
    return table->CompareRows(model_index1, model_index2) < 0;
  }

  TableView* table;
};

// Used as the comparator to sort the contents of the table when a TableGrouper
// is present. When groups are present we sort the groups based on the first row
// in the group and within the groups we keep the same order as the model.
struct TableView::GroupSortHelper {
  explicit GroupSortHelper(TableView* table) : table(table) {}

  bool operator()(int model_index1, int model_index2) {
    const int range1 = model_index_to_range_start[model_index1];
    const int range2 = model_index_to_range_start[model_index2];
    if (range1 == range2) {
      // The two rows are in the same group, sort so that items in the same
      // group always appear in the same order.
      return model_index1 < model_index2;
    }
    return table->CompareRows(range1, range2) < 0;
  }

  TableView* table;
  std::map<int, int> model_index_to_range_start;
};

TableView::VisibleColumn::VisibleColumn() : x(0), width(0) {}

TableView::VisibleColumn::~VisibleColumn() {}

TableView::PaintRegion::PaintRegion()
    : min_row(0),
      max_row(0),
      min_column(0),
      max_column(0) {
}

TableView::PaintRegion::~PaintRegion() {}

TableView::TableView(ui::TableModel* model,
                     const std::vector<ui::TableColumn>& columns,
                     TableTypes table_type,
                     bool single_selection)
    : model_(NULL),
      columns_(columns),
      header_(NULL),
      table_type_(table_type),
      single_selection_(single_selection),
      table_view_observer_(NULL),
      row_height_(font_list_.GetHeight() + kTextVerticalPadding * 2),
      last_parent_width_(0),
      layout_width_(0),
      grouper_(NULL),
      in_set_visible_column_width_(false) {
  for (size_t i = 0; i < columns.size(); ++i) {
    VisibleColumn visible_column;
    visible_column.column = columns[i];
    visible_columns_.push_back(visible_column);
  }
  SetFocusable(true);
  SetModel(model);
}

TableView::~TableView() {
  if (model_)
    model_->SetObserver(NULL);
}

// TODO: this doesn't support arbitrarily changing the model, rename this to
// ClearModel() or something.
void TableView::SetModel(ui::TableModel* model) {
  if (model == model_)
    return;

  if (model_)
    model_->SetObserver(NULL);
  model_ = model;
  selection_model_.Clear();
  if (model_)
    model_->SetObserver(this);
}

View* TableView::CreateParentIfNecessary() {
  ScrollView* scroll_view = ScrollView::CreateScrollViewWithBorder();
  scroll_view->SetContents(this);
  CreateHeaderIfNecessary();
  if (header_)
    scroll_view->SetHeader(header_);
  return scroll_view;
}

void TableView::SetRowBackgroundPainter(
    scoped_ptr<TableViewRowBackgroundPainter> painter) {
  row_background_painter_ = painter.Pass();
}

void TableView::SetGrouper(TableGrouper* grouper) {
  grouper_ = grouper;
  SortItemsAndUpdateMapping();
}

int TableView::RowCount() const {
  return model_ ? model_->RowCount() : 0;
}

int TableView::SelectedRowCount() {
  return static_cast<int>(selection_model_.size());
}

void TableView::Select(int model_row) {
  if (!model_)
    return;

  SelectByViewIndex(model_row == -1 ? -1 : ModelToView(model_row));
}

int TableView::FirstSelectedRow() {
  return SelectedRowCount() == 0 ? -1 : selection_model_.selected_indices()[0];
}

void TableView::SetColumnVisibility(int id, bool is_visible) {
  if (is_visible == IsColumnVisible(id))
    return;

  if (is_visible) {
    VisibleColumn visible_column;
    visible_column.column = FindColumnByID(id);
    visible_columns_.push_back(visible_column);
  } else {
    for (size_t i = 0; i < visible_columns_.size(); ++i) {
      if (visible_columns_[i].column.id == id) {
        visible_columns_.erase(visible_columns_.begin() + i);
        break;
      }
    }
  }
  UpdateVisibleColumnSizes();
  PreferredSizeChanged();
  SchedulePaint();
  if (header_)
    header_->SchedulePaint();
}

void TableView::ToggleSortOrder(int visible_column_index) {
  DCHECK(visible_column_index >= 0 &&
         visible_column_index < static_cast<int>(visible_columns_.size()));
  if (!visible_columns_[visible_column_index].column.sortable)
    return;
  const int column_id = visible_columns_[visible_column_index].column.id;
  SortDescriptors sort(sort_descriptors_);
  if (!sort.empty() && sort[0].column_id == column_id) {
    sort[0].ascending = !sort[0].ascending;
  } else {
    SortDescriptor descriptor(column_id, true);
    sort.insert(sort.begin(), descriptor);
    // Only persist two sort descriptors.
    if (sort.size() > 2)
      sort.resize(2);
  }
  SetSortDescriptors(sort);
}

bool TableView::IsColumnVisible(int id) const {
  for (size_t i = 0; i < visible_columns_.size(); ++i) {
    if (visible_columns_[i].column.id == id)
      return true;
  }
  return false;
}

void TableView::AddColumn(const ui::TableColumn& col) {
  DCHECK(!HasColumn(col.id));
  columns_.push_back(col);
}

bool TableView::HasColumn(int id) const {
  for (size_t i = 0; i < columns_.size(); ++i) {
    if (columns_[i].id == id)
      return true;
  }
  return false;
}

void TableView::SetVisibleColumnWidth(int index, int width) {
  DCHECK(index >= 0 && index < static_cast<int>(visible_columns_.size()));
  if (visible_columns_[index].width == width)
    return;
  base::AutoReset<bool> reseter(&in_set_visible_column_width_, true);
  visible_columns_[index].width = width;
  for (size_t i = index + 1; i < visible_columns_.size(); ++i) {
    visible_columns_[i].x =
        visible_columns_[i - 1].x + visible_columns_[i - 1].width;
  }
  PreferredSizeChanged();
  SchedulePaint();
}

int TableView::ModelToView(int model_index) const {
  if (!is_sorted())
    return model_index;
  DCHECK_GE(model_index, 0) << " negative model_index " << model_index;
  DCHECK_LT(model_index, RowCount()) << " out of bounds model_index " <<
      model_index;
  return model_to_view_[model_index];
}

int TableView::ViewToModel(int view_index) const {
  if (!is_sorted())
    return view_index;
  DCHECK_GE(view_index, 0) << " negative view_index " << view_index;
  DCHECK_LT(view_index, RowCount()) << " out of bounds view_index " <<
      view_index;
  return view_to_model_[view_index];
}

void TableView::Layout() {
  // parent()->parent() is the scrollview. When its width changes we force
  // recalculating column sizes.
  View* scroll_view = parent() ? parent()->parent() : NULL;
  if (scroll_view) {
    const int scroll_view_width = scroll_view->GetContentsBounds().width();
    if (scroll_view_width != last_parent_width_) {
      last_parent_width_ = scroll_view_width;
      if (!in_set_visible_column_width_) {
        // Layout to the parent (the Viewport), which differs from
        // |scroll_view_width| when scrollbars are present.
        layout_width_ = parent()->width();
        UpdateVisibleColumnSizes();
      }
    }
  }
  // We have to override Layout like this since we're contained in a ScrollView.
  gfx::Size pref = GetPreferredSize();
  int width = pref.width();
  int height = pref.height();
  if (parent()) {
    width = std::max(parent()->width(), width);
    height = std::max(parent()->height(), height);
  }
  SetBounds(x(), y(), width, height);
}

gfx::Size TableView::GetPreferredSize() const {
  int width = 50;
  if (header_ && !visible_columns_.empty())
    width = visible_columns_.back().x + visible_columns_.back().width;
  return gfx::Size(width, RowCount() * row_height_);
}

bool TableView::OnKeyPressed(const ui::KeyEvent& event) {
  if (!HasFocus())
    return false;

  switch (event.key_code()) {
    case ui::VKEY_A:
      // control-a selects all.
      if (event.IsControlDown() && !single_selection_ && RowCount()) {
        ui::ListSelectionModel selection_model;
        selection_model.SetSelectedIndex(selection_model_.active());
        for (int i = 0; i < RowCount(); ++i)
          selection_model.AddIndexToSelection(i);
        SetSelectionModel(selection_model);
        return true;
      }
      break;

    case ui::VKEY_HOME:
      if (RowCount())
        SelectByViewIndex(0);
      return true;

    case ui::VKEY_END:
      if (RowCount())
        SelectByViewIndex(RowCount() - 1);
      return true;

    case ui::VKEY_UP:
      AdvanceSelection(ADVANCE_DECREMENT);
      return true;

    case ui::VKEY_DOWN:
      AdvanceSelection(ADVANCE_INCREMENT);
      return true;

    default:
      break;
  }
  if (table_view_observer_)
    table_view_observer_->OnKeyDown(event.key_code());
  return false;
}

bool TableView::OnMousePressed(const ui::MouseEvent& event) {
  RequestFocus();
  if (!event.IsOnlyLeftMouseButton())
    return true;

  const int row = event.y() / row_height_;
  if (row < 0 || row >= RowCount())
    return true;

  if (event.GetClickCount() == 2) {
    SelectByViewIndex(row);
    if (table_view_observer_)
      table_view_observer_->OnDoubleClick();
  } else if (event.GetClickCount() == 1) {
    ui::ListSelectionModel new_model;
    ConfigureSelectionModelForEvent(event, &new_model);
    SetSelectionModel(new_model);
  }

  return true;
}

void TableView::OnGestureEvent(ui::GestureEvent* event) {
  if (event->type() != ui::ET_GESTURE_TAP)
    return;

  const int row = event->y() / row_height_;
  if (row < 0 || row >= RowCount())
    return;

  event->StopPropagation();
  ui::ListSelectionModel new_model;
  ConfigureSelectionModelForEvent(*event, &new_model);
  SetSelectionModel(new_model);
}

bool TableView::GetTooltipText(const gfx::Point& p,
                               base::string16* tooltip) const {
  return GetTooltipImpl(p, tooltip, NULL);
}

bool TableView::GetTooltipTextOrigin(const gfx::Point& p,
                                     gfx::Point* loc) const {
  return GetTooltipImpl(p, NULL, loc);
}

void TableView::OnModelChanged() {
  selection_model_.Clear();
  NumRowsChanged();
}

void TableView::OnItemsChanged(int start, int length) {
  SortItemsAndUpdateMapping();
}

void TableView::OnItemsAdded(int start, int length) {
  for (int i = 0; i < length; ++i)
    selection_model_.IncrementFrom(start);
  NumRowsChanged();
}

void TableView::OnItemsRemoved(int start, int length) {
  // Determine the currently selected index in terms of the view. We inline the
  // implementation here since ViewToModel() has DCHECKs that fail since the
  // model has changed but |model_to_view_| has not been updated yet.
  const int previously_selected_model_index = FirstSelectedRow();
  int previously_selected_view_index = previously_selected_model_index;
  if (previously_selected_model_index != -1 && is_sorted())
    previously_selected_view_index =
        model_to_view_[previously_selected_model_index];
  for (int i = 0; i < length; ++i)
    selection_model_.DecrementFrom(start);
  NumRowsChanged();
  // If the selection was empty and is no longer empty select the same visual
  // index.
  if (selection_model_.empty() && previously_selected_view_index != -1 &&
      RowCount()) {
    selection_model_.SetSelectedIndex(
        ViewToModel(std::min(RowCount() - 1, previously_selected_view_index)));
  }
  if (table_view_observer_)
    table_view_observer_->OnSelectionChanged();
}

gfx::Point TableView::GetKeyboardContextMenuLocation() {
  int first_selected = FirstSelectedRow();
  gfx::Rect vis_bounds(GetVisibleBounds());
  int y = vis_bounds.height() / 2;
  if (first_selected != -1) {
    gfx::Rect cell_bounds(GetRowBounds(first_selected));
    if (cell_bounds.bottom() >= vis_bounds.y() &&
        cell_bounds.bottom() < vis_bounds.bottom()) {
      y = cell_bounds.bottom();
    }
  }
  gfx::Point screen_loc(0, y);
  if (base::i18n::IsRTL())
    screen_loc.set_x(width());
  ConvertPointToScreen(this, &screen_loc);
  return screen_loc;
}

void TableView::OnPaint(gfx::Canvas* canvas) {
  // Don't invoke View::OnPaint so that we can render our own focus border.

  canvas->DrawColor(GetNativeTheme()->GetSystemColor(
                        ui::NativeTheme::kColorId_TableBackground));

  if (!RowCount() || visible_columns_.empty())
    return;

  const PaintRegion region(GetPaintRegion(GetPaintBounds(canvas)));
  if (region.min_column == -1)
    return;  // No need to paint anything.

  const SkColor selected_bg_color = GetNativeTheme()->GetSystemColor(
      text_background_color_id(HasFocus()));
  const SkColor fg_color = GetNativeTheme()->GetSystemColor(
      ui::NativeTheme::kColorId_TableText);
  const SkColor selected_fg_color = GetNativeTheme()->GetSystemColor(
      selected_text_color_id(HasFocus()));
  for (int i = region.min_row; i < region.max_row; ++i) {
    const int model_index = ViewToModel(i);
    const bool is_selected = selection_model_.IsSelected(model_index);
    if (is_selected) {
      canvas->FillRect(GetRowBounds(i), selected_bg_color);
    } else if (row_background_painter_) {
      row_background_painter_->PaintRowBackground(model_index,
                                                  GetRowBounds(i),
                                                  canvas);
    }
    if (selection_model_.active() == i && HasFocus())
      canvas->DrawFocusRect(GetRowBounds(i));
    for (int j = region.min_column; j < region.max_column; ++j) {
      const gfx::Rect cell_bounds(GetCellBounds(i, j));
      int text_x = kTextHorizontalPadding + cell_bounds.x();

      // Provide space for the grouping indicator, but draw it separately.
      if (j == 0 && grouper_)
        text_x += kGroupingIndicatorSize + kTextHorizontalPadding;

      // Always paint the icon in the first visible column.
      if (j == 0 && table_type_ == ICON_AND_TEXT) {
        gfx::ImageSkia image = model_->GetIcon(model_index);
        if (!image.isNull()) {
          int image_x = GetMirroredXWithWidthInView(text_x, kImageSize);
          canvas->DrawImageInt(
              image, 0, 0, image.width(), image.height(),
              image_x,
              cell_bounds.y() + (cell_bounds.height() - kImageSize) / 2,
              kImageSize, kImageSize, true);
        }
        text_x += kImageSize + kTextHorizontalPadding;
      }
      if (text_x < cell_bounds.right() - kTextHorizontalPadding) {
        canvas->DrawStringRectWithFlags(
            model_->GetText(model_index, visible_columns_[j].column.id),
            font_list_, is_selected ? selected_fg_color : fg_color,
            gfx::Rect(GetMirroredXWithWidthInView(
                text_x, cell_bounds.right() - text_x - kTextHorizontalPadding),
                      cell_bounds.y() + kTextVerticalPadding,
                      cell_bounds.right() - text_x,
                      cell_bounds.height() - kTextVerticalPadding * 2),
            TableColumnAlignmentToCanvasAlignment(
                visible_columns_[j].column.alignment));
      }
    }
  }

  if (!grouper_ || region.min_column > 0)
    return;

  const SkColor grouping_color = GetNativeTheme()->GetSystemColor(
      ui::NativeTheme::kColorId_TableGroupingIndicatorColor);
  SkPaint grouping_paint;
  grouping_paint.setColor(grouping_color);
  grouping_paint.setStyle(SkPaint::kFill_Style);
  grouping_paint.setAntiAlias(true);
  const int group_indicator_x = GetMirroredXInView(GetCellBounds(0, 0).x() +
      kTextHorizontalPadding + kGroupingIndicatorSize / 2);
  for (int i = region.min_row; i < region.max_row; ) {
    const int model_index = ViewToModel(i);
    GroupRange range;
    grouper_->GetGroupRange(model_index, &range);
    DCHECK_GT(range.length, 0);
    // The order of rows in a group is consistent regardless of sort, so it's ok
    // to do this calculation.
    const int start = i - (model_index - range.start);
    const int last = start + range.length - 1;
    const gfx::Rect start_cell_bounds(GetCellBounds(start, 0));
    if (start != last) {
      const gfx::Rect last_cell_bounds(GetCellBounds(last, 0));
      canvas->FillRect(gfx::Rect(
                           group_indicator_x - kGroupingIndicatorSize / 2,
                           start_cell_bounds.CenterPoint().y(),
                           kGroupingIndicatorSize,
                           last_cell_bounds.y() - start_cell_bounds.y()),
                       grouping_color);
      canvas->DrawCircle(gfx::Point(group_indicator_x,
                                    last_cell_bounds.CenterPoint().y()),
                         kGroupingIndicatorSize / 2, grouping_paint);
    }
    canvas->DrawCircle(gfx::Point(group_indicator_x,
                                  start_cell_bounds.CenterPoint().y()),
                       kGroupingIndicatorSize / 2, grouping_paint);
    i = last + 1;
  }
}

void TableView::OnFocus() {
  SchedulePaintForSelection();
}

void TableView::OnBlur() {
  SchedulePaintForSelection();
}

void TableView::NumRowsChanged() {
  SortItemsAndUpdateMapping();
  PreferredSizeChanged();
  SchedulePaint();
}

void TableView::SetSortDescriptors(const SortDescriptors& sort_descriptors) {
  sort_descriptors_ = sort_descriptors;
  SortItemsAndUpdateMapping();
  if (header_)
    header_->SchedulePaint();
}

void TableView::SortItemsAndUpdateMapping() {
  if (!is_sorted()) {
    view_to_model_.clear();
    model_to_view_.clear();
  } else {
    const int row_count = RowCount();
    view_to_model_.resize(row_count);
    model_to_view_.resize(row_count);
    for (int i = 0; i < row_count; ++i)
      view_to_model_[i] = i;
    if (grouper_) {
      GroupSortHelper sort_helper(this);
      GetModelIndexToRangeStart(grouper_, RowCount(),
                                &sort_helper.model_index_to_range_start);
      std::sort(view_to_model_.begin(), view_to_model_.end(), sort_helper);
    } else {
      std::sort(view_to_model_.begin(), view_to_model_.end(), SortHelper(this));
    }
    for (int i = 0; i < row_count; ++i)
      model_to_view_[view_to_model_[i]] = i;
    model_->ClearCollator();
  }
  SchedulePaint();
}

int TableView::CompareRows(int model_row1, int model_row2) {
  const int sort_result = model_->CompareValues(
      model_row1, model_row2, sort_descriptors_[0].column_id);
  if (sort_result == 0 && sort_descriptors_.size() > 1) {
    // Try the secondary sort.
    return SwapCompareResult(
        model_->CompareValues(model_row1, model_row2,
                              sort_descriptors_[1].column_id),
        sort_descriptors_[1].ascending);
  }
  return SwapCompareResult(sort_result, sort_descriptors_[0].ascending);
}

gfx::Rect TableView::GetRowBounds(int row) const {
  return gfx::Rect(0, row * row_height_, width(), row_height_);
}

gfx::Rect TableView::GetCellBounds(int row, int visible_column_index) const {
  if (!header_)
    return GetRowBounds(row);
  const VisibleColumn& vis_col(visible_columns_[visible_column_index]);
  return gfx::Rect(vis_col.x, row * row_height_, vis_col.width, row_height_);
}

void TableView::AdjustCellBoundsForText(int visible_column_index,
                                        gfx::Rect* bounds) const {
  int text_x = kTextHorizontalPadding + bounds->x();
  if (visible_column_index == 0) {
    if (grouper_)
      text_x += kGroupingIndicatorSize + kTextHorizontalPadding;
    if (table_type_ == ICON_AND_TEXT)
      text_x += kImageSize + kTextHorizontalPadding;
  }
  bounds->set_x(text_x);
  bounds->set_width(
      std::max(0, bounds->right() - kTextHorizontalPadding - text_x));
}

void TableView::CreateHeaderIfNecessary() {
  // Only create a header if there is more than one column or the title of the
  // only column is not empty.
  if (header_ || (columns_.size() == 1 && columns_[0].title.empty()))
    return;

  header_ = new TableHeader(this);
}

void TableView::UpdateVisibleColumnSizes() {
  if (!header_)
    return;

  std::vector<ui::TableColumn> columns;
  for (size_t i = 0; i < visible_columns_.size(); ++i)
    columns.push_back(visible_columns_[i].column);

  int first_column_padding = 0;
  if (table_type_ == ICON_AND_TEXT && header_)
    first_column_padding += kImageSize + kTextHorizontalPadding;
  if (grouper_)
    first_column_padding += kGroupingIndicatorSize + kTextHorizontalPadding;

  std::vector<int> sizes = views::CalculateTableColumnSizes(
      layout_width_, first_column_padding, header_->font_list(), font_list_,
      std::max(kTextHorizontalPadding, TableHeader::kHorizontalPadding) * 2,
      TableHeader::kSortIndicatorWidth, columns, model_);
  DCHECK_EQ(visible_columns_.size(), sizes.size());
  int x = 0;
  for (size_t i = 0; i < visible_columns_.size(); ++i) {
    visible_columns_[i].x = x;
    visible_columns_[i].width = sizes[i];
    x += sizes[i];
  }
}

TableView::PaintRegion TableView::GetPaintRegion(
    const gfx::Rect& bounds) const {
  DCHECK(!visible_columns_.empty());
  DCHECK(RowCount());

  PaintRegion region;
  region.min_row = std::min(RowCount() - 1,
                            std::max(0, bounds.y() / row_height_));
  region.max_row = bounds.bottom() / row_height_;
  if (bounds.bottom() % row_height_ != 0)
    region.max_row++;
  region.max_row = std::min(region.max_row, RowCount());

  if (!header_) {
    region.max_column = 1;
    return region;
  }

  const int paint_x = GetMirroredXForRect(bounds);
  const int paint_max_x = paint_x + bounds.width();
  region.min_column = -1;
  region.max_column = visible_columns_.size();
  for (size_t i = 0; i < visible_columns_.size(); ++i) {
    int max_x = visible_columns_[i].x + visible_columns_[i].width;
    if (region.min_column == -1 && max_x >= paint_x)
      region.min_column = static_cast<int>(i);
    if (region.min_column != -1 && visible_columns_[i].x >= paint_max_x) {
      region.max_column = i;
      break;
    }
  }
  return region;
}

gfx::Rect TableView::GetPaintBounds(gfx::Canvas* canvas) const {
  SkRect sk_clip_rect;
  if (canvas->sk_canvas()->getClipBounds(&sk_clip_rect))
    return gfx::ToEnclosingRect(gfx::SkRectToRectF(sk_clip_rect));
  return GetVisibleBounds();
}

void TableView::SchedulePaintForSelection() {
  if (selection_model_.size() == 1) {
    const int first_model_row = FirstSelectedRow();
    SchedulePaintInRect(GetRowBounds(ModelToView(first_model_row)));
    if (first_model_row != selection_model_.active())
      SchedulePaintInRect(GetRowBounds(ModelToView(selection_model_.active())));
  } else if (selection_model_.size() > 1) {
    SchedulePaint();
  }
}

ui::TableColumn TableView::FindColumnByID(int id) const {
  for (size_t i = 0; i < columns_.size(); ++i) {
    if (columns_[i].id == id)
      return columns_[i];
  }
  NOTREACHED();
  return ui::TableColumn();
}

void TableView::SelectByViewIndex(int view_index) {
  ui::ListSelectionModel new_selection;
  if (view_index != -1) {
    SelectRowsInRangeFrom(view_index, true, &new_selection);
    new_selection.set_anchor(ViewToModel(view_index));
    new_selection.set_active(ViewToModel(view_index));
  }

  SetSelectionModel(new_selection);
}

void TableView::SetSelectionModel(const ui::ListSelectionModel& new_selection) {
  if (new_selection.Equals(selection_model_))
    return;

  SchedulePaintForSelection();
  selection_model_.Copy(new_selection);
  SchedulePaintForSelection();

  // Scroll the group for the active item to visible.
  if (selection_model_.active() != -1) {
    gfx::Rect vis_rect(GetVisibleBounds());
    const GroupRange range(GetGroupRange(selection_model_.active()));
    const int start_y = GetRowBounds(ModelToView(range.start)).y();
    const int end_y =
        GetRowBounds(ModelToView(range.start + range.length - 1)).bottom();
    vis_rect.set_y(start_y);
    vis_rect.set_height(end_y - start_y);
    ScrollRectToVisible(vis_rect);
  }

  if (table_view_observer_)
    table_view_observer_->OnSelectionChanged();
}

void TableView::AdvanceSelection(AdvanceDirection direction) {
  if (selection_model_.active() == -1) {
    SelectByViewIndex(0);
    return;
  }
  int view_index = ModelToView(selection_model_.active());
  if (direction == ADVANCE_DECREMENT)
    view_index = std::max(0, view_index - 1);
  else
    view_index = std::min(RowCount() - 1, view_index + 1);
  SelectByViewIndex(view_index);
}

void TableView::ConfigureSelectionModelForEvent(
    const ui::LocatedEvent& event,
    ui::ListSelectionModel* model) const {
  const int view_index = event.y() / row_height_;
  DCHECK(view_index >= 0 && view_index < RowCount());

  if (selection_model_.anchor() == -1 ||
      single_selection_ ||
      (!event.IsControlDown() && !event.IsShiftDown())) {
    SelectRowsInRangeFrom(view_index, true, model);
    model->set_anchor(ViewToModel(view_index));
    model->set_active(ViewToModel(view_index));
    return;
  }
  if ((event.IsControlDown() && event.IsShiftDown()) || event.IsShiftDown()) {
    // control-shift: copy existing model and make sure rows between anchor and
    // |view_index| are selected.
    // shift: reset selection so that only rows between anchor and |view_index|
    // are selected.
    if (event.IsControlDown() && event.IsShiftDown())
      model->Copy(selection_model_);
    else
      model->set_anchor(selection_model_.anchor());
    for (int i = std::min(view_index, ModelToView(model->anchor())),
             end = std::max(view_index, ModelToView(model->anchor()));
         i <= end; ++i) {
      SelectRowsInRangeFrom(i, true, model);
    }
    model->set_active(ViewToModel(view_index));
  } else {
    DCHECK(event.IsControlDown());
    // Toggle the selection state of |view_index| and set the anchor/active to
    // it and don't change the state of any other rows.
    model->Copy(selection_model_);
    model->set_anchor(ViewToModel(view_index));
    model->set_active(ViewToModel(view_index));
    SelectRowsInRangeFrom(view_index,
                          !model->IsSelected(ViewToModel(view_index)),
                          model);
  }
}

void TableView::SelectRowsInRangeFrom(int view_index,
                                      bool select,
                                      ui::ListSelectionModel* model) const {
  const GroupRange range(GetGroupRange(ViewToModel(view_index)));
  for (int i = 0; i < range.length; ++i) {
    if (select)
      model->AddIndexToSelection(range.start + i);
    else
      model->RemoveIndexFromSelection(range.start + i);
  }
}

GroupRange TableView::GetGroupRange(int model_index) const {
  GroupRange range;
  if (grouper_) {
    grouper_->GetGroupRange(model_index, &range);
  } else {
    range.start = model_index;
    range.length = 1;
  }
  return range;
}

bool TableView::GetTooltipImpl(const gfx::Point& location,
                               base::string16* tooltip,
                               gfx::Point* tooltip_origin) const {
  const int row = location.y() / row_height_;
  if (row < 0 || row >= RowCount() || visible_columns_.empty())
    return false;

  const int x = GetMirroredXInView(location.x());
  const int column = GetClosestVisibleColumnIndex(this, x);
  if (x < visible_columns_[column].x ||
      x > (visible_columns_[column].x + visible_columns_[column].width))
    return false;

  const base::string16 text(model_->GetText(ViewToModel(row),
                                      visible_columns_[column].column.id));
  if (text.empty())
    return false;

  gfx::Rect cell_bounds(GetCellBounds(row, column));
  AdjustCellBoundsForText(column, &cell_bounds);
  const int right = std::min(GetVisibleBounds().right(), cell_bounds.right());
  if (right > cell_bounds.x() &&
      gfx::GetStringWidth(text, font_list_) <= (right - cell_bounds.x()))
    return false;

  if (tooltip)
    *tooltip = text;
  if (tooltip_origin) {
    tooltip_origin->SetPoint(cell_bounds.x(),
                             cell_bounds.y() + kTextVerticalPadding);
  }
  return true;
}

}  // namespace views
