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

import 'package:flutter/material.dart';

// Based on https://github.com/eseidelGoogle/bezier_perf/blob/master/lib/main.dart
class CubicBezierPage extends StatelessWidget {
  const CubicBezierPage({super.key});

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: const <Widget>[
          Bezier(Colors.amber, 1.0),
        ],
      ),
    );
  }
}

class Bezier extends StatelessWidget {
  const Bezier(this.color, this.scale, {super.key, this.blur = 0.0, this.delay = 0.0});

  final Color color;
  final double scale;
  final double blur;
  final double delay;

  List<PathDetail> _getLogoPath() {
    final List<PathDetail> paths = <PathDetail>[];

    final Path path = Path();
    path.moveTo(100.0, 97.0);
    path.cubicTo(100.0, 97.0, 142.0, 59.0, 169.91, 41.22);
    path.cubicTo(197.82, 23.44, 249.24, 5.52, 204.67, 85.84);

    paths.add(PathDetail(path));

    // Path 2
    final Path bezier2Path = Path();
    bezier2Path.moveTo(0.0, 70.55);
    bezier2Path.cubicTo(0.0, 70.55, 42.0, 31.55, 69.91, 14.77);
    bezier2Path.cubicTo(97.82, -2.01, 149.24, -20.93, 104.37, 59.39);

    paths.add(PathDetail(bezier2Path,
        translate: <double>[29.45, 151.0], rotation: -1.5708));

    // Path 3
    final Path bezier3Path = Path();
    bezier3Path.moveTo(0.0, 69.48);
    bezier3Path.cubicTo(0.0, 69.48, 44.82, 27.92, 69.91, 13.7);
    bezier3Path.cubicTo(95.0, -0.52, 149.24, -22.0, 104.37, 58.32);

    paths.add(PathDetail(bezier3Path,
        translate: <double>[53.0, 200.48], rotation: -3.14159));

    // Path 4
    final Path bezier4Path = Path();
    bezier4Path.moveTo(0.0, 69.48);
    bezier4Path.cubicTo(0.0, 69.48, 43.82, 27.92, 69.91, 13.7);
    bezier4Path.cubicTo(96.0, -0.52, 149.24, -22.0, 104.37, 58.32);

    paths.add(PathDetail(bezier4Path,
        translate: <double>[122.48, 77.0], rotation: -4.71239));

    return paths;
  }

  @override
  Widget build(BuildContext context) {
    return Stack(children: <Widget>[
      CustomPaint(
        foregroundPainter:
        BezierPainter(Colors.grey, 0.0, _getLogoPath(), false),
        size: const Size(100.0, 100.0),
      ),
      AnimatedBezier(color, scale, blur: blur),
    ]);
  }
}

class PathDetail {
  PathDetail(this.path, {this.translate, this.rotation});

  Path path;
  List<double>? translate = <double>[];
  double? rotation;
}

class AnimatedBezier extends StatefulWidget {
  const AnimatedBezier(this.color, this.scale, {super.key, this.blur = 0.0});

  final Color color;
  final double scale;
  final double blur;

  @override
  State createState() => AnimatedBezierState();
}

class Point {
  Point(this.x, this.y);

  double x;
  double y;
}

class AnimatedBezierState extends State<AnimatedBezier>
    with SingleTickerProviderStateMixin {
  late AnimationController controller;
  late CurvedAnimation curve;
  bool isPlaying = false;
  List<List<Point>> pointList = <List<Point>>[
    <Point>[],
    <Point>[],
    <Point>[],
    <Point>[],
  ];
  bool isReversed = false;

  List<PathDetail> _playForward() {
    final List<PathDetail> paths = <PathDetail>[];
    final double t = curve.value;
    final double b = controller.upperBound;
    double pX;
    double pY;

    final Path path = Path();

    if (t < b / 2) {
      pX = _getCubicPoint(t * 2, 100.0, 100.0, 142.0, 169.91);
      pY = _getCubicPoint(t * 2, 97.0, 97.0, 59.0, 41.22);
      pointList[0].add(Point(pX, pY));
    } else {
      pX = _getCubicPoint(t * 2 - b, 169.91, 197.80, 249.24, 204.67);
      pY = _getCubicPoint(t * 2 - b, 41.22, 23.44, 5.52, 85.84);
      pointList[0].add(Point(pX, pY));
    }

    path.moveTo(100.0, 97.0);

    for (final Point p in pointList[0]) {
      path.lineTo(p.x, p.y);
    }

    paths.add(PathDetail(path));

    // Path 2
    final Path bezier2Path = Path();

    if (t <= b / 2) {
      final double pX = _getCubicPoint(t * 2, 0.0, 0.0, 42.0, 69.91);
      final double pY = _getCubicPoint(t * 2, 70.55, 70.55, 31.55, 14.77);
      pointList[1].add(Point(pX, pY));
    } else {
      final double pX = _getCubicPoint(t * 2 - b, 69.91, 97.82, 149.24, 104.37);
      final double pY = _getCubicPoint(t * 2 - b, 14.77, -2.01, -20.93, 59.39);
      pointList[1].add(Point(pX, pY));
    }

    bezier2Path.moveTo(0.0, 70.55);

    for (final Point p in pointList[1]) {
      bezier2Path.lineTo(p.x, p.y);
    }

    paths.add(PathDetail(bezier2Path,
        translate: <double>[29.45, 151.0], rotation: -1.5708));

    // Path 3
    final Path bezier3Path = Path();
    if (t <= b / 2) {
      pX = _getCubicPoint(t * 2, 0.0, 0.0, 44.82, 69.91);
      pY = _getCubicPoint(t * 2, 69.48, 69.48, 27.92, 13.7);
      pointList[2].add(Point(pX, pY));
    } else {
      pX = _getCubicPoint(t * 2 - b, 69.91, 95.0, 149.24, 104.37);
      pY = _getCubicPoint(t * 2 - b, 13.7, -0.52, -22.0, 58.32);
      pointList[2].add(Point(pX, pY));
    }

    bezier3Path.moveTo(0.0, 69.48);

    for (final Point p in pointList[2]) {
      bezier3Path.lineTo(p.x, p.y);
    }

    paths.add(PathDetail(bezier3Path,
        translate: <double>[53.0, 200.48], rotation: -3.14159));

    // Path 4
    final Path bezier4Path = Path();

    if (t < b / 2) {
      final double pX = _getCubicPoint(t * 2, 0.0, 0.0, 43.82, 69.91);
      final double pY = _getCubicPoint(t * 2, 69.48, 69.48, 27.92, 13.7);
      pointList[3].add(Point(pX, pY));
    } else {
      final double pX = _getCubicPoint(t * 2 - b, 69.91, 96.0, 149.24, 104.37);
      final double pY = _getCubicPoint(t * 2 - b, 13.7, -0.52, -22.0, 58.32);
      pointList[3].add(Point(pX, pY));
    }

    bezier4Path.moveTo(0.0, 69.48);

    for (final Point p in pointList[3]) {
      bezier4Path.lineTo(p.x, p.y);
    }

    paths.add(PathDetail(bezier4Path,
        translate: <double>[122.48, 77.0], rotation: -4.71239));

    return paths;
  }

  List<PathDetail> _playReversed() {
    for (final List<Point> list in pointList) {
      if (list.isNotEmpty) {
        list.removeLast();
      }
    }

    final List<Point> points = pointList[0];
    final Path path = Path();

    path.moveTo(100.0, 97.0);

    for (final Point point in points) {
      path.lineTo(point.x, point.y);
    }

    final Path bezier2Path = Path();

    bezier2Path.moveTo(0.0, 70.55);

    for (final Point p in pointList[1]) {
      bezier2Path.lineTo(p.x, p.y);
    }

    final Path bezier3Path = Path();
    bezier3Path.moveTo(0.0, 69.48);

    for (final Point p in pointList[2]) {
      bezier3Path.lineTo(p.x, p.y);
    }

    final Path bezier4Path = Path();

    bezier4Path.moveTo(0.0, 69.48);

    for (final Point p in pointList[3]) {
      bezier4Path.lineTo(p.x, p.y);
    }

    return <PathDetail>[
      PathDetail(path),
      PathDetail(bezier2Path, translate: <double>[29.45, 151.0], rotation: -1.5708),
      PathDetail(bezier3Path,
          translate: <double>[53.0, 200.48], rotation: -3.14159),
      PathDetail(bezier4Path, translate: <double>[122.48, 77.0], rotation: -4.71239),
    ];
  }

  List<PathDetail> _getLogoPath() {
    if (!isReversed) {
      return _playForward();
    }

    return _playReversed();
  }

  //From http://wiki.roblox.com/index.php?title=File:Beziereq4.png
  double _getCubicPoint(double t, double p0, double p1, double p2, double p3) {
    return (pow(1 - t, 3) as double) * p0 +
        3 * pow(1 - t, 2) * t * p1 +
        3 * (1 - t) * pow(t, 2) * p2 +
        pow(t, 3) * p3;
  }

  void playAnimation() {
    isPlaying = true;
    isReversed = false;
    for (final List<Point> list in pointList) {
      list.clear();
    }
    controller.reset();
    controller.forward();
  }

  void stopAnimation() {
    isPlaying = false;
    controller.stop();
    for (final List<Point> list in pointList) {
      list.clear();
    }
  }

  void reverseAnimation() {
    isReversed = true;
    controller.reverse();
  }

  @override
  void initState() {
    super.initState();
    controller = AnimationController(
        vsync: this, duration: const Duration(milliseconds: 1000));
    // Animations are typically implemented using the AnimatedBuilder widget.
    // This code uses a manual listener for historical reasons and will remain
    // in order to preserve compatibility with the history of measurements for
    // this benchmark.
    curve = CurvedAnimation(parent: controller, curve: Curves.linear)
      ..addListener(() {
        setState(() {});
      })
      ..addStatusListener((AnimationStatus state) {
        if (state == AnimationStatus.completed) {
          reverseAnimation();
        } else if (state == AnimationStatus.dismissed) {
          playAnimation();
        }
      });

    playAnimation();
  }

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

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
        foregroundPainter: BezierPainter(widget.color,
            curve.value * widget.blur, _getLogoPath(), isPlaying),
        size: const Size(100.0, 100.0));
  }
}

class BezierPainter extends CustomPainter {
  BezierPainter(this.color, this.blur, this.path, this.isPlaying);

  Color color;
  final double blur;
  List<PathDetail> path;
  bool isPlaying;

  @override
  void paint(Canvas canvas, Size size) {
    final Paint paint = Paint();
    paint.strokeWidth = 18.0;
    paint.style = PaintingStyle.stroke;
    paint.strokeCap = StrokeCap.round;
    paint.color = color;
    canvas.scale(0.5, 0.5);

    for (int i = 0; i < path.length; i++) {
      if (path[i].translate != null) {
        canvas.translate(path[i].translate![0], path[i].translate![1]);
      }

      if (path[i].rotation != null) {
        canvas.rotate(path[i].rotation!);
      }

      if (blur > 0) {
        final MaskFilter blur = MaskFilter.blur(BlurStyle.normal, this.blur);
        paint.maskFilter = blur;
        canvas.drawPath(path[i].path, paint);
      }

      paint.maskFilter = null;
      canvas.drawPath(path[i].path, paint);
    }
  }

  @override
  bool shouldRepaint(BezierPainter oldDelegate) => true;

  @override
  bool shouldRebuildSemantics(BezierPainter oldDelegate) => false;
}
