// Copyright 2014 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:ui';

import 'recorder.dart';

/// Repeatedly paints a grid of rectangles where each rectangle is drawn in its
/// own [Picture].
///
/// Measures the performance of updating many layers. For example, the HTML
/// rendering backend attempts to reuse the DOM nodes created for engine layers.
///
/// See also `bench_draw_rect.dart`, which draws nearly identical UI but puts all
/// rectangles into the same picture.
class BenchUpdateManyChildLayers extends SceneBuilderRecorder {
  BenchUpdateManyChildLayers() : super(name: benchmarkName);

  static const String benchmarkName = 'bench_update_many_child_layers';

  /// Number of rows in the grid.
  static const int kRows = 32;

  /// Number of columns in the grid.
  static const int kColumns = 32;

  /// Counter used to offset the rendered rects to make them wobble.
  ///
  /// The wobbling is there so a human could visually verify that the benchmark
  /// is correctly pumping frames.
  double wobbleCounter = 0;

  late List<Picture> _pictures;
  late Size windowSize;
  late Size cellSize;
  late Size rectSize;

  @override
  Future<void> setUpAll() async {
    _pictures = <Picture>[];
    windowSize = window.physicalSize;
    cellSize = Size(
      windowSize.width / kColumns,
      windowSize.height / kRows,
    );
    rectSize = cellSize * 0.8;

    final Paint paint = Paint()..color = const Color.fromARGB(255, 255, 0, 0);
    for (int i = 0; i < kRows * kColumns; i++) {
      final PictureRecorder pictureRecorder = PictureRecorder();
      final Canvas canvas = Canvas(pictureRecorder);
      canvas.drawRect(Offset.zero & rectSize, paint);
      _pictures.add(pictureRecorder.endRecording());
    }
  }

  OffsetEngineLayer? _rootLayer;
  final Map<int, OffsetEngineLayer> _layers = <int, OffsetEngineLayer>{};

  @override
  void onDrawFrame(SceneBuilder sceneBuilder) {
    _rootLayer = sceneBuilder.pushOffset(0, 0, oldLayer: _rootLayer);
    for (int row = 0; row < kRows; row++) {
      for (int col = 0; col < kColumns; col++) {
        final int layerId = 1000000 * row + col;
        final OffsetEngineLayer? oldLayer = _layers[layerId];
        final double wobbleOffsetX = col * cellSize.width + (wobbleCounter - 5).abs();
        final double offsetY = row * cellSize.height;
        // Retain every other layer, so we exercise the update path 50% of the
        // time and the retain path the other 50%.
        final bool shouldRetain = oldLayer != null && (row + col).isEven;
        if (shouldRetain) {
          sceneBuilder.addRetained(oldLayer);
        } else {
          _layers[layerId] = sceneBuilder.pushOffset(
            wobbleOffsetX,
            offsetY,
            oldLayer: oldLayer,
          );
          sceneBuilder.addPicture(Offset.zero, _pictures[row * kColumns + col]);
          sceneBuilder.pop();
        }
      }
    }
    sceneBuilder.pop();
    wobbleCounter += 1;
    wobbleCounter = wobbleCounter % 10;
  }
}
