// 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(),
    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;

  /// 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.of(context).devicePixelRatio,
      painter: painter,
    );
  }

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

// 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,
  }) : _devicePixelRatio = devicePixelRatio,
       _controller = controller,
       _mode = mode,
       _painter = painter;

  /// 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();
  }

  ui.Image? _childRaster;
  // 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;
    super.detach();
  }

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

  void _onRasterValueChanged() {
    _disableSnapshotAttempt = false;
    _childRaster?.dispose();
    _childRaster = 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();
    return image;
  }

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

/// 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`:
  ///
  /// ```dart
  /// void paint(PaintingContext context, Offset offset, Size size, ui.Image image, double pixelRatio) {
  ///   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}
  void paintSnapshot(PaintingContext context, Offset offset, Size size, ui.Image image, 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, double pixelRatio) {
    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);
  }

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

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