// Copyright 2018 The Chromium 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_test/flutter_test.dart';

void main() {
  test('ButtonThemeData defaults', () {
    const ButtonThemeData theme = ButtonThemeData();
    expect(theme.textTheme, ButtonTextTheme.normal);
    expect(theme.constraints, const BoxConstraints(minWidth: 88.0, minHeight: 36.0));
    expect(theme.padding, const EdgeInsets.symmetric(horizontal: 16.0));
    expect(theme.shape, const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(2.0)),
    ));
    expect(theme.alignedDropdown, false);
    expect(theme.layoutBehavior, ButtonBarLayoutBehavior.padded);
  });

  test('ButtonThemeData default overrides', () {
    const ButtonThemeData theme = ButtonThemeData(
      textTheme: ButtonTextTheme.primary,
      minWidth: 100.0,
      height: 200.0,
      padding: EdgeInsets.zero,
      shape: RoundedRectangleBorder(),
      alignedDropdown: true,
    );
    expect(theme.textTheme, ButtonTextTheme.primary);
    expect(theme.constraints, const BoxConstraints(minWidth: 100.0, minHeight: 200.0));
    expect(theme.padding, EdgeInsets.zero);
    expect(theme.shape, const RoundedRectangleBorder());
    expect(theme.alignedDropdown, true);
  });

  testWidgets('ButtonTheme defaults', (WidgetTester tester) async {
    ButtonTextTheme textTheme;
    ButtonBarLayoutBehavior layoutBehavior;
    BoxConstraints constraints;
    EdgeInsets padding;
    ShapeBorder shape;
    bool alignedDropdown;
    ColorScheme colorScheme;

    await tester.pumpWidget(
      ButtonTheme(
        child: Builder(
          builder: (BuildContext context) {
            final ButtonThemeData theme = ButtonTheme.of(context);
            textTheme = theme.textTheme;
            constraints = theme.constraints;
            padding = theme.padding;
            shape = theme.shape;
            layoutBehavior = theme.layoutBehavior;
            colorScheme = theme.colorScheme;
            alignedDropdown = theme.alignedDropdown;
            return Container(
              alignment: Alignment.topLeft,
              child: Directionality(
                textDirection: TextDirection.ltr,
                child: FlatButton(
                  onPressed: () { },
                  child: const Text('b'), // intrinsic width < minimum width
                ),
              ),
            );
          },
        ),
      ),
    );

    expect(textTheme, ButtonTextTheme.normal);
    expect(layoutBehavior, ButtonBarLayoutBehavior.padded);
    expect(constraints, const BoxConstraints(minWidth: 88.0, minHeight: 36.0));
    expect(padding, const EdgeInsets.symmetric(horizontal: 16.0));
    expect(shape, const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(2.0)),
    ));
    expect(alignedDropdown, false);
    expect(colorScheme, ThemeData.light().colorScheme);
    expect(tester.widget<Material>(find.byType(Material)).shape, shape);
    expect(tester.getSize(find.byType(Material)), const Size(88.0, 36.0));
  });

  test('ButtonThemeData.copyWith', () {
    ButtonThemeData theme = const ButtonThemeData().copyWith();
    expect(theme.textTheme, ButtonTextTheme.normal);
    expect(theme.layoutBehavior, ButtonBarLayoutBehavior.padded);
    expect(theme.constraints, const BoxConstraints(minWidth: 88.0, minHeight: 36.0));
    expect(theme.padding, const EdgeInsets.symmetric(horizontal: 16.0));
    expect(theme.shape, const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(2.0)),
    ));
    expect(theme.alignedDropdown, false);
    expect(theme.colorScheme, null);

    theme = const ButtonThemeData().copyWith(
      textTheme: ButtonTextTheme.primary,
      layoutBehavior: ButtonBarLayoutBehavior.constrained,
      minWidth: 100.0,
      height: 200.0,
      padding: EdgeInsets.zero,
      shape: const StadiumBorder(),
      alignedDropdown: true,
      colorScheme: const ColorScheme.dark(),
      materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
    );
    expect(theme.textTheme, ButtonTextTheme.primary);
    expect(theme.layoutBehavior, ButtonBarLayoutBehavior.constrained);
    expect(theme.constraints, const BoxConstraints(minWidth: 100.0, minHeight: 200.0));
    expect(theme.padding, EdgeInsets.zero);
    expect(theme.shape, const StadiumBorder());
    expect(theme.alignedDropdown, true);
    expect(theme.colorScheme, const ColorScheme.dark());
  });

  testWidgets('Theme buttonTheme defaults', (WidgetTester tester) async {
    final ThemeData lightTheme = ThemeData.light();
    ButtonTextTheme textTheme;
    BoxConstraints constraints;
    EdgeInsets padding;
    ShapeBorder shape;

    const Color disabledColor = Color(0xFF00FF00);
    await tester.pumpWidget(
      Theme(
        data: lightTheme.copyWith(
          disabledColor: disabledColor, // disabled RaisedButton fill color
          buttonTheme: const ButtonThemeData(disabledColor: disabledColor),
          textTheme: lightTheme.textTheme.copyWith(
            button: lightTheme.textTheme.button.copyWith(
              // The button's height will match because there's no
              // vertical padding by default
              fontSize: 48.0,
            ),
          ),
        ),
        child: Builder(
          builder: (BuildContext context) {
            final ButtonThemeData theme = ButtonTheme.of(context);
            textTheme = theme.textTheme;
            constraints = theme.constraints;
            padding = theme.padding;
            shape = theme.shape;
            return Container(
              alignment: Alignment.topLeft,
              child: const Directionality(
                textDirection: TextDirection.ltr,
                child: RaisedButton(
                  onPressed: null,
                  child: Text('b'), // intrinsic width < minimum width
                ),
              ),
            );
          },
        ),
      ),
    );

    expect(textTheme, ButtonTextTheme.normal);
    expect(constraints, const BoxConstraints(minWidth: 88.0, minHeight: 36.0));
    expect(padding, const EdgeInsets.symmetric(horizontal: 16.0));
    expect(shape, const RoundedRectangleBorder(
      borderRadius: BorderRadius.all(Radius.circular(2.0)),
    ));

    expect(tester.widget<Material>(find.byType(Material)).shape, shape);
    expect(tester.widget<Material>(find.byType(Material)).color, disabledColor);
    expect(tester.getSize(find.byType(Material)), const Size(88.0, 48.0));
  });

  testWidgets('Theme buttonTheme ButtonTheme overrides', (WidgetTester tester) async {
    ButtonTextTheme textTheme;
    BoxConstraints constraints;
    EdgeInsets padding;
    ShapeBorder shape;

    await tester.pumpWidget(
      Theme(
        data: ThemeData.light().copyWith(
          buttonColor: const Color(0xFF00FF00), // enabled RaisedButton fill color
        ),
        child: ButtonTheme(
          textTheme: ButtonTextTheme.primary,
          minWidth: 100.0,
          height: 200.0,
          padding: EdgeInsets.zero,
          buttonColor: const Color(0xFF00FF00), // enabled RaisedButton fill color
          shape: const RoundedRectangleBorder(),
          child: Builder(
            builder: (BuildContext context) {
              final ButtonThemeData theme = ButtonTheme.of(context);
              textTheme = theme.textTheme;
              constraints = theme.constraints;
              padding = theme.padding;
              shape = theme.shape;
              return Container(
                alignment: Alignment.topLeft,
                child: Directionality(
                  textDirection: TextDirection.ltr,
                  child: RaisedButton(
                    onPressed: () { },
                    child: const Text('b'), // intrinsic width < minimum width
                  ),
                ),
              );
            },
          ),
        ),
      ),
    );

    expect(textTheme, ButtonTextTheme.primary);
    expect(constraints, const BoxConstraints(minWidth: 100.0, minHeight: 200.0));
    expect(padding, EdgeInsets.zero);
    expect(shape, const RoundedRectangleBorder());

    expect(tester.widget<Material>(find.byType(Material)).shape, shape);
    expect(tester.widget<Material>(find.byType(Material)).color, const Color(0xFF00FF00));
    expect(tester.getSize(find.byType(Material)), const Size(100.0, 200.0));
  });

  testWidgets('ButtonTheme alignedDropdown', (WidgetTester tester) async {
    final Key dropdownKey = UniqueKey();

    Widget buildFrame({ bool alignedDropdown, TextDirection textDirection }) {
      return MaterialApp(
        builder: (BuildContext context, Widget child) {
          return Directionality(
            textDirection: textDirection,
            child: child,
          );
        },
        home: ButtonTheme(
          alignedDropdown: alignedDropdown,
          child: Material(
            child: Builder(
              builder: (BuildContext context) {
                return Container(
                  alignment: Alignment.center,
                  child: DropdownButtonHideUnderline(
                    child: Container(
                      width: 200.0,
                      child: DropdownButton<String>(
                        key: dropdownKey,
                        onChanged: (String value) { },
                        value: 'foo',
                        items: const <DropdownMenuItem<String>>[
                          DropdownMenuItem<String>(
                            value: 'foo',
                            child: Text('foo'),
                          ),
                          DropdownMenuItem<String>(
                            value: 'bar',
                            child: Text('bar'),
                          ),
                        ],
                      ),
                    ),
                  ),
                );
              },
            ),
          ),
        ),
      );
    }

    final Finder button = find.byKey(dropdownKey);
    final Finder menu = find.byWidgetPredicate((Widget w) => '${w.runtimeType}' == '_DropdownMenu<String>');

    await tester.pumpWidget(
      buildFrame(
        alignedDropdown: false,
        textDirection: TextDirection.ltr,
      ),
    );
    await tester.tap(button);
    await tester.pumpAndSettle();

    // 240 = 200.0 (button width) + _kUnalignedMenuMargin (20.0 left and right)
    expect(tester.getSize(button).width, 200.0);
    expect(tester.getSize(menu).width, 240.0);

    // Dismiss the menu.
    await tester.tapAt(Offset.zero);
    await tester.pumpAndSettle();
    expect(menu, findsNothing);

    await tester.pumpWidget(
      buildFrame(
        alignedDropdown: true,
        textDirection: TextDirection.ltr,
      ),
    );
    await tester.tap(button);
    await tester.pumpAndSettle();

    // Aligneddropdown: true means the button and menu widths match
    expect(tester.getSize(button).width, 200.0);
    expect(tester.getSize(menu).width, 200.0);

    // There are two 'foo' widgets: the selected menu item's label and the drop
    // down button's label. The should both appear at the same location.
    final Finder fooText = find.text('foo');
    expect(fooText, findsNWidgets(2));
    expect(tester.getRect(fooText.at(0)), tester.getRect(fooText.at(1)));

    // Dismiss the menu.
    await tester.tapAt(Offset.zero);
    await tester.pumpAndSettle();
    expect(menu, findsNothing);

    // Same test as above execpt RTL
    await tester.pumpWidget(
      buildFrame(
        alignedDropdown: true,
        textDirection: TextDirection.rtl,
      ),
    );
    await tester.tap(button);
    await tester.pumpAndSettle();

    expect(fooText, findsNWidgets(2));
    expect(tester.getRect(fooText.at(0)), tester.getRect(fooText.at(1)));
  });
}
