// Copyright 2010 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 "cc/base/tiling_data.h"

#include <algorithm>

#include "base/numerics/ranges.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/vector2d.h"

namespace cc {

namespace {
// IndexRect which is at left top corner of the positive quadrant.
const IndexRect kNonPositiveQuadrantIndexRect(-1, -1, -1, -1);
}

static int ComputeNumTiles(int max_texture_size,
                           int total_size,
                           int border_texels) {
  if (max_texture_size - 2 * border_texels <= 0)
    return total_size > 0 && max_texture_size >= total_size ? 1 : 0;

  int num_tiles = std::max(1,
                           1 + (total_size - 1 - 2 * border_texels) /
                           (max_texture_size - 2 * border_texels));
  return total_size > 0 ? num_tiles : 0;
}

TilingData::TilingData()
    : border_texels_(0) {
  RecomputeNumTiles();
}

TilingData::TilingData(const gfx::Size& max_texture_size,
                       const gfx::Size& tiling_size,
                       bool has_border_texels)
    : max_texture_size_(max_texture_size),
      tiling_size_(tiling_size),
      border_texels_(has_border_texels ? 1 : 0) {
  RecomputeNumTiles();
}

TilingData::TilingData(const gfx::Size& max_texture_size,
                       const gfx::Size& tiling_size,
                       int border_texels)
    : max_texture_size_(max_texture_size),
      tiling_size_(tiling_size),
      border_texels_(border_texels) {
  RecomputeNumTiles();
}

void TilingData::SetTilingSize(const gfx::Size& tiling_size) {
  tiling_size_ = tiling_size;
  RecomputeNumTiles();
}

void TilingData::SetMaxTextureSize(const gfx::Size& max_texture_size) {
  max_texture_size_ = max_texture_size;
  RecomputeNumTiles();
}

void TilingData::SetHasBorderTexels(bool has_border_texels) {
  border_texels_ = has_border_texels ? 1 : 0;
  RecomputeNumTiles();
}

void TilingData::SetBorderTexels(int border_texels) {
  border_texels_ = border_texels;
  RecomputeNumTiles();
}

int TilingData::TileXIndexFromSrcCoord(int src_position) const {
  if (num_tiles_x_ <= 1)
    return 0;

  DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0);
  int x = (src_position - border_texels_) /
      (max_texture_size_.width() - 2 * border_texels_);
  return base::ClampToRange(x, 0, num_tiles_x_ - 1);
}

int TilingData::TileYIndexFromSrcCoord(int src_position) const {
  if (num_tiles_y_ <= 1)
    return 0;

  DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0);
  int y = (src_position - border_texels_) /
      (max_texture_size_.height() - 2 * border_texels_);
  return base::ClampToRange(y, 0, num_tiles_y_ - 1);
}

int TilingData::FirstBorderTileXIndexFromSrcCoord(int src_position) const {
  if (num_tiles_x_ <= 1)
    return 0;

  DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0);
  int inner_tile_size = max_texture_size_.width() - 2 * border_texels_;
  int x = (src_position - 2 * border_texels_) / inner_tile_size;
  return base::ClampToRange(x, 0, num_tiles_x_ - 1);
}

int TilingData::FirstBorderTileYIndexFromSrcCoord(int src_position) const {
  if (num_tiles_y_ <= 1)
    return 0;

  DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0);
  int inner_tile_size = max_texture_size_.height() - 2 * border_texels_;
  int y = (src_position - 2 * border_texels_) / inner_tile_size;
  return base::ClampToRange(y, 0, num_tiles_y_ - 1);
}

int TilingData::LastBorderTileXIndexFromSrcCoord(int src_position) const {
  if (num_tiles_x_ <= 1)
    return 0;

  DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0);
  int inner_tile_size = max_texture_size_.width() - 2 * border_texels_;
  int x = src_position / inner_tile_size;
  return base::ClampToRange(x, 0, num_tiles_x_ - 1);
}

int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const {
  if (num_tiles_y_ <= 1)
    return 0;

  DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0);
  int inner_tile_size = max_texture_size_.height() - 2 * border_texels_;
  int y = src_position / inner_tile_size;
  return base::ClampToRange(y, 0, num_tiles_y_ - 1);
}

IndexRect TilingData::TileAroundIndexRect(const gfx::Rect& center_rect) const {
  int around_left = 0;
  // Determine around left, such that it is between -1 and num_tiles_x.
  if (center_rect.x() < 0 || center_rect.IsEmpty())
    around_left = -1;
  else if (center_rect.x() >= tiling_size().width())
    around_left = num_tiles_x();
  else
    around_left = TileXIndexFromSrcCoord(center_rect.x());

  // Determine around top, such that it is between -1 and num_tiles_y.
  int around_top = 0;
  if (center_rect.y() < 0 || center_rect.IsEmpty())
    around_top = -1;
  else if (center_rect.y() >= tiling_size().height())
    around_top = num_tiles_y();
  else
    around_top = TileYIndexFromSrcCoord(center_rect.y());

  // Determine around right, such that it is between -1 and num_tiles_x.
  int around_right = 0;
  int right_src_coord = center_rect.right() - 1;
  if (right_src_coord < 0 || center_rect.IsEmpty()) {
    around_right = -1;
  } else if (right_src_coord >= tiling_size().width()) {
    around_right = num_tiles_x();
  } else {
    around_right = TileXIndexFromSrcCoord(right_src_coord);
  }

  // Determine around bottom, such that it is between -1 and num_tiles_y.
  int around_bottom = 0;
  int bottom_src_coord = center_rect.bottom() - 1;
  if (bottom_src_coord < 0 || center_rect.IsEmpty()) {
    around_bottom = -1;
  } else if (bottom_src_coord >= tiling_size().height()) {
    around_bottom = num_tiles_y();
  } else {
    around_bottom = TileYIndexFromSrcCoord(bottom_src_coord);
  }

  return IndexRect(around_left, around_right, around_top, around_bottom);
}

gfx::Rect TilingData::ExpandRectIgnoringBordersToTileBounds(
    const gfx::Rect& rect) const {
  if (rect.IsEmpty() || has_empty_bounds())
    return gfx::Rect();
  if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height())
    return gfx::Rect();
  int index_x = TileXIndexFromSrcCoord(rect.x());
  int index_y = TileYIndexFromSrcCoord(rect.y());
  int index_right = TileXIndexFromSrcCoord(rect.right() - 1);
  int index_bottom = TileYIndexFromSrcCoord(rect.bottom() - 1);

  gfx::Rect rect_top_left(TileBounds(index_x, index_y));
  gfx::Rect rect_bottom_right(TileBounds(index_right, index_bottom));

  return gfx::UnionRects(rect_top_left, rect_bottom_right);
}

gfx::Rect TilingData::ExpandRectToTileBounds(const gfx::Rect& rect) const {
  if (rect.IsEmpty() || has_empty_bounds())
    return gfx::Rect();
  if (rect.x() > tiling_size_.width() || rect.y() > tiling_size_.height())
    return gfx::Rect();
  int index_x = FirstBorderTileXIndexFromSrcCoord(rect.x());
  int index_y = FirstBorderTileYIndexFromSrcCoord(rect.y());
  int index_right = LastBorderTileXIndexFromSrcCoord(rect.right() - 1);
  int index_bottom = LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1);

  gfx::Rect rect_top_left(TileBounds(index_x, index_y));
  gfx::Rect rect_bottom_right(TileBounds(index_right, index_bottom));

  return gfx::UnionRects(rect_top_left, rect_bottom_right);
}

gfx::Rect TilingData::TileBounds(int i, int j) const {
  AssertTile(i, j);
  int max_texture_size_x = max_texture_size_.width() - 2 * border_texels_;
  int max_texture_size_y = max_texture_size_.height() - 2 * border_texels_;

  int lo_x = max_texture_size_x * i;
  if (i != 0)
    lo_x += border_texels_;

  int lo_y = max_texture_size_y * j;
  if (j != 0)
    lo_y += border_texels_;

  int hi_x = max_texture_size_x * (i + 1) + border_texels_;
  if (i + 1 == num_tiles_x_)
    hi_x += border_texels_;

  int hi_y = max_texture_size_y * (j + 1) + border_texels_;
  if (j + 1 == num_tiles_y_)
    hi_y += border_texels_;

  hi_x = std::min(hi_x, tiling_size_.width());
  hi_y = std::min(hi_y, tiling_size_.height());

  int x = lo_x;
  int y = lo_y;
  int width = hi_x - lo_x;
  int height = hi_y - lo_y;
  DCHECK_GE(x, 0);
  DCHECK_GE(y, 0);
  DCHECK_GE(width, 0);
  DCHECK_GE(height, 0);
  DCHECK_LE(x, tiling_size_.width());
  DCHECK_LE(y, tiling_size_.height());
  return gfx::Rect(x, y, width, height);
}

gfx::Rect TilingData::TileBoundsWithBorder(int i, int j) const {
  AssertTile(i, j);
  int max_texture_size_x = max_texture_size_.width() - 2 * border_texels_;
  int max_texture_size_y = max_texture_size_.height() - 2 * border_texels_;

  int lo_x = max_texture_size_x * i;
  int lo_y = max_texture_size_y * j;

  int hi_x = lo_x + max_texture_size_x + 2 * border_texels_;
  int hi_y = lo_y + max_texture_size_y + 2 * border_texels_;

  hi_x = std::min(hi_x, tiling_size_.width());
  hi_y = std::min(hi_y, tiling_size_.height());

  int x = lo_x;
  int y = lo_y;
  int width = hi_x - lo_x;
  int height = hi_y - lo_y;
  DCHECK_GE(x, 0);
  DCHECK_GE(y, 0);
  DCHECK_GE(width, 0);
  DCHECK_GE(height, 0);
  DCHECK_LE(x, tiling_size_.width());
  DCHECK_LE(y, tiling_size_.height());
  return gfx::Rect(x, y, width, height);
}

int TilingData::TilePositionX(int x_index) const {
  DCHECK_GE(x_index, 0);
  DCHECK_LT(x_index, num_tiles_x_);

  int pos = (max_texture_size_.width() - 2 * border_texels_) * x_index;
  if (x_index != 0)
    pos += border_texels_;

  return pos;
}

int TilingData::TilePositionY(int y_index) const {
  DCHECK_GE(y_index, 0);
  DCHECK_LT(y_index, num_tiles_y_);

  int pos = (max_texture_size_.height() - 2 * border_texels_) * y_index;
  if (y_index != 0)
    pos += border_texels_;

  return pos;
}

int TilingData::TileSizeX(int x_index) const {
  DCHECK_GE(x_index, 0);
  DCHECK_LT(x_index, num_tiles_x_);

  if (!x_index && num_tiles_x_ == 1)
    return tiling_size_.width();
  if (!x_index && num_tiles_x_ > 1)
    return max_texture_size_.width() - border_texels_;
  if (x_index < num_tiles_x_ - 1)
    return max_texture_size_.width() - 2 * border_texels_;
  if (x_index == num_tiles_x_ - 1)
    return tiling_size_.width() - TilePositionX(x_index);

  NOTREACHED();
  return 0;
}

int TilingData::TileSizeY(int y_index) const {
  DCHECK_GE(y_index, 0);
  DCHECK_LT(y_index, num_tiles_y_);

  if (!y_index && num_tiles_y_ == 1)
    return tiling_size_.height();
  if (!y_index && num_tiles_y_ > 1)
    return max_texture_size_.height() - border_texels_;
  if (y_index < num_tiles_y_ - 1)
    return max_texture_size_.height() - 2 * border_texels_;
  if (y_index == num_tiles_y_ - 1)
    return tiling_size_.height() - TilePositionY(y_index);

  NOTREACHED();
  return 0;
}

gfx::RectF TilingData::TexelExtent(int i, int j) const {
  gfx::RectF result(TileBoundsWithBorder(i, j));
  result.Inset(0.5f, 0.5f);
  return result;
}

gfx::Vector2d TilingData::TextureOffset(int x_index, int y_index) const {
  int left = (!x_index || num_tiles_x_ == 1) ? 0 : border_texels_;
  int top = (!y_index || num_tiles_y_ == 1) ? 0 : border_texels_;

  return gfx::Vector2d(left, top);
}

void TilingData::RecomputeNumTiles() {
  num_tiles_x_ = ComputeNumTiles(
      max_texture_size_.width(), tiling_size_.width(), border_texels_);
  num_tiles_y_ = ComputeNumTiles(
      max_texture_size_.height(), tiling_size_.height(), border_texels_);
}

TilingData::BaseIterator::BaseIterator() : index_x_(-1), index_y_(-1) {
}

TilingData::Iterator::Iterator() : index_rect_(kNonPositiveQuadrantIndexRect) {
  done();
}

TilingData::Iterator::Iterator(const TilingData* tiling_data,
                               const gfx::Rect& consider_rect,
                               bool include_borders)
    : index_rect_(kNonPositiveQuadrantIndexRect) {
  if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) {
    done();
    return;
  }

  gfx::Rect tiling_bounds_rect(tiling_data->tiling_size());
  gfx::Rect rect(consider_rect);
  rect.Intersect(tiling_bounds_rect);

  gfx::Rect top_left_tile;
  if (include_borders) {
    index_x_ = tiling_data->FirstBorderTileXIndexFromSrcCoord(rect.x());
    index_y_ = tiling_data->FirstBorderTileYIndexFromSrcCoord(rect.y());
    index_rect_ = IndexRect(
        index_x_,
        tiling_data->LastBorderTileXIndexFromSrcCoord(rect.right() - 1),
        index_y_,
        tiling_data->LastBorderTileYIndexFromSrcCoord(rect.bottom() - 1));
    DCHECK(index_rect_.is_valid());
    top_left_tile = tiling_data->TileBoundsWithBorder(index_x_, index_y_);
  } else {
    index_x_ = tiling_data->TileXIndexFromSrcCoord(rect.x());
    index_y_ = tiling_data->TileYIndexFromSrcCoord(rect.y());
    index_rect_ = IndexRect(
        index_x_, tiling_data->TileXIndexFromSrcCoord(rect.right() - 1),
        index_y_, tiling_data->TileYIndexFromSrcCoord(rect.bottom() - 1));
    DCHECK(index_rect_.is_valid());
    top_left_tile = tiling_data->TileBounds(index_x_, index_y_);
  }

  // Index functions always return valid indices, so explicitly check
  // for non-intersecting rects.
  if (!top_left_tile.Intersects(rect))
    done();
}

TilingData::Iterator& TilingData::Iterator::operator++() {
  if (!*this)
    return *this;

  index_x_++;
  if (index_x_ > index_rect_.right()) {
    index_x_ = index_rect_.left();
    index_y_++;
    if (index_y_ > index_rect_.bottom())
      done();
  }

  return *this;
}

TilingData::BaseDifferenceIterator::BaseDifferenceIterator()
    : consider_index_rect_(kNonPositiveQuadrantIndexRect),
      ignore_index_rect_(kNonPositiveQuadrantIndexRect) {
  done();
}

TilingData::BaseDifferenceIterator::BaseDifferenceIterator(
    const TilingData* tiling_data,
    const gfx::Rect& consider_rect,
    const gfx::Rect& ignore_rect)
    : consider_index_rect_(kNonPositiveQuadrantIndexRect),
      ignore_index_rect_(kNonPositiveQuadrantIndexRect) {
  if (tiling_data->num_tiles_x() <= 0 || tiling_data->num_tiles_y() <= 0) {
    done();
    return;
  }

  gfx::Rect tiling_bounds_rect(tiling_data->tiling_size());
  gfx::Rect consider(consider_rect);
  consider.Intersect(tiling_bounds_rect);

  if (consider.IsEmpty()) {
    done();
    return;
  }

  consider_index_rect_ =
      IndexRect(tiling_data->TileXIndexFromSrcCoord(consider.x()),
                tiling_data->TileXIndexFromSrcCoord(consider.right() - 1),
                tiling_data->TileYIndexFromSrcCoord(consider.y()),
                tiling_data->TileYIndexFromSrcCoord(consider.bottom() - 1));
  DCHECK(consider_index_rect_.is_valid());

  gfx::Rect ignore(ignore_rect);
  ignore.Intersect(tiling_bounds_rect);

  if (!ignore.IsEmpty()) {
    ignore_index_rect_ =
        IndexRect(tiling_data->TileXIndexFromSrcCoord(ignore.x()),
                  tiling_data->TileXIndexFromSrcCoord(ignore.right() - 1),
                  tiling_data->TileYIndexFromSrcCoord(ignore.y()),
                  tiling_data->TileYIndexFromSrcCoord(ignore.bottom() - 1));
    DCHECK(ignore_index_rect_.is_valid());

    // Clamp ignore indices to consider indices.
    ignore_index_rect_.ClampTo(consider_index_rect_);

    // If ignore rect is invalid, reset.
    if (!ignore_index_rect_.is_valid())
      ignore_index_rect_ = kNonPositiveQuadrantIndexRect;

    if (ignore_index_rect_ == consider_index_rect_) {
      consider_index_rect_ = kNonPositiveQuadrantIndexRect;
      done();
      return;
    }
  }
}

bool TilingData::BaseDifferenceIterator::HasConsiderRect() const {
  // Consider indices are either all valid or all equal to -1.
  DCHECK(consider_index_rect_.is_in_positive_quadrant() ||
         consider_index_rect_ == kNonPositiveQuadrantIndexRect);
  return consider_index_rect_.left() != -1;
}

TilingData::DifferenceIterator::DifferenceIterator() = default;

TilingData::DifferenceIterator::DifferenceIterator(
    const TilingData* tiling_data,
    const gfx::Rect& consider_rect,
    const gfx::Rect& ignore_rect)
    : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) {
  if (!HasConsiderRect()) {
    done();
    return;
  }

  index_x_ = consider_index_rect_.left();
  index_y_ = consider_index_rect_.top();

  if (ignore_index_rect_.Contains(index_x_, index_y_))
    ++(*this);
}

TilingData::DifferenceIterator& TilingData::DifferenceIterator::operator++() {
  if (!*this)
    return *this;

  index_x_++;
  if (ignore_index_rect_.Contains(index_x_, index_y_))
    index_x_ = ignore_index_rect_.right() + 1;

  if (index_x_ > consider_index_rect_.right()) {
    index_x_ = consider_index_rect_.left();
    index_y_++;

    if (ignore_index_rect_.Contains(index_x_, index_y_)) {
      index_x_ = ignore_index_rect_.right() + 1;
      // If the ignore rect spans the whole consider rect horizontally, then
      // ignore_right + 1 will be out of bounds.
      if (ignore_index_rect_.Contains(index_x_, index_y_) ||
          index_x_ > consider_index_rect_.right()) {
        index_y_ = ignore_index_rect_.bottom() + 1;
        index_x_ = consider_index_rect_.left();
      }
    }

    if (index_y_ > consider_index_rect_.bottom())
      done();
  }

  return *this;
}

TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator() {
  done();
}

TilingData::SpiralDifferenceIterator::SpiralDifferenceIterator(
    const TilingData* tiling_data,
    const gfx::Rect& consider_rect,
    const gfx::Rect& ignore_rect,
    const gfx::Rect& center_rect)
    : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) {
  if (!HasConsiderRect()) {
    done();
    return;
  }

  IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect);
  DCHECK(around_index_rect.is_valid());

  spiral_iterator_ = SpiralIterator(around_index_rect, consider_index_rect_,
                                    ignore_index_rect_);

  if (!spiral_iterator_) {
    done();
    return;
  }

  index_x_ = spiral_iterator_.index_x();
  index_y_ = spiral_iterator_.index_y();
}

TilingData::SpiralDifferenceIterator& TilingData::SpiralDifferenceIterator::
operator++() {
  ++spiral_iterator_;

  if (!spiral_iterator_) {
    done();
    return *this;
  }

  index_x_ = spiral_iterator_.index_x();
  index_y_ = spiral_iterator_.index_y();

  return *this;
}

TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator() {
  done();
}

TilingData::ReverseSpiralDifferenceIterator::ReverseSpiralDifferenceIterator(
    const TilingData* tiling_data,
    const gfx::Rect& consider_rect,
    const gfx::Rect& ignore_rect,
    const gfx::Rect& center_rect)
    : BaseDifferenceIterator(tiling_data, consider_rect, ignore_rect) {
  if (!HasConsiderRect()) {
    done();
    return;
  }

  IndexRect around_index_rect = tiling_data->TileAroundIndexRect(center_rect);
  DCHECK(around_index_rect.is_valid());

  reverse_spiral_iterator_ = ReverseSpiralIterator(
      around_index_rect, consider_index_rect_, ignore_index_rect_);

  if (!reverse_spiral_iterator_) {
    done();
    return;
  }

  index_x_ = reverse_spiral_iterator_.index_x();
  index_y_ = reverse_spiral_iterator_.index_y();
}

TilingData::ReverseSpiralDifferenceIterator&
    TilingData::ReverseSpiralDifferenceIterator::
    operator++() {
  ++reverse_spiral_iterator_;

  if (!reverse_spiral_iterator_) {
    done();
    return *this;
  }

  index_x_ = reverse_spiral_iterator_.index_x();
  index_y_ = reverse_spiral_iterator_.index_y();

  return *this;
}

}  // namespace cc
