// 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' as ui;

import 'package:flutter/rendering.dart';

import 'basic.dart';
import 'debug.dart';
import 'framework.dart';
import 'media_query.dart';

/// Controls how the [SnapshotWidget] paints its child.
enum SnapshotMode {
  /// The child is snapshotted, but only if all descendants can be snapshotted.
  ///
  /// If there is a platform view in the children of a snapshot widget, the
  /// snapshot will not be used and the child will be rendered using
  /// [SnapshotPainter.paint]. This uses an un-snapshotted child and by default
  /// paints it with no additional modification.
  permissive,

  /// An error is thrown if the child cannot be snapshotted.
  ///
  /// This setting is the default state of the [SnapshotWidget].
  normal,

  /// The child is snapshotted and any child platform views are ignored.
  ///
  /// This mode can be useful if there is a platform view descendant that does
  /// not need to be included in the snapshot.
  forced,
}

/// A controller for the [SnapshotWidget] that controls when the child image is displayed
/// and when to regenerated the child image.
///
/// When the value of [allowSnapshotting] is true, the [SnapshotWidget] will paint the child
/// widgets based on the [SnapshotMode] of the snapshot widget.
///
/// The controller notifies its listeners when the value of [allowSnapshotting] changes
/// or when [clear] is called.
///
/// To force [SnapshotWidget] to recreate the child image, call [clear].
class SnapshotController extends ChangeNotifier {
  /// Create a new [SnapshotController].
  ///
  /// By default, [allowSnapshotting] is `false` and cannot be `null`.
  SnapshotController({
    bool allowSnapshotting = false,
  }) : _allowSnapshotting = allowSnapshotting;

  /// Reset the snapshot held by any listening [SnapshotWidget].
  ///
  /// This has no effect if [allowSnapshotting] is `false`.
  void clear() {
    notifyListeners();
  }

  /// Whether a snapshot of this child widget is painted in its place.
  bool get allowSnapshotting => _allowSnapshotting;
  bool _allowSnapshotting;
  set allowSnapshotting(bool value) {
    if (value == allowSnapshotting) {
      return;
    }
    _allowSnapshotting = value;
    notifyListeners();
  }
}

/// A widget that can replace its child with a snapshotted version of the child.
///
/// A snapshot is a frozen texture-backed representation of all child pictures
/// and layers stored as a [ui.Image].
///
/// This widget is useful for performing short animations that would otherwise
/// be expensive or that cannot rely on raster caching. For example, scale and
/// skew animations are often expensive to perform on complex children, as are
/// blurs. For a short animation, a widget that contains these expensive effects
/// can be replaced with a snapshot of itself and manipulated instead.
///
/// For example, the Android Q [ZoomPageTransitionsBuilder] uses a snapshot widget
/// for the forward and entering route to avoid the expensive scale animation.
/// This also has the effect of briefly pausing any animations on the page.
///
/// Generally, this widget should not be used in places where users expect the
/// child widget to continue animating or to be responsive, such as an unbounded
/// animation.
///
/// Caveats:
///
/// * The contents of platform views cannot be captured by a snapshot
///   widget. If a platform view is encountered, then the snapshot widget will
///   determine how to render its children based on the [SnapshotMode]. This
///   defaults to [SnapshotMode.normal] which will throw an exception if a
///   platform view is encountered.
///
/// * The snapshotting functionality of this widget is not supported on the HTML
///   backend of Flutter for the Web. Setting [SnapshotController.allowSnapshotting] to true
///   may cause an error to be thrown. On the CanvasKit backend of Flutter, the
///   performance of using this widget may regress performance due to the fact
///   that both the UI and engine share a single thread.
class SnapshotWidget extends SingleChildRenderObjectWidget {
  /// Create a new [SnapshotWidget].
  ///
  /// The [controller] and [child] arguments are required.
  const SnapshotWidget({
    super.key,
    this.mode = SnapshotMode.normal,
    this.painter = const _DefaultSnapshotPainter(),
    this.autoresize = false,
    required this.controller,
    required super.child
  });

  /// The controller that determines when to display the children as a snapshot.
  final SnapshotController controller;

  /// Configuration that controls how the snapshot widget decides to paint its children.
  ///
  /// Defaults to [SnapshotMode.normal], which throws an error when a platform view
  /// or texture view is encountered.
  ///
  /// See [SnapshotMode] for more information.
  final SnapshotMode mode;

  /// Whether or not changes in render object size should automatically re-create
  /// the snapshot.
  ///
  /// Defaults to false.
  final bool autoresize;

  /// The painter used to paint the child snapshot or child widgets.
  final SnapshotPainter painter;

  @override
  RenderObject createRenderObject(BuildContext context) {
    debugCheckHasMediaQuery(context);
    return _RenderSnapshotWidget(
      controller: controller,
      mode: mode,
      devicePixelRatio: MediaQuery.devicePixelRatioOf(context),
      painter: painter,
      autoresize: autoresize,
    );
  }

  @override
  void updateRenderObject(BuildContext context, covariant RenderObject renderObject) {
    debugCheckHasMediaQuery(context);
    (renderObject as _RenderSnapshotWidget)
      ..controller = controller
      ..mode = mode
      ..devicePixelRatio = MediaQuery.devicePixelRatioOf(context)
      ..painter = painter
      ..autoresize = autoresize;
  }
}

// A render object that conditionally converts its child into a [ui.Image]
// and then paints it in place of the child.
class _RenderSnapshotWidget extends RenderProxyBox {
  // Create a new [_RenderSnapshotWidget].
  _RenderSnapshotWidget({
    required double devicePixelRatio,
    required SnapshotController controller,
    required SnapshotMode mode,
    required SnapshotPainter painter,
    required bool autoresize,
  }) : _devicePixelRatio = devicePixelRatio,
       _controller = controller,
       _mode = mode,
       _painter = painter,
       _autoresize = autoresize;

  /// The device pixel ratio used to create the child image.
  double get devicePixelRatio => _devicePixelRatio;
  double _devicePixelRatio;
  set devicePixelRatio(double value) {
    if (value == devicePixelRatio) {
      return;
    }
    _devicePixelRatio = value;
    if (_childRaster == null) {
      return;
    } else {
      _childRaster?.dispose();
      _childRaster = null;
      markNeedsPaint();
    }
  }

  /// The painter used to paint the child snapshot or child widgets.
  SnapshotPainter get painter => _painter;
  SnapshotPainter _painter;
  set painter(SnapshotPainter value) {
    if (value == painter) {
      return;
    }
    final SnapshotPainter oldPainter = painter;
    oldPainter.removeListener(markNeedsPaint);
    _painter = value;
    if (oldPainter.runtimeType != painter.runtimeType ||
        painter.shouldRepaint(oldPainter)) {
      markNeedsPaint();
    }
    if (attached) {
      painter.addListener(markNeedsPaint);
    }
  }

  /// A controller that determines whether to paint the child normally or to
  /// paint a snapshotted version of that child.
  SnapshotController get controller => _controller;
  SnapshotController _controller;
  set controller(SnapshotController value) {
    if (value == controller) {
      return;
    }
    controller.removeListener(_onRasterValueChanged);
    final bool oldValue = controller.allowSnapshotting;
    _controller = value;
    if (attached) {
      controller.addListener(_onRasterValueChanged);
      if (oldValue != controller.allowSnapshotting) {
        _onRasterValueChanged();
      }
    }
  }

  /// How the snapshot widget will handle platform views in child layers.
  SnapshotMode get mode => _mode;
  SnapshotMode _mode;
  set mode(SnapshotMode value) {
    if (value == _mode) {
      return;
    }
    _mode = value;
    markNeedsPaint();
  }

  /// Whether or not changes in render object size should automatically re-rasterize.
  bool get autoresize => _autoresize;
  bool _autoresize;
  set autoresize(bool value) {
    if (value == autoresize) {
      return;
    }
    _autoresize = value;
    markNeedsPaint();
  }

  ui.Image? _childRaster;
  Size? _childRasterSize;
  // Set to true if the snapshot mode was not forced and a platform view
  // was encountered while attempting to snapshot the child.
  bool _disableSnapshotAttempt = false;

  @override
  void attach(covariant PipelineOwner owner) {
    controller.addListener(_onRasterValueChanged);
    painter.addListener(markNeedsPaint);
    super.attach(owner);
  }

  @override
  void detach() {
    _disableSnapshotAttempt = false;
    controller.removeListener(_onRasterValueChanged);
    painter.removeListener(markNeedsPaint);
    _childRaster?.dispose();
    _childRaster = null;
    _childRasterSize = null;
    super.detach();
  }

  @override
  void dispose() {
    controller.removeListener(_onRasterValueChanged);
    painter.removeListener(markNeedsPaint);
    _childRaster?.dispose();
    _childRaster = null;
    _childRasterSize = null;
    super.dispose();
  }

  void _onRasterValueChanged() {
    _disableSnapshotAttempt = false;
    _childRaster?.dispose();
    _childRaster = null;
    _childRasterSize = null;
    markNeedsPaint();
  }

  // Paint [child] with this painting context, then convert to a raster and detach all
  // children from this layer.
  ui.Image? _paintAndDetachToImage() {
    final OffsetLayer offsetLayer = OffsetLayer();
    final PaintingContext context = PaintingContext(offsetLayer, Offset.zero & size);
    super.paint(context, Offset.zero);
    // This ignore is here because this method is protected by the `PaintingContext`. Adding a new
    // method that performs the work of `_paintAndDetachToImage` would avoid the need for this, but
    // that would conflict with our goals of minimizing painting context.
    // ignore: invalid_use_of_protected_member
    context.stopRecordingIfNeeded();
    if (mode != SnapshotMode.forced && !offsetLayer.supportsRasterization()) {
      if (mode == SnapshotMode.normal) {
        throw FlutterError('SnapshotWidget used with a child that contains a PlatformView.');
      }
      _disableSnapshotAttempt = true;
      return null;
    }
    final ui.Image image = offsetLayer.toImageSync(Offset.zero & size, pixelRatio: devicePixelRatio);
    offsetLayer.dispose();
    _lastCachedSize = size;
    return image;
  }

  Size? _lastCachedSize;

  @override
  void paint(PaintingContext context, Offset offset) {
    if (size.isEmpty) {
      _childRaster?.dispose();
      _childRaster = null;
      _childRasterSize = null;
      return;
    }
    if (!controller.allowSnapshotting || _disableSnapshotAttempt) {
      _childRaster?.dispose();
      _childRaster = null;
      _childRasterSize = null;
      painter.paint(context, offset, size, super.paint);
      return;
    }

    if (autoresize && size != _lastCachedSize && _lastCachedSize != null) {
      _childRaster?.dispose();
      _childRaster = null;
    }

    if (_childRaster == null) {
      _childRaster = _paintAndDetachToImage();
      _childRasterSize = size * devicePixelRatio;
    }
    if (_childRaster == null) {
      painter.paint(context, offset, size, super.paint);
    } else {
      painter.paintSnapshot(context, offset, size, _childRaster!, _childRasterSize!, devicePixelRatio);
    }
  }
}

/// A painter used to paint either a snapshot or the child widgets that
/// would be a snapshot.
///
/// The painter can call [notifyListeners] to have the [SnapshotWidget]
/// re-paint (re-using the same raster). This allows animations to be performed
/// without re-snapshotting of children. For certain scale or perspective changing
/// transforms, such as a rotation, this can be significantly faster than performing
/// the same animation at the widget level.
///
/// By default, the [SnapshotWidget] includes a delegate that draws the child raster
/// exactly as the child widgets would have been drawn. Nevertheless, this can
/// also be used to efficiently transform the child raster and apply complex paint
/// effects.
///
/// {@tool snippet}
///
/// The following method shows how to efficiently rotate the child raster.
///
/// ```dart
/// void paint(PaintingContext context, Offset offset, Size size, ui.Image image, double pixelRatio) {
///   const double radians = 0.5; // Could be driven by an animation.
///   final Matrix4 transform = Matrix4.rotationZ(radians);
///   context.canvas.transform(transform.storage);
///   final Rect src = Rect.fromLTWH(0, 0, image.width.toDouble(), image.height.toDouble());
///   final Rect dst = Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height);
///   final Paint paint = Paint()
///     ..filterQuality = FilterQuality.low;
///   context.canvas.drawImageRect(image, src, dst, paint);
/// }
/// ```
/// {@end-tool}
abstract class SnapshotPainter extends ChangeNotifier  {
  /// Called whenever the [image] that represents a [SnapshotWidget]s child should be painted.
  ///
  /// The image is rasterized at the physical pixel resolution and should be scaled down by
  /// [pixelRatio] to account for device independent pixels.
  ///
  /// {@tool snippet}
  ///
  /// The following method shows how the default implementation of the delegate used by the
  /// [SnapshotPainter] paints the snapshot. This must account for the fact that the image
  /// width and height will be given in physical pixels, while the image must be painted with
  /// device independent pixels. That is, the width and height of the image is the widget and
  /// height of the provided `size`, multiplied by the `pixelRatio`. In addition, the actual
  /// size of the scene captured by the `image` is not `image.width` or `image.height`, but
  /// indeed `sourceSize`, because the former is a rounded inaccurate integer:
  ///
  /// ```dart
  /// void paint(PaintingContext context, Offset offset, Size size, ui.Image image, Size sourceSize, double pixelRatio) {
  ///   final Rect src = Rect.fromLTWH(0, 0, sourceSize.width, sourceSize.height);
  ///   final Rect dst = Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height);
  ///   final Paint paint = Paint()
  ///     ..filterQuality = FilterQuality.low;
  ///   context.canvas.drawImageRect(image, src, dst, paint);
  /// }
  /// ```
  /// {@end-tool}
  void paintSnapshot(PaintingContext context, Offset offset, Size size, ui.Image image, Size sourceSize, double pixelRatio);

  /// Paint the child via [painter], applying any effects that would have been painted
  /// in [SnapshotPainter.paintSnapshot].
  ///
  /// This method is called when snapshotting is disabled, or when [SnapshotMode.permissive]
  /// is used and a child platform view prevents snapshotting.
  ///
  /// The [offset] and [size] are the location and dimensions of the render object.
  void paint(PaintingContext context, Offset offset, Size size, PaintingContextCallback painter);

  /// Called whenever a new instance of the snapshot widget delegate class is
  /// provided to the [SnapshotWidget] object, or any time that a new
  /// [SnapshotPainter] object is created with a new instance of the
  /// delegate class (which amounts to the same thing, because the latter is
  /// implemented in terms of the former).
  ///
  /// If the new instance represents different information than the old
  /// instance, then the method should return true, otherwise it should return
  /// false.
  ///
  /// If the method returns false, then the [paint] call might be optimized
  /// away.
  ///
  /// It's possible that the [paint] method will get called even if
  /// [shouldRepaint] returns false (e.g. if an ancestor or descendant needed to
  /// be repainted). It's also possible that the [paint] method will get called
  /// without [shouldRepaint] being called at all (e.g. if the box changes
  /// size).
  ///
  /// Changing the delegate will not cause the child image retained by the
  /// [SnapshotWidget] to be updated. Instead, [SnapshotController.clear] can
  /// be used to force the generation of a new image.
  ///
  /// The `oldPainter` argument will never be null.
  bool shouldRepaint(covariant SnapshotPainter oldPainter);
}

class _DefaultSnapshotPainter implements SnapshotPainter {
  const _DefaultSnapshotPainter();

  @override
  void addListener(ui.VoidCallback listener) { }

  @override
  void dispose() { }

  @override
  bool get hasListeners => false;

  @override
  void notifyListeners() { }

  @override
  void paint(PaintingContext context, ui.Offset offset, ui.Size size, PaintingContextCallback painter) {
    painter(context, offset);
  }

  @override
  void paintSnapshot(PaintingContext context, ui.Offset offset, ui.Size size, ui.Image image, Size sourceSize, double pixelRatio) {
    final Rect src = Rect.fromLTWH(0, 0, sourceSize.width, sourceSize.height);
    final Rect dst = Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height);
    final Paint paint = Paint()
      ..filterQuality = FilterQuality.low;
    context.canvas.drawImageRect(image, src, dst, paint);
  }

  @override
  void removeListener(ui.VoidCallback listener) { }

  @override
  bool shouldRepaint(covariant _DefaultSnapshotPainter oldPainter) => false;
}
