// 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/rendering.dart';
import 'package:flutter/widgets.dart';

import 'button_bar_theme.dart';
import 'button_theme.dart';
import 'dialog.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:
///
///  * [TextButton], a simple flat button without a shadow.
///  * [ElevatedButton], a filled button whose material elevates when pressed.
///  * [OutlinedButton], a [TextButton] with a border outline.
///  * [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({
    super.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);

  /// How the children should be placed along the horizontal axis.
  ///
  /// If null then it will use [ButtonBarThemeData.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 [ButtonBarThemeData.mainAxisSize].
  /// If that is null, it will default to [MainAxisSize.max].
  final MainAxisSize? mainAxisSize;

  /// Overrides the surrounding [ButtonBarThemeData.buttonTextTheme] to define a
  /// button's base colors, size, internal padding and shape.
  ///
  /// If null then it will use the surrounding
  /// [ButtonBarThemeData.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 [ButtonBarThemeData.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 [ButtonBarThemeData.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 [ButtonBarThemeData.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 [ButtonBarThemeData.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 [ButtonBarThemeData.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
  /// [ButtonBarThemeData.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 [ElevatedButton] or [TextButton] 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,
        overflowButtonSpacing: overflowButtonSpacing,
        children: children.map<Widget>((Widget child) {
          return Padding(
            padding: EdgeInsets.symmetric(horizontal: paddingUnit),
            child: child,
          );
        }).toList(),
      ),
    );
    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,
        );
    }
  }
}

/// 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({
    required super.children,
    super.mainAxisSize,
    super.mainAxisAlignment,
    VerticalDirection overflowDirection = VerticalDirection.down,
    this.overflowButtonSpacing,
  }) : super(
    direction: Axis.horizontal,
    verticalDirection: overflowDirection,
  );

  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({
    super.direction,
    super.mainAxisSize,
    super.mainAxisAlignment,
    super.crossAxisAlignment,
    required TextDirection super.textDirection,
    super.verticalDirection,
    super.textBaseline,
    this.overflowButtonSpacing,
  }) : assert(textDirection != null),
       assert(overflowButtonSpacing == null || overflowButtonSpacing >= 0);

  bool _hasCheckedLayoutWidth = false;
  double? overflowButtonSpacing;

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

  @override
  Size computeDryLayout(BoxConstraints constraints) {
    final Size size = super.computeDryLayout(constraints.copyWith(maxWidth: double.infinity));
    if (size.width <= constraints.maxWidth) {
      return super.computeDryLayout(constraints);
    }
    double currentHeight = 0.0;
    RenderBox? child = firstChild;
    while (child != null) {
      final BoxConstraints childConstraints = constraints.copyWith(minWidth: 0.0);
      final Size childSize = child.getDryLayout(childConstraints);
      currentHeight += childSize.height;
      child = childAfter(child);
      if (overflowButtonSpacing != null && child != null) {
        currentHeight += overflowButtonSpacing!;
      }
    }
    return constraints.constrain(Size(constraints.maxWidth, currentHeight));
  }

  @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;
              case MainAxisAlignment.spaceAround:
              case MainAxisAlignment.spaceBetween:
              case MainAxisAlignment.spaceEvenly:
              case MainAxisAlignment.start:
                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;
              case MainAxisAlignment.spaceAround:
              case MainAxisAlignment.spaceBetween:
              case MainAxisAlignment.spaceEvenly:
              case MainAxisAlignment.start:
                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));
    }
  }
}
