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

import 'package:flutter/material.dart';

import 'recorder.dart';

/// Creates a [PageView] that uses a font style that can't be rendered
/// using canvas (switching to DOM).
///
/// Since the whole page uses a CustomPainter this is a good representation
/// for apps that have pictures with large number of painting commands.
class BenchPageViewScrollLineThrough extends WidgetRecorder {
  BenchPageViewScrollLineThrough() : super(name: benchmarkName);

  static const String benchmarkName = 'bench_page_view_scroll_line_through';

  @override
  Widget createWidget() => const MaterialApp(
        title: 'PageView Scroll LineThrough Benchmark',
        home: _MyScrollContainer(),
      );
}

class _MyScrollContainer extends StatefulWidget {
  const _MyScrollContainer();

  @override
  State<_MyScrollContainer> createState() => _MyScrollContainerState();
}

class _MyScrollContainerState extends State<_MyScrollContainer> {
  static const Duration stepDuration = Duration(milliseconds: 500);

  late PageController pageController;
  final _CustomPainter _painter =  _CustomPainter('aa');
  int pageNumber = 0;

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

    pageController = PageController();

    // Without the timer the animation doesn't begin.
    Timer.run(() async {
      while (pageNumber < 25) {
        await pageController.animateToPage(pageNumber % 5,
            duration: stepDuration, curve: Curves.easeInOut);
        pageNumber++;
      }
    });
  }

  @override
  void dispose() {
    pageController.dispose();
    _painter._textPainter.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return PageView.builder(
        controller: pageController,
        itemBuilder: (BuildContext context, int position) {
          return CustomPaint(
            painter: _painter,
            size: const Size(300, 500),
          );
        });
  }
}

class _CustomPainter extends CustomPainter {
  _CustomPainter(this.text);

  final String text;
  final Paint _linePainter = Paint();
  final TextPainter _textPainter = TextPainter();
  static const double lineWidth = 0.5;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.clipRect(Rect.fromLTWH(0, 0, size.width, size.height));
    double xPosition, yPosition;
    final double width = size.width / 7;
    final double height = size.height / 6;
    xPosition = 0;
    const double viewPadding = 5;
    const double circlePadding = 4;
    yPosition = viewPadding;
    _textPainter.textDirection = TextDirection.ltr;
    _textPainter.textWidthBasis = TextWidthBasis.longestLine;
    _textPainter.textScaleFactor = 1;
    const TextStyle textStyle =
        TextStyle(color: Colors.black87, fontSize: 13, fontFamily: 'Roboto');

    _linePainter.isAntiAlias = true;
    for (int i = 0; i < 42; i++) {
      _linePainter.color = Colors.white;

      TextStyle temp = textStyle;
      if (i % 7 == 0) {
        temp = textStyle.copyWith(decoration: TextDecoration.lineThrough);
      }

      final TextSpan span = TextSpan(
        text: text,
        style: temp,
      );

      _textPainter.text = span;

      _textPainter.layout(maxWidth: width);
      _linePainter.style = PaintingStyle.fill;
      canvas.drawRect(
          Rect.fromLTWH(xPosition, yPosition - viewPadding, width, height),
          _linePainter);

      _textPainter.paint(
          canvas,
          Offset(xPosition + (width / 2 - _textPainter.width / 2),
              yPosition + circlePadding));
      xPosition += width;
      if (xPosition.round() >= size.width.round()) {
        xPosition = 0;
        yPosition += height;
      }
    }

    _drawVerticalAndHorizontalLines(
        canvas, size, yPosition, xPosition, height, width);
  }

  void _drawVerticalAndHorizontalLines(Canvas canvas, Size size,
      double yPosition, double xPosition, double height, double width) {
    yPosition = height;
    _linePainter.strokeWidth = lineWidth;
    _linePainter.color = Colors.grey;
    canvas.drawLine(const Offset(0, lineWidth), Offset(size.width, lineWidth),
        _linePainter);
    for (int i = 0; i < 6; i++) {
      canvas.drawLine(
          Offset(0, yPosition), Offset(size.width, yPosition), _linePainter);
      yPosition += height;
    }

    canvas.drawLine(Offset(0, size.height - lineWidth),
        Offset(size.width, size.height - lineWidth), _linePainter);
    xPosition = width;
    canvas.drawLine(const Offset(lineWidth, 0), Offset(lineWidth, size.height),
        _linePainter);
    for (int i = 0; i < 6; i++) {
      canvas.drawLine(
          Offset(xPosition, 0), Offset(xPosition, size.height), _linePainter);
      xPosition += width;
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
