// 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:math' as math;
import 'dart:ui';

import 'recorder.dart';

/// Draws many pictures in a grid with only the middle picture visible on the
/// screen, all others are clipped out, for example:
///
///     +-------------+-------------+-------------+---...
///     |             |             |             |
///     |  invisible  |  invisible  |  invisible  |
///     |             |             |             |
///     +-----------------------------------------+---...
///     |             |             |             |
///     |  invisible  |  invisible  |  invisible  |
///     |             |             |             |
///     +-----------------------------------------+---...
///     |             |             |             |
///     |  invisible  |  invisible  |   VISIBLE   |
///     |             |             |             |
///     +-------------+-------------+-------------+---...
///     |             |             |             |
///     :             :             :             :
///
/// We used to unnecessarily allocate DOM nodes, consuming memory and CPU time.
class BenchClippedOutPictures extends SceneBuilderRecorder {
  BenchClippedOutPictures() : super(name: benchmarkName);

  static const String benchmarkName = 'clipped_out_pictures';

  static final Paint paint = Paint();

  double angle = 0.0;

  static const int kRows = 20;
  static const int kColumns = 20;

  @override
  void onDrawFrame(SceneBuilder sceneBuilder) {
    final Size screenSize = window.physicalSize / window.devicePixelRatio;
    final Size pictureSize = Size(
      screenSize.width / kColumns,
      screenSize.height / kRows,
    );

    // Fills a single cell with random text.
    void fillCell(int row, int column) {
      sceneBuilder.pushOffset(
        column * pictureSize.width,
        row * pictureSize.height,
      );

      final PictureRecorder pictureRecorder = PictureRecorder();
      final Canvas canvas = Canvas(pictureRecorder);
      canvas.save();
      canvas.drawCircle(Offset(pictureSize.width / 2, pictureSize.height / 2), 5.0, paint);
      canvas.drawRect(Rect.fromCenter(
        center: Offset(pictureSize.width / 2, pictureSize.height / 2),
        width: pictureSize.width / 6,
        height: pictureSize.height / 6,
      ), paint);
      canvas.restore();
      final Picture picture = pictureRecorder.endRecording();
      sceneBuilder.addPicture(Offset.zero, picture);
      sceneBuilder.pop();
    }

    // Starting with the top-left cell, fill every cell.
    sceneBuilder.pushClipRect(Rect.fromCircle(
      center: Offset(screenSize.width / 2, screenSize.height / 2),
      radius: math.min(screenSize.width, screenSize.height) / 6,
    ));
    sceneBuilder.pushOffset(
      5.0 * math.cos(angle),
      5.0 * math.sin(angle),
    );
    angle += math.pi / 20;
    for (int row = 0; row < 10; row++) {
      for (int column = 0; column < 10; column++) {
        fillCell(row, column);
      }
    }
    sceneBuilder.pop();
    sceneBuilder.pop();
  }
}
