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

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.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 {
  @override
  _ColorFilterAndFadePageState 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;
                    });
                  },
                ),
              ],
            ),
        ),
    );
  }

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

  AnimationController _controller;
  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,
        willChange: false,
      ),
    );
  }
}

class _ShadowPainter extends CustomPainter {
  const _ShadowPainter({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;
}
