// 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.

// @dart = 2.8

import 'package:flutter/widgets.dart';
import 'package:flutter/rendering.dart';

import 'button_bar_theme.dart';
import 'button_theme.dart';
import 'dialog.dart';
import 'flat_button.dart';
import 'raised_button.dart';

/// An end-aligned row of buttons, laying out into a column if there is not
/// enough horizontal space.
///
/// Places the buttons horizontally according to the [buttonPadding]. The
/// children are laid out in a [Row] with [MainAxisAlignment.end]. When the
/// [Directionality] is [TextDirection.ltr], the button bar's children are
/// right justified and the last child becomes the rightmost child. When the
/// [Directionality] [TextDirection.rtl] the children are left justified and
/// the last child becomes the leftmost child.
///
/// If the button bar's width exceeds the maximum width constraint on the
/// widget, it aligns its buttons in a column. The key difference here
/// is that the [MainAxisAlignment] will then be treated as a
/// cross-axis/horizontal alignment. For example, if the buttons overflow and
/// [ButtonBar.alignment] was set to [MainAxisAlignment.start], the buttons would
/// align to the horizontal start of the button bar.
///
/// The [ButtonBar] can be configured with a [ButtonBarTheme]. For any null
/// property on the ButtonBar, the surrounding ButtonBarTheme's property
/// will be used instead. If the ButtonBarTheme's property is null
/// as well, the property will default to a value described in the field
/// documentation below.
///
/// The [children] are wrapped in a [ButtonTheme] that is a copy of the
/// surrounding ButtonTheme with the button properties overridden by the
/// properties of the ButtonBar as described above. These properties include
/// [buttonTextTheme], [buttonMinWidth], [buttonHeight], [buttonPadding],
/// and [buttonAlignedDropdown].
///
/// Used by [Dialog] to arrange the actions at the bottom of the dialog.
///
/// See also:
///
///  * [RaisedButton], a kind of button.
///  * [FlatButton], another kind of button.
///  * [Card], at the bottom of which it is common to place a [ButtonBar].
///  * [Dialog], which uses a [ButtonBar] for its actions.
///  * [ButtonBarTheme], which configures the [ButtonBar].
class ButtonBar extends StatelessWidget {
  /// Creates a button bar.
  ///
  /// Both [buttonMinWidth] and [buttonHeight] must be non-negative if they
  /// are not null.
  const ButtonBar({
    Key key,
    this.alignment,
    this.mainAxisSize,
    this.buttonTextTheme,
    this.buttonMinWidth,
    this.buttonHeight,
    this.buttonPadding,
    this.buttonAlignedDropdown,
    this.layoutBehavior,
    this.overflowDirection,
    this.overflowButtonSpacing,
    this.children = const <Widget>[],
  }) : assert(buttonMinWidth == null || buttonMinWidth >= 0.0),
       assert(buttonHeight == null || buttonHeight >= 0.0),
       assert(overflowButtonSpacing == null || overflowButtonSpacing >= 0.0),
       super(key: key);

  /// How the children should be placed along the horizontal axis.
  ///
  /// If null then it will use [ButtonBarTheme.alignment]. If that is null,
  /// it will default to [MainAxisAlignment.end].
  final MainAxisAlignment alignment;

  /// How much horizontal space is available. See [Row.mainAxisSize].
  ///
  /// If null then it will use the surrounding [ButtonBarTheme.mainAxisSize].
  /// If that is null, it will default to [MainAxisSize.max].
  final MainAxisSize mainAxisSize;

  /// Overrides the surrounding [ButtonTheme.textTheme] to define a button's
  /// base colors, size, internal padding and shape.
  ///
  /// If null then it will use the surrounding [ButtonBarTheme.buttonTextTheme].
  /// If that is null, it will default to [ButtonTextTheme.primary].
  final ButtonTextTheme buttonTextTheme;

  /// Overrides the surrounding [ButtonThemeData.minWidth] to define a button's
  /// minimum width.
  ///
  /// If null then it will use the surrounding [ButtonBarTheme.buttonMinWidth].
  /// If that is null, it will default to 64.0 logical pixels.
  final double buttonMinWidth;

  /// Overrides the surrounding [ButtonThemeData.height] to define a button's
  /// minimum height.
  ///
  /// If null then it will use the surrounding [ButtonBarTheme.buttonHeight].
  /// If that is null, it will default to 36.0 logical pixels.
  final double buttonHeight;

  /// Overrides the surrounding [ButtonThemeData.padding] to define the padding
  /// for a button's child (typically the button's label).
  ///
  /// If null then it will use the surrounding [ButtonBarTheme.buttonPadding].
  /// If that is null, it will default to 8.0 logical pixels on the left
  /// and right.
  final EdgeInsetsGeometry buttonPadding;

  /// Overrides the surrounding [ButtonThemeData.alignedDropdown] to define whether
  /// a [DropdownButton] menu's width will match the button's width.
  ///
  /// If null then it will use the surrounding [ButtonBarTheme.buttonAlignedDropdown].
  /// If that is null, it will default to false.
  final bool buttonAlignedDropdown;

  /// Defines whether a [ButtonBar] should size itself with a minimum size
  /// constraint or with padding.
  ///
  /// Overrides the surrounding [ButtonThemeData.layoutBehavior].
  ///
  /// If null then it will use the surrounding [ButtonBarTheme.layoutBehavior].
  /// If that is null, it will default [ButtonBarLayoutBehavior.padded].
  final ButtonBarLayoutBehavior layoutBehavior;

  /// Defines the vertical direction of a [ButtonBar]'s children if it
  /// overflows.
  ///
  /// If [children] do not fit into a single row, then they
  /// are arranged in a column. The first action is at the top of the
  /// column if this property is set to [VerticalDirection.down], since it
  /// "starts" at the top and "ends" at the bottom. On the other hand,
  /// the first action will be at the bottom of the column if this
  /// property is set to [VerticalDirection.up], since it "starts" at the
  /// bottom and "ends" at the top.
  ///
  /// If null then it will use the surrounding
  /// [ButtonBarTheme.overflowDirection]. If that is null, it will
  /// default to [VerticalDirection.down].
  final VerticalDirection overflowDirection;

  /// The spacing between buttons when the button bar overflows.
  ///
  /// If the [children] do not fit into a single row, they are
  /// arranged into a column. This parameter provides additional
  /// vertical space in between buttons when it does overflow.
  ///
  /// Note that the button spacing may appear to be more than
  /// the value provided. This is because most buttons adhere to the
  /// [MaterialTapTargetSize] of 48px. So, even though a button
  /// might visually be 36px in height, it might still take up to
  /// 48px vertically.
  ///
  /// If null then no spacing will be added in between buttons in
  /// an overflow state.
  final double overflowButtonSpacing;

  /// The buttons to arrange horizontally.
  ///
  /// Typically [RaisedButton] or [FlatButton] widgets.
  final List<Widget> children;

  @override
  Widget build(BuildContext context) {
    final ButtonThemeData parentButtonTheme = ButtonTheme.of(context);
    final ButtonBarThemeData barTheme = ButtonBarTheme.of(context);

    final ButtonThemeData buttonTheme = parentButtonTheme.copyWith(
      textTheme: buttonTextTheme ?? barTheme.buttonTextTheme ?? ButtonTextTheme.primary,
      minWidth: buttonMinWidth ?? barTheme.buttonMinWidth ?? 64.0,
      height: buttonHeight ?? barTheme.buttonHeight ?? 36.0,
      padding: buttonPadding ?? barTheme.buttonPadding ?? const EdgeInsets.symmetric(horizontal: 8.0),
      alignedDropdown: buttonAlignedDropdown ?? barTheme.buttonAlignedDropdown ?? false,
      layoutBehavior: layoutBehavior ?? barTheme.layoutBehavior ?? ButtonBarLayoutBehavior.padded,
    );

    // We divide by 4.0 because we want half of the average of the left and right padding.
    final double paddingUnit = buttonTheme.padding.horizontal / 4.0;
    final Widget child = ButtonTheme.fromButtonThemeData(
      data: buttonTheme,
      child: _ButtonBarRow(
        mainAxisAlignment: alignment ?? barTheme.alignment ?? MainAxisAlignment.end,
        mainAxisSize: mainAxisSize ?? barTheme.mainAxisSize ?? MainAxisSize.max,
        overflowDirection: overflowDirection ?? barTheme.overflowDirection ?? VerticalDirection.down,
        children: children.map<Widget>((Widget child) {
          return Padding(
            padding: EdgeInsets.symmetric(horizontal: paddingUnit),
            child: child,
          );
        }).toList(),
        overflowButtonSpacing: overflowButtonSpacing,
      ),
    );
    switch (buttonTheme.layoutBehavior) {
      case ButtonBarLayoutBehavior.padded:
        return Padding(
          padding: EdgeInsets.symmetric(
            vertical: 2.0 * paddingUnit,
            horizontal: paddingUnit,
          ),
          child: child,
        );
      case ButtonBarLayoutBehavior.constrained:
        return Container(
          padding: EdgeInsets.symmetric(horizontal: paddingUnit),
          constraints: const BoxConstraints(minHeight: 52.0),
          alignment: Alignment.center,
          child: child,
        );
    }
    assert(false);
    return null;
  }
}

/// Attempts to display buttons in a row, but displays them in a column if
/// there is not enough horizontal space.
///
/// It first attempts to lay out its buttons as though there were no
/// maximum width constraints on the widget. If the button bar's width is
/// less than the maximum width constraints of the widget, it then lays
/// out the widget as though it were placed in a [Row].
///
/// However, if the button bar's width exceeds the maximum width constraint on
/// the widget, it then aligns its buttons in a column. The key difference here
/// is that the [MainAxisAlignment] will then be treated as a
/// cross-axis/horizontal alignment. For example, if the buttons overflow and
/// [ButtonBar.alignment] was set to [MainAxisAlignment.start], the column of
/// buttons would align to the horizontal start of the button bar.
class _ButtonBarRow extends Flex {
  /// Creates a button bar that attempts to display in a row, but displays in
  /// a column if there is insufficient horizontal space.
  _ButtonBarRow({
    List<Widget> children,
    Axis direction = Axis.horizontal,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    TextDirection textDirection,
    VerticalDirection overflowDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    this.overflowButtonSpacing,
  }) : super(
    children: children,
    direction: direction,
    mainAxisSize: mainAxisSize,
    mainAxisAlignment: mainAxisAlignment,
    crossAxisAlignment: crossAxisAlignment,
    textDirection: textDirection,
    verticalDirection: overflowDirection,
    textBaseline: textBaseline,
  );

  final double overflowButtonSpacing;

  @override
  _RenderButtonBarRow createRenderObject(BuildContext context) {
    return _RenderButtonBarRow(
      direction: direction,
      mainAxisAlignment: mainAxisAlignment,
      mainAxisSize: mainAxisSize,
      crossAxisAlignment: crossAxisAlignment,
      textDirection: getEffectiveTextDirection(context),
      verticalDirection: verticalDirection,
      textBaseline: textBaseline,
      overflowButtonSpacing: overflowButtonSpacing,
    );
  }

  @override
  void updateRenderObject(BuildContext context, covariant _RenderButtonBarRow renderObject) {
    renderObject
      ..direction = direction
      ..mainAxisAlignment = mainAxisAlignment
      ..mainAxisSize = mainAxisSize
      ..crossAxisAlignment = crossAxisAlignment
      ..textDirection = getEffectiveTextDirection(context)
      ..verticalDirection = verticalDirection
      ..textBaseline = textBaseline
      ..overflowButtonSpacing = overflowButtonSpacing;
  }
}

/// Attempts to display buttons in a row, but displays them in a column if
/// there is not enough horizontal space.
///
/// It first attempts to lay out its buttons as though there were no
/// maximum width constraints on the widget. If the button bar's width is
/// less than the maximum width constraints of the widget, it then lays
/// out the widget as though it were placed in a [Row].
///
/// However, if the button bar's width exceeds the maximum width constraint on
/// the widget, it then aligns its buttons in a column. The key difference here
/// is that the [MainAxisAlignment] will then be treated as a
/// cross-axis/horizontal alignment. For example, if the buttons overflow and
/// [ButtonBar.alignment] was set to [MainAxisAlignment.start], the buttons would
/// align to the horizontal start of the button bar.
class _RenderButtonBarRow extends RenderFlex {
  /// Creates a button bar that attempts to display in a row, but displays in
  /// a column if there is insufficient horizontal space.
  _RenderButtonBarRow({
    List<RenderBox> children,
    Axis direction = Axis.horizontal,
    MainAxisSize mainAxisSize = MainAxisSize.max,
    MainAxisAlignment mainAxisAlignment = MainAxisAlignment.start,
    CrossAxisAlignment crossAxisAlignment = CrossAxisAlignment.center,
    @required TextDirection textDirection,
    VerticalDirection verticalDirection = VerticalDirection.down,
    TextBaseline textBaseline,
    this.overflowButtonSpacing,
  }) : assert(textDirection != null),
       assert(overflowButtonSpacing == null || overflowButtonSpacing >= 0),
       super(
         children: children,
         direction: direction,
         mainAxisSize: mainAxisSize,
         mainAxisAlignment: mainAxisAlignment,
         crossAxisAlignment: crossAxisAlignment,
         textDirection: textDirection,
         verticalDirection: verticalDirection,
         textBaseline: textBaseline,
       );

  bool _hasCheckedLayoutWidth = false;
  double overflowButtonSpacing;

  @override
  BoxConstraints get constraints {
    if (_hasCheckedLayoutWidth)
      return super.constraints;
    return super.constraints?.copyWith(maxWidth: double.infinity);
  }

  @override
  void performLayout() {
    // Set check layout width to false in reload or update cases.
    _hasCheckedLayoutWidth = false;

    // Perform layout to ensure that button bar knows how wide it would
    // ideally want to be.
    super.performLayout();
    _hasCheckedLayoutWidth = true;

    // If the button bar is constrained by width and it overflows, set the
    // buttons to align vertically. Otherwise, lay out the button bar
    // horizontally.
    if (size.width <= constraints.maxWidth) {
      // A second performLayout is required to ensure that the original maximum
      // width constraints are used. The original perform layout call assumes
      // a maximum width constraint of infinity.
      super.performLayout();
    } else {
      final BoxConstraints childConstraints = constraints.copyWith(minWidth: 0.0);
      RenderBox child;
      double currentHeight = 0.0;
      switch (verticalDirection) {
        case VerticalDirection.down:
          child = firstChild;
          break;
        case VerticalDirection.up:
          child = lastChild;
          break;
      }

      while (child != null) {
        final FlexParentData childParentData = child.parentData as FlexParentData;

        // Lay out the child with the button bar's original constraints, but
        // with minimum width set to zero.
        child.layout(childConstraints, parentUsesSize: true);

        // Set the cross axis alignment for the column to match the main axis
        // alignment for a row. For [MainAxisAlignment.spaceAround],
        // [MainAxisAlignment.spaceBetween] and [MainAxisAlignment.spaceEvenly]
        // cases, use [MainAxisAlignment.start].
        switch (textDirection) {
          case TextDirection.ltr:
            switch (mainAxisAlignment) {
              case MainAxisAlignment.center:
                final double midpoint = (constraints.maxWidth - child.size.width) / 2.0;
                childParentData.offset = Offset(midpoint, currentHeight);
                break;
              case MainAxisAlignment.end:
                childParentData.offset = Offset(constraints.maxWidth - child.size.width, currentHeight);
                break;
              default:
                childParentData.offset = Offset(0, currentHeight);
                break;
            }
            break;
          case TextDirection.rtl:
            switch (mainAxisAlignment) {
              case MainAxisAlignment.center:
                final double midpoint = constraints.maxWidth / 2.0 - child.size.width / 2.0;
                childParentData.offset = Offset(midpoint, currentHeight);
                break;
              case MainAxisAlignment.end:
                childParentData.offset = Offset(0, currentHeight);
                break;
              default:
                childParentData.offset = Offset(constraints.maxWidth - child.size.width, currentHeight);
                break;
            }
            break;
        }
        currentHeight += child.size.height;
        switch (verticalDirection) {
          case VerticalDirection.down:
            child = childParentData.nextSibling;
            break;
          case VerticalDirection.up:
            child = childParentData.previousSibling;
            break;
        }

        if (overflowButtonSpacing != null && child != null)
          currentHeight += overflowButtonSpacing;
      }
      size = constraints.constrain(Size(constraints.maxWidth, currentHeight));
    }
  }
}
