// 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 'package:flutter/material.dart';
import 'package:flutter_driver/driver_extension.dart';

/// This sample application creates a hard to render frame, causing the
/// driver script to race the raster thread. If the driver script wins the
/// race, it will screenshot the previous frame. If the raster thread wins
/// it, it will screenshot the latest frame.
void main() {
  enableFlutterDriverExtension();

  runApp(const Toggler());
}

class Toggler extends StatefulWidget {
  const Toggler({Key key}) : super(key: key);

  @override
  State<Toggler> createState() => TogglerState();
}

class TogglerState extends State<Toggler> {
  bool _visible = false;

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: const Text('FlutterDriver test'),
        ),
        body: Material(
          child: Column(
            children: <Widget>[
              TextButton(
                key: const ValueKey<String>('toggle'),
                child: const Text('Toggle visibility'),
                onPressed: () {
                  setState(() {
                    _visible = !_visible;
                  });
                },
              ),
              Expanded(
                child: ListView(
                  children: _buildRows(_visible ? 10 : 0),
                ),
              ),
            ],
          ),
        ),
      ),
    );
  }
}

List<Widget> _buildRows(int count) {
  return List<Widget>.generate(count, (int i) {
    return Row(
      children: _buildCells(i / count),
    );
  });
}

/// Builds cells that are known to take time to render causing a delay on the
/// raster thread.
List<Widget> _buildCells(double epsilon) {
  return List<Widget>.generate(15, (int i) {
    return Expanded(
      child: Material(
        // A magic color that the test will be looking for on the screenshot.
        color: const Color(0xffff0102),
        borderRadius: BorderRadius.all(Radius.circular(i.toDouble() + epsilon)),
        elevation: 5.0,
        child: const SizedBox(height: 10.0, width: 10.0),
      ),
    );
  });
}
