// 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({Key? key}) : super(key: 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, {Key? key, this.blur = 0.0, this.delay = 0.0}) : super(key: key);

  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, {Key? key, this.blur = 0.0}) : super(key: key);

  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;
}
