// 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({Key? key}) : super(key: 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;
}
