// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:math' as math;

import 'package:flutter/rendering.dart';

import 'base_grid_layout.dart';
import 'render_dynamic_grid.dart';
import 'wrap_layout.dart';

/// A [DynamicSliverGridLayout] that creates tiles with varying main axis
/// sizes and fixed cross axis sizes, generating a staggered layout. The extent
/// in the main axis will be defined by the child's size and must be finite.
/// Similar to Android's StaggeredGridLayoutManager:
/// [https://developer.android.com/reference/androidx/recyclerview/widget/StaggeredGridLayoutManager].
///
/// The tiles are placed in the column (or row in case [scrollDirection] is set
/// to [Axis.horizontal]) with the minimum extent, which means children are not
/// neccesarily layed out in sequential order.
///
/// See also:
///
///  * [SliverGridWrappingTileLayout], a similar layout that allows tiles to be
///    freely sized in the main and cross axis.
///  * [DynamicSliverGridDelegateWithMaxCrossAxisExtent], which creates
///    staggered layouts with a maximum extent in the cross axis.
///  * [DynamicSliverGridDelegateWithFixedCrossAxisCount], which creates
///    staggered layouts with a consistent amount of tiles in the cross axis.
///  * [DynamicGridView.staggered], which uses these delegates to create
///    staggered layouts.
///  * [DynamicSliverGridGeometry], which establishes the position of a child
///    and pass the child's desired proportions to a [DynamicSliverGridLayout].
///  * [RenderDynamicSliverGrid], which is the sliver where the dynamic sized
///    tiles are positioned.
class SliverGridStaggeredTileLayout extends DynamicSliverGridLayout {
  /// Creates a layout with dynamic main axis extents determined by the child's
  /// size and fixed cross axis extents.
  ///
  /// All arguments must be not null. The [crossAxisCount] argument must be
  /// greater than zero. The [mainAxisSpacing], [crossAxisSpacing] and
  /// [childCrossAxisExtent] arguments must not be negative.
  SliverGridStaggeredTileLayout({
    required this.crossAxisCount,
    required this.mainAxisSpacing,
    required this.crossAxisSpacing,
    required this.childCrossAxisExtent,
    required this.scrollDirection,
  })  : assert(crossAxisCount != null && crossAxisCount > 0),
        assert(crossAxisSpacing != null && crossAxisSpacing >= 0),
        assert(childCrossAxisExtent != null && childCrossAxisExtent >= 0);

  /// The number of children in the cross axis.
  final int crossAxisCount;

  /// The number of logical pixels between each child along the main axis.
  final double mainAxisSpacing;

  /// The number of logical pixels between each child along the cross axis.
  final double crossAxisSpacing;

  /// The number of pixels from the leading edge of one tile to the trailing
  /// edge of the same tile in the cross axis.
  final double childCrossAxisExtent;

  /// The axis along which the scroll view scrolls.
  final Axis scrollDirection;

  /// The collection of scroll offsets for every row or column across the main
  /// axis. It includes the tiles' sizes and the spacing between them.
  final List<double> _scrollOffsetForMainAxis = <double>[];

  /// The amount of tiles in every row or column across the main axis.
  final List<int> _mainAxisCount = <int>[];

  /// Returns the row or column with the minimum extent for the next child to
  /// be layed out.
  int _getNextCrossAxisSlot() {
    int nextCrossAxisSlot = 0;
    double minScrollOffset = double.infinity;

    if (_scrollOffsetForMainAxis.length < crossAxisCount) {
      nextCrossAxisSlot = _scrollOffsetForMainAxis.length;
      _scrollOffsetForMainAxis.add(0.0);
      return nextCrossAxisSlot;
    }

    for (int i = 0; i < crossAxisCount; i++) {
      if (_scrollOffsetForMainAxis[i] < minScrollOffset) {
        nextCrossAxisSlot = i;
        minScrollOffset = _scrollOffsetForMainAxis[i];
      }
    }
    return nextCrossAxisSlot;
  }

  @override
  bool reachedTargetScrollOffset(double targetOffset) {
    for (final double scrollOffset in _scrollOffsetForMainAxis) {
      if (scrollOffset < targetOffset) {
        return false;
      }
    }
    return true;
  }

  @override
  DynamicSliverGridGeometry getGeometryForChildIndex(int index) {
    return DynamicSliverGridGeometry(
      scrollOffset: 0.0,
      crossAxisOffset: 0.0,
      mainAxisExtent: double.infinity,
      crossAxisExtent: childCrossAxisExtent,
    );
  }

  @override
  DynamicSliverGridGeometry updateGeometryForChildIndex(
    int index,
    Size childSize,
  ) {
    final int crossAxisSlot = _getNextCrossAxisSlot();
    final double currentScrollOffset = _scrollOffsetForMainAxis[crossAxisSlot];
    final double childMainAxisExtent =
        scrollDirection == Axis.vertical ? childSize.height : childSize.width;
    final double scrollOffset = currentScrollOffset +
        (_mainAxisCount.length >= crossAxisCount
                ? _mainAxisCount[crossAxisSlot]
                : 0) *
            mainAxisSpacing;
    final double crossAxisOffset =
        crossAxisSlot * (childCrossAxisExtent + crossAxisSpacing);
    final double mainAxisExtent =
        scrollDirection == Axis.vertical ? childSize.height : childSize.width;
    _scrollOffsetForMainAxis[crossAxisSlot] =
        childMainAxisExtent + _scrollOffsetForMainAxis[crossAxisSlot];
    _mainAxisCount.length >= crossAxisCount
        ? _mainAxisCount[crossAxisSlot] += 1
        : _mainAxisCount.add(1);

    return DynamicSliverGridGeometry(
      scrollOffset: scrollOffset,
      crossAxisOffset: crossAxisOffset,
      mainAxisExtent: mainAxisExtent,
      crossAxisExtent: childCrossAxisExtent,
    );
  }
}

/// Creates dynamic grid layouts with a fixed number of tiles in the cross axis
/// and varying main axis size dependent on the child's corresponding finite
/// extent. It uses the same logic as
/// [SliverGridDelegateWithFixedCrossAxisCount] where the total extent in the
/// cross axis is distributed equally between the specified amount of tiles,
/// but with a [SliverGridStaggeredTileLayout].
///
/// For example, if the grid is vertical, this delegate will create a layout
/// with a fixed number of columns. If the grid is horizontal, this delegate
/// will create a layout with a fixed number of rows.
///
/// This sample code shows how to use it independently with a [DynamicGridView]
/// constructor:
///
/// ```dart
/// DynamicGridView(
///   gridDelegate: const DynamicSliverGridDelegateWithFixedCrossAxisCount(
///     crossAxisCount: 4,
///   ),
///   children: List<Widget>.generate(
///     50,
///     (int index) => SizedBox(
///       height: index % 2 * 20 + 20,
///       child: Text('Index $index'),
///     ),
///   ),
/// );
/// ```
///
/// See also:
///
///  * [DynamicSliverGridDelegateWithMaxCrossAxisExtent], which creates a
///    dynamic layout with tiles that have a maximum cross-axis extent
///    and varying main axis size.
///  * [DynamicGridView], which can use this delegate to control the layout of
///    its tiles.
///  * [DynamicSliverGridGeometry], which establishes the position of a child
///    and pass the child's desired proportions to [DynamicSliverGridLayout].
///  * [RenderDynamicSliverGrid], which is the sliver where the dynamic sized
///    tiles are positioned.
class DynamicSliverGridDelegateWithFixedCrossAxisCount
    extends SliverGridDelegateWithFixedCrossAxisCount {
  /// Creates a delegate that makes grid layouts with a fixed number of tiles
  /// in the cross axis and varying main axis size dependent on the child's
  /// corresponding finite extent.
  ///
  /// Only the [crossAxisCount] argument needs to be greater than zero. All of
  /// them must be not null.
  const DynamicSliverGridDelegateWithFixedCrossAxisCount({
    required super.crossAxisCount,
    super.mainAxisSpacing = 0.0,
    super.crossAxisSpacing = 0.0,
  })  : assert(crossAxisCount != null && crossAxisCount > 0),
        assert(mainAxisSpacing != null && mainAxisSpacing >= 0),
        assert(crossAxisSpacing != null && crossAxisSpacing >= 0);

  bool _debugAssertIsValid() {
    assert(crossAxisCount > 0);
    assert(mainAxisSpacing >= 0.0);
    assert(crossAxisSpacing >= 0.0);
    assert(childAspectRatio > 0.0);
    return true;
  }

  @override
  DynamicSliverGridLayout getLayout(SliverConstraints constraints) {
    assert(_debugAssertIsValid());
    final double usableCrossAxisExtent = math.max(
      0.0,
      constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1),
    );
    final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
    return SliverGridStaggeredTileLayout(
      crossAxisCount: crossAxisCount,
      mainAxisSpacing: mainAxisSpacing,
      crossAxisSpacing: crossAxisSpacing,
      childCrossAxisExtent: childCrossAxisExtent,
      scrollDirection: axisDirectionToAxis(constraints.axisDirection),
    );
  }
}

/// Creates dynamic grid layouts with tiles that each have a maximum cross-axis
/// extent and varying main axis size dependent on the child's corresponding
/// finite extent. It uses the same logic as
/// [SliverGridDelegateWithMaxCrossAxisExtent] where every tile has the same
/// cross axis size and does not exceed the provided max extent, but with a
/// [SliverGridStaggeredTileLayout].
///
/// This delegate will select a cross-axis extent for the tiles that is as
/// large as possible subject to the following conditions:
///
///  * The extent evenly divides the cross-axis extent of the grid.
///  * The extent is at most [maxCrossAxisExtent].
///
/// This sample code shows how to use it independently with a [DynamicGridView]
/// constructor:
///
/// ```dart
/// DynamicGridView(
///   gridDelegate: const DynamicSliverGridDelegateWithMaxCrossAxisExtent(
///     maxCrossAxisExtent: 100,
///   ),
///   children: List<Widget>.generate(
///     50,
///     (int index) => SizedBox(
///       height: index % 2 * 20 + 20,
///       child: Text('Index $index'),
///     ),
///   ),
/// );
/// ```
///
/// See also:
///
///  * [DynamicSliverGridDelegateWithFixedCrossAxisCount], which creates a
///    layout with a fixed number of tiles in the cross axis.
///  * [DynamicGridView], which can use this delegate to control the layout of
///    its tiles.
///  * [DynamicSliverGridGeometry], which establishes the position of a child
///    and pass the child's desired proportions to [DynamicSliverGridLayout].
///  * [RenderDynamicSliverGrid], which is the sliver where the dynamic sized
///    tiles are positioned.
class DynamicSliverGridDelegateWithMaxCrossAxisExtent
    extends SliverGridDelegateWithMaxCrossAxisExtent {
  /// Creates a delegate that makes grid layouts with tiles that have a maximum
  /// cross-axis extent and varying main axis size dependent on the child's
  /// corresponding finite extent.
  ///
  /// Only the [maxCrossAxisExtent] argument needs to be greater than zero.
  /// All of them must be not null.
  const DynamicSliverGridDelegateWithMaxCrossAxisExtent({
    required super.maxCrossAxisExtent,
    super.mainAxisSpacing = 0.0,
    super.crossAxisSpacing = 0.0,
  })  : assert(maxCrossAxisExtent != null && maxCrossAxisExtent > 0),
        assert(mainAxisSpacing != null && mainAxisSpacing >= 0),
        assert(crossAxisSpacing != null && crossAxisSpacing >= 0);

  bool _debugAssertIsValid(double crossAxisExtent) {
    assert(crossAxisExtent > 0.0);
    assert(maxCrossAxisExtent > 0.0);
    assert(mainAxisSpacing >= 0.0);
    assert(crossAxisSpacing >= 0.0);
    assert(childAspectRatio > 0.0);
    return true;
  }

  @override
  DynamicSliverGridLayout getLayout(SliverConstraints constraints) {
    assert(_debugAssertIsValid(constraints.crossAxisExtent));
    final int crossAxisCount =
        (constraints.crossAxisExtent / (maxCrossAxisExtent + crossAxisSpacing))
            .ceil();
    final double usableCrossAxisExtent = math.max(
      0.0,
      constraints.crossAxisExtent - crossAxisSpacing * (crossAxisCount - 1),
    );
    final double childCrossAxisExtent = usableCrossAxisExtent / crossAxisCount;
    return SliverGridStaggeredTileLayout(
      crossAxisCount: crossAxisCount,
      mainAxisSpacing: mainAxisSpacing,
      crossAxisSpacing: crossAxisSpacing,
      childCrossAxisExtent: childCrossAxisExtent,
      scrollDirection: axisDirectionToAxis(constraints.axisDirection),
    );
  }
}
