// 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/material.dart';

// This tests whether the Opacity layer raster cache works with color filters.
// See https://github.com/flutter/flutter/issues/51975.
class ColorFilterAndFadePage extends StatefulWidget {
  const ColorFilterAndFadePage({super.key});

  @override
  State<ColorFilterAndFadePage> createState() => _ColorFilterAndFadePageState();
}

class _ColorFilterAndFadePageState extends State<ColorFilterAndFadePage> with TickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    final Widget shadowWidget = _ShadowWidget(
      width: 24,
      height: 24,
      useColorFilter: _useColorFilter,
      shadow: const ui.Shadow(
        color: Colors.black45,
        offset: Offset(0.0, 2.0),
        blurRadius: 4.0,
      ),
    );

    final Widget row = Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        shadowWidget,
        const SizedBox(width: 12),
        shadowWidget,
        const SizedBox(width: 12),
        shadowWidget,
        const SizedBox(width: 12),
        shadowWidget,
        const SizedBox(width: 12),
        shadowWidget,
        const SizedBox(width: 12),
      ],
    );

    final Widget column = Column(mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          row,
          const SizedBox(height: 12),
          row,
          const SizedBox(height: 12),
          row,
          const SizedBox(height: 12),
          row,
          const SizedBox(height: 12),
        ],
    );

    final Widget fadeTransition = FadeTransition(
      opacity: _opacityAnimation,
      // This RepaintBoundary is necessary to not let the opacity change
      // invalidate the layer raster cache below. This is necessary with
      // or without the color filter.
      child: RepaintBoundary(
        child: column,
      ),
    );

    return Scaffold(
        backgroundColor: Colors.lightBlue,
        body: Center(
            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                fadeTransition,
                Container(height: 20),
                const Text('Use Color Filter:'),
                Checkbox(
                  value: _useColorFilter,
                  onChanged: (bool? value) {
                    setState(() {
                      _useColorFilter = value ?? false;
                    });
                  },
                ),
              ],
            ),
        ),
    );
  }

  // Create a looping fade-in fade-out animation for opacity.
  void _initAnimation() {
    _controller = AnimationController(duration: const Duration(seconds: 3), vsync: this);
    _opacityAnimation = Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
    _opacityAnimation.addStatusListener((AnimationStatus status) {
      if (status == AnimationStatus.completed) {
        _controller.reverse();
      } else if (status == AnimationStatus.dismissed) {
        _controller.forward();
      }
    });
    _controller.forward();
  }

  @override
  void initState() {
    super.initState();
    _initAnimation();
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  late AnimationController _controller;
  late Animation<double> _opacityAnimation;
  bool _useColorFilter = true;
}

class _ShadowWidget extends StatelessWidget {
  const _ShadowWidget({
    required this.width,
    required this.height,
    required this.useColorFilter,
    required this.shadow,
  });

  final double width;
  final double height;
  final bool useColorFilter;
  final Shadow shadow;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: width,
      height: height,
      child: CustomPaint(
        painter: _ShadowPainter(
          useColorFilter: useColorFilter,
          shadow: shadow,
        ),
        size: Size(width, height),
        isComplex: true,
      ),
    );
  }
}

class _ShadowPainter extends CustomPainter {
  const _ShadowPainter({required this.useColorFilter, required this.shadow});

  final bool useColorFilter;
  final Shadow shadow;

  @override
  void paint(Canvas canvas, Size size) {
    final Rect rect = Offset.zero & size;

    final Paint paint = Paint();
    if (useColorFilter) {
      paint.colorFilter = ColorFilter.mode(shadow.color, BlendMode.srcIn);
    }

    canvas.saveLayer(null, paint);
    canvas.translate(shadow.offset.dx, shadow.offset.dy);
    canvas.drawRect(rect, Paint());
    canvas.drawRect(rect, Paint()..maskFilter = MaskFilter.blur(BlurStyle.normal, shadow.blurSigma));
    canvas.restore();

    canvas.drawRect(rect, Paint()..color = useColorFilter ? Colors.white : Colors.black);
  }

  @override
  bool shouldRepaint(_ShadowPainter oldDelegate) => oldDelegate.useColorFilter != useColorFilter;
}
