// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "renderer/table_layout.h"

#include <algorithm>
#include <numeric>

#include "base/logging.h"

namespace mozc {
namespace renderer {
namespace {
// The minimum height of the indicator in the VScrollBar.
const int kMinimumIndicatorHeight = 1;
}  // anonymous namespace

// ------------------------------------------------------------------------
// Initializations
// ------------------------------------------------------------------------

TableLayout::TableLayout()
    : minimum_footer_size_(0, 0),
      minimum_header_size_(0, 0),
      ensure_width_from_column_(0),
      ensure_width_to_column_(0),
      ensure_width_(0),
      number_of_rows_(1),
      number_of_columns_(1),
      window_border_pixels_(1),
      row_rect_padding_pixels_(0),
      row_height_(1),
      vscroll_width_pixels_(0),
      layout_frozen_(false) { }

void TableLayout::Initialize(int num_rows,
                             int num_columns) {
  number_of_rows_ = num_rows;
  number_of_columns_ = num_columns;

  layout_frozen_ = false;
  window_border_pixels_ = 0;
  minimum_footer_size_ = Size(0, 0);
  minimum_header_size_ = Size(0, 0);
  row_rect_padding_pixels_ = 0;
  row_height_ = 0;
  vscroll_width_pixels_ = 0;

  column_width_list_.clear();
  column_width_list_.resize(num_columns);

  total_size_ = Size();
}

// ------------------------------------------------------------------------
// Add layout element
// ------------------------------------------------------------------------

void TableLayout::SetVScrollBar(int width_in_pixels) {
  if (layout_frozen_) {
    LOG(ERROR) << "Layout already frozen";
    return;
  }

  vscroll_width_pixels_ = width_in_pixels;
}

void TableLayout::SetWindowBorder(int width_in_pixels) {
  if (layout_frozen_) {
    LOG(ERROR) << "Layout already frozen";
    return;
  }

  window_border_pixels_ = width_in_pixels;
}

void TableLayout::SetRowRectPadding(int width_pixels) {
  if (layout_frozen_) {
    LOG(ERROR) << "Layout already frozen";
    return;
  }

  row_rect_padding_pixels_ = width_pixels;
}

void TableLayout::EnsureCellSize(int column, const Size &size) {
  if (layout_frozen_) {
    LOG(ERROR) << "Layout already frozen";
    return;
  }
  DCHECK(0 <= column && column < column_width_list_.size());

  column_width_list_[column] = max(column_width_list_[column], size.width);
  row_height_ = max(row_height_, size.height + row_rect_padding_pixels_ * 2);
}

void TableLayout::EnsureColumnsWidth(int from_column, int to_column,
                                     int width) {
  ensure_width_from_column_ = from_column;
  ensure_width_to_column_ = to_column;
  ensure_width_ = width;
}

void TableLayout::EnsureFooterSize(const Size &size_in_pixels) {
  if (layout_frozen_) {
    LOG(ERROR) << "Layout already frozen";
    return;
  }
  minimum_footer_size_.height
      = max(minimum_footer_size_.height, size_in_pixels.height);
  minimum_footer_size_.width
      = max(minimum_footer_size_.width, size_in_pixels.width);
}

void TableLayout::EnsureHeaderSize(const Size &size_in_pixels) {
  if (layout_frozen_) {
    LOG(ERROR) << "Layout already frozen";
    return;
  }
  minimum_header_size_.height
      = max(minimum_header_size_.height, size_in_pixels.height);
  minimum_header_size_.width
      = max(minimum_header_size_.width, size_in_pixels.width);
}

// ------------------------------------------------------------------------
// Layout status
// ------------------------------------------------------------------------
void TableLayout::FreezeLayout() {
  if (layout_frozen_) {
    LOG(ERROR) << "Layout already frozen";
    return;
  }

  // extends necessary column for EnsureColumnsWidth()
  if (ensure_width_from_column_ >= 0 &&
      ensure_width_from_column_ < number_of_columns_ &&
      ensure_width_to_column_ > ensure_width_from_column_ &&
      ensure_width_to_column_ < number_of_columns_ &&
      ensure_width_ > 0) {
    int ensured_range_width = 0;
    for (int i = ensure_width_from_column_; i <= ensure_width_to_column_; ++i) {
      ensured_range_width += column_width_list_[i];
    }
    if (ensured_range_width < ensure_width_) {
      column_width_list_[ensure_width_to_column_] +=
          (ensure_width_ - ensured_range_width);
    }
  }

  const int all_cell_width = accumulate(column_width_list_.begin(),
                                        column_width_list_.end(), 0);

  const int table_width =
      row_rect_padding_pixels_ * 2 +  // padding left and right
      all_cell_width +                // sum of all cell
      vscroll_width_pixels_;          // scrollbar width

  // contetnt width is determined as the maximum of
  // { table width, header width, footer width }
  const int content_width =
      max(table_width,
          max(minimum_footer_size_.width, minimum_header_size_.width));

  const int width = content_width +             // total content width
                    window_border_pixels_ * 2;  // border left and right

  const int all_cell_height = row_height_ * number_of_rows_;

  const int height = window_border_pixels_ * 2 +    // border top and bottom
                     minimum_header_size_.height +  // header height
                     all_cell_height +              // sum of all cell
                     minimum_footer_size_.height;   // footer height

  total_size_ = Size(width, height);
  layout_frozen_ = true;
}

bool TableLayout::IsLayoutFrozen() const {
  return layout_frozen_;
}

// ------------------------------------------------------------------------
// Get component rects
// ------------------------------------------------------------------------

Rect TableLayout::GetCellRect(int row, int column) const {
  if (!layout_frozen_) {
    LOG(ERROR) << "Layout is not frozen yet";
    return Rect();
  }
  DCHECK(0 <= row && row < number_of_rows_);
  DCHECK(0 <= column && column < column_width_list_.size());

  const int width_of_left_cells =
      accumulate(column_width_list_.begin(),
                 column_width_list_.begin() + column, 0);

  const int left = window_border_pixels_ +     // border left
                   row_rect_padding_pixels_ +  // row padding left
                   width_of_left_cells;        // left cells

  const int height_of_upper_cells = row_height_ * row;

  const int top = window_border_pixels_ +        // border top
                  minimum_header_size_.height +  // header height
                  height_of_upper_cells;         // upper cells

  const int width = column_width_list_[column];

  Rect rect(left, top, width, row_height_);

  // deflate top and bottom since row_height_ includes the padding
  rect.DeflateRect(0, row_rect_padding_pixels_, 0, row_rect_padding_pixels_);

  return rect;
}

Size TableLayout::GetTotalSize() const {
  if (!layout_frozen_) {
    LOG(ERROR) << "Layout is not frozen yet";
    return Size();
  }

  return total_size_;
}

Rect TableLayout::GetHeaderRect() const {
  if (!layout_frozen_) {
    LOG(ERROR) << "Layout is not frozen yet";
    return Rect();
  }

  const int width = total_size_.width -         // total width
                    window_border_pixels_ * 2;  // border left and rigth

  return Rect(window_border_pixels_, window_border_pixels_,
              width, minimum_header_size_.height);
}

Rect TableLayout::GetFooterRect() const {
  if (!layout_frozen_) {
    LOG(ERROR) << "Layout is not frozen yet";
    return Rect();
  }

  const int top = total_size_.height -           // total width
                  minimum_footer_size_.height -  // footer height
                  window_border_pixels_;         // border bottom

  const int width = total_size_.width -         // total width
                    window_border_pixels_ * 2;  // border left and right

  return Rect(window_border_pixels_, top, width, minimum_footer_size_.height);
}

Rect TableLayout::GetVScrollBarRect() const {
  if (!layout_frozen_) {
    LOG(ERROR) << "Layout is not frozen yet";
    return Rect();
  }

  const int left = total_size_.width -      // total width
                   window_border_pixels_ -  // border right
                   vscroll_width_pixels_;   // vscroll width

  const int top = window_border_pixels_ +       // border top
                  minimum_header_size_.height;  // header height

  const int height = total_size_.height -           // total height
                     window_border_pixels_ * 2 -    // border top and bottom
                     minimum_header_size_.height -  // header height
                     minimum_footer_size_.height;   // footer height

  return Rect(left, top, vscroll_width_pixels_, height);
}

Rect TableLayout::GetVScrollIndicatorRect(
    int begin_index, int end_index, int candidates_total) const {
  const Rect &vscroll_rect = GetVScrollBarRect();

  const float scroll_bar_height =
      static_cast<float>(vscroll_rect.Height()) / candidates_total;
  const float top = vscroll_rect.Top() + scroll_bar_height * begin_index;
  const float bottom =
      vscroll_rect.Top() + scroll_bar_height * (end_index + 1);

  // add 0.5f to round up
  int rounded_top = static_cast<int>(top + 0.5f);
  int rounded_height = static_cast<int>(bottom - top + 0.5f);

  if (rounded_height < kMinimumIndicatorHeight) {
    rounded_height = kMinimumIndicatorHeight;
  }
  if (rounded_top + rounded_height > vscroll_rect.Bottom()) {
    rounded_top = vscroll_rect.Bottom() - rounded_height;
  }

  return Rect(Point(vscroll_rect.Left(), rounded_top),
              Size(vscroll_rect.Width(), rounded_height));
}

Rect TableLayout::GetRowRect(int row) const {
  if (!layout_frozen_) {
    LOG(ERROR) << "Layout is not frozen yet";
    return Rect();
  }
  DCHECK(0 <= row && row < number_of_rows_);

  const int top = window_border_pixels_ +        // border top
                  minimum_header_size_.height +  // header height
                  row_height_ * row;             // upper cells

  const int width = total_size_.width -          // total width
                    window_border_pixels_ * 2 -  // border left and right
                    vscroll_width_pixels_;       // vscroll width

  return Rect(window_border_pixels_, top, width, row_height_);
}

Rect TableLayout::GetColumnRect(int column) const {
  if (!layout_frozen_) {
    LOG(ERROR) << "Layout is not frozen yet";
    return Rect();
  }
  DCHECK(0 <= column && column < column_width_list_.size());

  const int width_of_left_cells =
    accumulate(column_width_list_.begin(),
               column_width_list_.begin() + column, 0);

  const int left = window_border_pixels_ +     // border left
                   row_rect_padding_pixels_ +  // padding left
                   width_of_left_cells;        // left cells

  const int top = window_border_pixels_ +       // border top
                  minimum_header_size_.height;  // header height

  const int width = column_width_list_[column];

  const int height = row_height_ * number_of_rows_;

  return Rect(left, top, width, height);
}

// ------------------------------------------------------------------------
// Parameter getters
// ------------------------------------------------------------------------
int TableLayout::number_of_rows() const {
  return number_of_rows_;
}

int TableLayout::number_of_columns() const {
  return number_of_columns_;
}

}  // namespace renderer
}  // namespace mozc
