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

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

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

  PageController pageController;
  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() {
    super.dispose();
    pageController.dispose();
  }

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

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

  final String text;
  Paint _linePainter;
  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 = _textPainter ?? TextPainter();
    _textPainter.textDirection = TextDirection.ltr;
    _textPainter.textWidthBasis = TextWidthBasis.longestLine;
    _textPainter.textScaleFactor = 1;
    const TextStyle textStyle =
        TextStyle(color: Colors.black87, fontSize: 13, fontFamily: 'Roboto');

    _linePainter = _linePainter ?? Paint();
    _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(minWidth: 0, 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;
  }
}
