// 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 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';

import 'framework.dart';

/// Applies an [ImageFilter] to its child.
///
/// An image filter will always apply its filter operation to the child widget,
/// even if said filter is conceptually a "no-op", such as an ImageFilter.blur
/// with a radius of 0 or an ImageFilter.matrix with an identity matrix. Setting
/// [ImageFiltered.enabled] to `false` is a more efficient manner of disabling
/// an image filter.
///
/// The framework does not attempt to optimize out "no-op" filters because it
/// cannot tell the difference between an intentional no-op and a filter that is
/// only incidentally a no-op. Consider an ImageFilter.matrix that is animated
/// and happens to pass through the identity matrix. If the framework identified it
/// as a no-op it would drop and then recreate the layer during the animation which
/// would be more expensive than keeping it around.
///
/// {@youtube 560 315 https://www.youtube.com/watch?v=7Lftorq4i2o}
///
/// See also:
///
/// * [BackdropFilter], which applies an [ImageFilter] to everything
///   beneath its child.
/// * [ColorFiltered], which applies a [ColorFilter] to its child.
@immutable
class ImageFiltered extends SingleChildRenderObjectWidget {
  /// Creates a widget that applies an [ImageFilter] to its child.
  ///
  /// The [imageFilter] must not be null.
  const ImageFiltered({
    super.key,
    required this.imageFilter,
    super.child,
    this.enabled = true,
  }) : assert(imageFilter != null);

  /// The image filter to apply to the child of this widget.
  final ImageFilter imageFilter;

  /// Whether or not to apply the image filter operation to the child of this
  /// widget.
  ///
  /// Prefer setting enabled to `false` instead of creating a "no-op" filter
  /// type for performance reasons.
  final bool enabled;

  @override
  RenderObject createRenderObject(BuildContext context) => _ImageFilterRenderObject(imageFilter, enabled);

  @override
  void updateRenderObject(BuildContext context, RenderObject renderObject) {
    (renderObject as _ImageFilterRenderObject)
      ..enabled = enabled
      ..imageFilter = imageFilter;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DiagnosticsProperty<ImageFilter>('imageFilter', imageFilter));
  }
}

class _ImageFilterRenderObject extends RenderProxyBox {
  _ImageFilterRenderObject(this._imageFilter, this._enabled);

  bool get enabled => _enabled;
  bool _enabled;
  set enabled(bool value) {
    if (enabled == value) {
      return;
    }
    _enabled = value;
    markNeedsPaint();
  }

  ImageFilter get imageFilter => _imageFilter;
  ImageFilter _imageFilter;
  set imageFilter(ImageFilter value) {
    assert(value != null);
    if (value != _imageFilter) {
      _imageFilter = value;
      markNeedsPaint();
    }
  }

  @override
  bool get alwaysNeedsCompositing => child != null && enabled;

  @override
  void paint(PaintingContext context, Offset offset) {
    assert(imageFilter != null);
    if (!enabled) {
      layer = null;
      return super.paint(context, offset);
    }

    if (layer == null) {
      layer = ImageFilterLayer(imageFilter: imageFilter);
    } else {
      final ImageFilterLayer filterLayer = layer! as ImageFilterLayer;
      filterLayer.imageFilter = imageFilter;
    }
    context.pushLayer(layer!, super.paint, offset);
    assert(() {
      layer!.debugCreator = debugCreator;
      return true;
    }());
  }
}
