// 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:math' as math;

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

import 'scaffold.dart';

/// The margin that a [FloatingActionButton] should leave between it and the
/// edge of the screen.
///
/// [FloatingActionButtonLocation.endFloat] uses this to set the appropriate margin
/// between the [FloatingActionButton] and the end of the screen.
const double kFloatingActionButtonMargin = 16.0;

/// The amount of time the [FloatingActionButton] takes to transition in or out.
///
/// The [Scaffold] uses this to set the duration of [FloatingActionButton]
/// motion, entrance, and exit animations.
const Duration kFloatingActionButtonSegue = Duration(milliseconds: 200);

/// The fraction of a circle the [FloatingActionButton] should turn when it enters.
///
/// Its value corresponds to 0.125 of a full circle, equivalent to 45 degrees or pi/4 radians.
const double kFloatingActionButtonTurnInterval = 0.125;

/// If a [FloatingActionButton] is used on a [Scaffold] in certain positions,
/// it is moved [kMiniButtonOffsetAdjustment] pixels closer to the edge of the screen.
///
/// This is intended to be used with [FloatingActionButton.mini] set to true,
/// so that the floating action button appears to align with [CircleAvatar]s
/// in the [ListTile.leading] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
///
/// More specifically:
/// * In the following positions, the [FloatingActionButton] is moved *horizontally*
/// closer to the edge of the screen:
///   * [FloatingActionButtonLocation.miniStartTop]
///   * [FloatingActionButtonLocation.miniStartFloat]
///   * [FloatingActionButtonLocation.miniStartDocked]
///   * [FloatingActionButtonLocation.miniEndTop]
///   * [FloatingActionButtonLocation.miniEndFloat]
///   * [FloatingActionButtonLocation.miniEndDocked]
/// * In the following positions, the [FloatingActionButton] is moved *vertically*
/// closer to the bottom of the screen:
///   * [FloatingActionButtonLocation.miniStartFloat]
///   * [FloatingActionButtonLocation.miniCenterFloat]
///   * [FloatingActionButtonLocation.miniEndFloat]
const double kMiniButtonOffsetAdjustment = 4.0;

/// An object that defines a position for the [FloatingActionButton]
/// based on the [Scaffold]'s [ScaffoldPrelayoutGeometry].
///
/// Flutter provides [FloatingActionButtonLocation]s for the common
/// [FloatingActionButton] placements in Material Design applications. These
/// locations are available as static members of this class.
///
/// ## Floating Action Button placements
///
/// The following diagrams show the available placement locations for the FloatingActionButton.
///
/// * [FloatingActionButtonLocation.centerDocked]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_center_docked.png)
///
///
/// * [FloatingActionButtonLocation.centerFloat]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_center_float.png)
///
///
/// * [FloatingActionButtonLocation.centerTop]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_center_top.png)
///
///
/// * [FloatingActionButtonLocation.endDocked]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_end_docked.png)
///
///
/// * [FloatingActionButtonLocation.endFloat]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_end_float.png)
///
///
/// * [FloatingActionButtonLocation.endTop]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_end_top.png)
///
///
/// * [FloatingActionButtonLocation.startDocked]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_start_docked.png)
///
///
/// * [FloatingActionButtonLocation.startFloat]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_start_float.png)
///
///
/// * [FloatingActionButtonLocation.startTop]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_start_top.png)
///
///
/// * [FloatingActionButtonLocation.miniCenterDocked]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_center_docked.png)
///
///
/// * [FloatingActionButtonLocation.miniCenterFloat]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_center_float.png)
///
///
/// * [FloatingActionButtonLocation.miniCenterTop]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_center_top.png)
///
///
/// * [FloatingActionButtonLocation.miniEndDocked]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_end_docked.png)
///
///
/// * [FloatingActionButtonLocation.miniEndFloat]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_end_float.png)
///
///
/// * [FloatingActionButtonLocation.miniEndTop]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_end_top.png)
///
///
/// * [FloatingActionButtonLocation.miniStartDocked]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_start_docked.png)
///
///
/// * [FloatingActionButtonLocation.miniStartFloat]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_start_float.png)
///
///
/// * [FloatingActionButtonLocation.miniStartTop]:
///
///   ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_start_top.png)
///
///
/// See also:
///
///  * [FloatingActionButton], which is a circular button typically shown in the
///    bottom right corner of the app.
///  * [FloatingActionButtonAnimator], which is used to animate the
///    [Scaffold.floatingActionButton] from one [FloatingActionButtonLocation] to
///    another.
///  * [ScaffoldPrelayoutGeometry], the geometry that
///    [FloatingActionButtonLocation]s use to position the [FloatingActionButton].
abstract class FloatingActionButtonLocation {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  const FloatingActionButtonLocation();

  /// Start-aligned [FloatingActionButton], floating over the transition between
  /// the [Scaffold.appBar] and the [Scaffold.body].
  ///
  /// To align a floating action button with [CircleAvatar]s in the
  /// [ListTile.leading] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
  /// use [miniStartTop] and set [FloatingActionButton.mini] to true.
  ///
  /// This is unlikely to be a useful location for apps that lack a top [AppBar]
  /// or that use a [SliverAppBar] in the scaffold body itself.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_start_top.png)
  static const FloatingActionButtonLocation startTop = _StartTopFabLocation();

  /// Start-aligned [FloatingActionButton], floating over the transition between
  /// the [Scaffold.appBar] and the [Scaffold.body], optimized for mini floating
  /// action buttons.
  ///
  /// This is intended to be used with [FloatingActionButton.mini] set to true,
  /// so that the floating action button appears to align with [CircleAvatar]s
  /// in the [ListTile.leading] slot of a [ListTile] in a [ListView] in the
  /// [Scaffold.body].
  ///
  /// This is unlikely to be a useful location for apps that lack a top [AppBar]
  /// or that use a [SliverAppBar] in the scaffold body itself.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_start_top.png)
  static const FloatingActionButtonLocation miniStartTop = _MiniStartTopFabLocation();

  /// Centered [FloatingActionButton], floating over the transition between
  /// the [Scaffold.appBar] and the [Scaffold.body].
  ///
  /// This is unlikely to be a useful location for apps that lack a top [AppBar]
  /// or that use a [SliverAppBar] in the scaffold body itself.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_center_top.png)
  static const FloatingActionButtonLocation centerTop = _CenterTopFabLocation();

  /// Centered [FloatingActionButton], floating over the transition between
  /// the [Scaffold.appBar] and the [Scaffold.body], intended to be used with
  /// [FloatingActionButton.mini] set to true.
  ///
  /// This is unlikely to be a useful location for apps that lack a top [AppBar]
  /// or that use a [SliverAppBar] in the scaffold body itself.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_center_top.png)
  static const FloatingActionButtonLocation miniCenterTop = _MiniCenterTopFabLocation();

  /// End-aligned [FloatingActionButton], floating over the transition between
  /// the [Scaffold.appBar] and the [Scaffold.body].
  ///
  /// To align a floating action button with [CircleAvatar]s in the
  /// [ListTile.trailing] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
  /// use [miniEndTop] and set [FloatingActionButton.mini] to true.
  ///
  /// This is unlikely to be a useful location for apps that lack a top [AppBar]
  /// or that use a [SliverAppBar] in the scaffold body itself.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_end_top.png)
  static const FloatingActionButtonLocation endTop = _EndTopFabLocation();

  /// End-aligned [FloatingActionButton], floating over the transition between
  /// the [Scaffold.appBar] and the [Scaffold.body], optimized for mini floating
  /// action buttons.
  ///
  /// This is intended to be used with [FloatingActionButton.mini] set to true,
  /// so that the floating action button appears to align with [CircleAvatar]s
  /// in the [ListTile.trailing] slot of a [ListTile] in a [ListView] in the
  /// [Scaffold.body].
  ///
  /// This is unlikely to be a useful location for apps that lack a top [AppBar]
  /// or that use a [SliverAppBar] in the scaffold body itself.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_end_top.png)
  static const FloatingActionButtonLocation miniEndTop = _MiniEndTopFabLocation();

  /// Start-aligned [FloatingActionButton], floating at the bottom of the screen.
  ///
  /// To align a floating action button with [CircleAvatar]s in the
  /// [ListTile.leading] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
  /// use [miniStartFloat] and set [FloatingActionButton.mini] to true.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_start_float.png)
  static const FloatingActionButtonLocation startFloat = _StartFloatFabLocation();

  /// Start-aligned [FloatingActionButton], floating at the bottom of the screen,
  /// optimized for mini floating action buttons.
  ///
  /// This is intended to be used with [FloatingActionButton.mini] set to true,
  /// so that the floating action button appears to align with [CircleAvatar]s
  /// in the [ListTile.leading] slot of a [ListTile] in a [ListView] in the
  /// [Scaffold.body].
  ///
  /// Compared to [FloatingActionButtonLocation.startFloat], floating action
  /// buttons using this location will move horizontally _and_ vertically
  /// closer to the edges, by [kMiniButtonOffsetAdjustment] each.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_start_float.png)
  static const FloatingActionButtonLocation miniStartFloat = _MiniStartFloatFabLocation();

  /// Centered [FloatingActionButton], floating at the bottom of the screen.
  ///
  /// To position a mini floating action button, use [miniCenterFloat] and
  /// set [FloatingActionButton.mini] to true.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_center_float.png)
  static const FloatingActionButtonLocation centerFloat = _CenterFloatFabLocation();

  /// Centered [FloatingActionButton], floating at the bottom of the screen,
  /// optimized for mini floating action buttons.
  ///
  /// This is intended to be used with [FloatingActionButton.mini] set to true,
  /// so that the floating action button appears to align horizontally with
  /// the locations [FloatingActionButtonLocation.miniStartFloat]
  /// and [FloatingActionButtonLocation.miniEndFloat].
  ///
  /// Compared to [FloatingActionButtonLocation.centerFloat], floating action
  /// buttons using this location will move vertically down
  /// by [kMiniButtonOffsetAdjustment].
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_center_float.png)
  static const FloatingActionButtonLocation miniCenterFloat = _MiniCenterFloatFabLocation();

  /// End-aligned [FloatingActionButton], floating at the bottom of the screen.
  ///
  /// This is the default alignment of [FloatingActionButton]s in Material applications.
  ///
  /// To align a floating action button with [CircleAvatar]s in the
  /// [ListTile.trailing] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
  /// use [miniEndFloat] and set [FloatingActionButton.mini] to true.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_end_float.png)
  static const FloatingActionButtonLocation endFloat = _EndFloatFabLocation();

  /// End-aligned [FloatingActionButton], floating at the bottom of the screen,
  /// optimized for mini floating action buttons.
  ///
  /// This is intended to be used with [FloatingActionButton.mini] set to true,
  /// so that the floating action button appears to align with [CircleAvatar]s
  /// in the [ListTile.trailing] slot of a [ListTile] in a [ListView] in the
  /// [Scaffold.body].
  ///
  /// Compared to [FloatingActionButtonLocation.endFloat], floating action
  /// buttons using this location will move horizontally _and_ vertically
  /// closer to the edges, by [kMiniButtonOffsetAdjustment] each.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_end_float.png)
  static const FloatingActionButtonLocation miniEndFloat = _MiniEndFloatFabLocation();

  /// Start-aligned [FloatingActionButton], floating over the
  /// [Scaffold.bottomNavigationBar] so that the center of the floating
  /// action button lines up with the top of the bottom navigation bar.
  ///
  /// To align a floating action button with [CircleAvatar]s in the
  /// [ListTile.leading] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
  /// use [miniStartDocked] and set [FloatingActionButton.mini] to true.
  ///
  /// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
  /// the bottom app bar can include a "notch" in its shape that accommodates
  /// the overlapping floating action button.
  ///
  /// This is unlikely to be a useful location for apps that lack a bottom
  /// navigation bar.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_start_docked.png)
  static const FloatingActionButtonLocation startDocked = _StartDockedFabLocation();

  /// Start-aligned [FloatingActionButton], floating over the
  /// [Scaffold.bottomNavigationBar] so that the center of the floating
  /// action button lines up with the top of the bottom navigation bar,
  /// optimized for mini floating action buttons.
  ///
  /// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
  /// the bottom app bar can include a "notch" in its shape that accommodates
  /// the overlapping floating action button.
  ///
  /// This is intended to be used with [FloatingActionButton.mini] set to true,
  /// so that the floating action button appears to align with [CircleAvatar]s
  /// in the [ListTile.leading] slot of a [ListTile] in a [ListView] in the
  /// [Scaffold.body].
  ///
  /// This is unlikely to be a useful location for apps that lack a bottom
  /// navigation bar.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_start_docked.png)
  static const FloatingActionButtonLocation miniStartDocked = _MiniStartDockedFabLocation();

  /// Centered [FloatingActionButton], floating over the
  /// [Scaffold.bottomNavigationBar] so that the center of the floating
  /// action button lines up with the top of the bottom navigation bar.
  ///
  /// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
  /// the bottom app bar can include a "notch" in its shape that accommodates
  /// the overlapping floating action button.
  ///
  /// This is unlikely to be a useful location for apps that lack a bottom
  /// navigation bar.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_center_docked.png)
  static const FloatingActionButtonLocation centerDocked = _CenterDockedFabLocation();

  /// Centered [FloatingActionButton], floating over the
  /// [Scaffold.bottomNavigationBar] so that the center of the floating
  /// action button lines up with the top of the bottom navigation bar;
  /// intended to be used with [FloatingActionButton.mini] set to true.
  ///
  /// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
  /// the bottom app bar can include a "notch" in its shape that accommodates
  /// the overlapping floating action button.
  ///
  /// This is unlikely to be a useful location for apps that lack a bottom
  /// navigation bar.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_center_docked.png)
  static const FloatingActionButtonLocation miniCenterDocked = _MiniCenterDockedFabLocation();

  /// End-aligned [FloatingActionButton], floating over the
  /// [Scaffold.bottomNavigationBar] so that the center of the floating
  /// action button lines up with the top of the bottom navigation bar.
  ///
  /// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
  /// the bottom app bar can include a "notch" in its shape that accommodates
  /// the overlapping floating action button.
  ///
  /// This is unlikely to be a useful location for apps that lack a bottom
  /// navigation bar.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_end_docked.png)
  static const FloatingActionButtonLocation endDocked = _EndDockedFabLocation();

  /// End-aligned [FloatingActionButton], floating over the
  /// [Scaffold.bottomNavigationBar] so that the center of the floating
  /// action button lines up with the top of the bottom navigation bar,
  /// optimized for mini floating action buttons.
  ///
  /// To align a floating action button with [CircleAvatar]s in the
  /// [ListTile.trailing] slots of [ListTile]s in a [ListView] in the [Scaffold.body],
  /// use [miniEndDocked] and set [FloatingActionButton.mini] to true.
  ///
  /// If the value of [Scaffold.bottomNavigationBar] is a [BottomAppBar],
  /// the bottom app bar can include a "notch" in its shape that accommodates
  /// the overlapping floating action button.
  ///
  /// This is intended to be used with [FloatingActionButton.mini] set to true,
  /// so that the floating action button appears to align with [CircleAvatar]s
  /// in the [ListTile.trailing] slot of a [ListTile] in a [ListView] in the
  /// [Scaffold.body].
  ///
  /// This is unlikely to be a useful location for apps that lack a bottom
  /// navigation bar.
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_mini_end_docked.png)
  static const FloatingActionButtonLocation miniEndDocked = _MiniEndDockedFabLocation();

  /// End-aligned [FloatingActionButton], floating over the
  /// [Scaffold.bottomNavigationBar] so that the floating
  /// action button lines up with the center of the bottom navigation bar.
  ///
  /// This is unlikely to be a useful location for apps which has a [BottomNavigationBar]
  /// or a non material 3 [BottomAppBar].
  ///
  /// ![](https://flutter.github.io/assets-for-api-docs/assets/material/floating_action_button_location_end_contained.png)
  static const FloatingActionButtonLocation endContained = _EndContainedFabLocation();

  /// Places the [FloatingActionButton] based on the [Scaffold]'s layout.
  ///
  /// This uses a [ScaffoldPrelayoutGeometry], which the [Scaffold] constructs
  /// during its layout phase after it has laid out every widget it can lay out
  /// except the [FloatingActionButton]. The [Scaffold] uses the [Offset]
  /// returned from this method to position the [FloatingActionButton] and
  /// complete its layout.
  Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry);

  @override
  String toString() => objectRuntimeType(this, 'FloatingActionButtonLocation');
}

/// A base class that simplifies building [FloatingActionButtonLocation]s when
/// used with mixins [FabTopOffsetY], [FabFloatOffsetY], [FabDockedOffsetY],
/// [FabStartOffsetX], [FabCenterOffsetX], [FabEndOffsetX], and [FabMiniOffsetAdjustment].
///
/// A subclass of [FloatingActionButtonLocation] which implements its [getOffset] method
/// using three other methods: [getOffsetX], [getOffsetY], and [isMini].
///
/// Different mixins on this class override different methods, so that combining
/// a set of mixins creates a floating action button location.
///
/// For example: the location [FloatingActionButtonLocation.miniEndTop]
/// is based on a class that extends [StandardFabLocation]
/// with mixins [FabMiniOffsetAdjustment], [FabEndOffsetX], and [FabTopOffsetY].
///
/// You can create your own subclass of [StandardFabLocation]
/// to implement a custom [FloatingActionButtonLocation].
///
/// {@tool dartpad}
/// This is an example of a user-defined [FloatingActionButtonLocation].
///
/// The example shows a [Scaffold] with an [AppBar], a [BottomAppBar], and a
/// [FloatingActionButton] using a custom [FloatingActionButtonLocation].
///
/// The new [FloatingActionButtonLocation] is defined
/// by extending [StandardFabLocation] with two mixins,
/// [FabEndOffsetX] and [FabFloatOffsetY], and overriding the
/// [getOffsetX] method to adjust the FAB's x-coordinate, creating a
/// [FloatingActionButtonLocation] slightly different from
/// [FloatingActionButtonLocation.endFloat].
///
/// ** See code in examples/api/lib/material/floating_action_button_location/standard_fab_location.0.dart **
/// {@end-tool}
///
abstract class StandardFabLocation extends FloatingActionButtonLocation {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  const StandardFabLocation();

  /// Obtains the x-offset to place the [FloatingActionButton] based on the
  /// [Scaffold]'s layout.
  ///
  /// Used by [getOffset] to compute its x-coordinate.
  double getOffsetX(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment);

  /// Obtains the y-offset to place the [FloatingActionButton] based on the
  /// [Scaffold]'s layout.
  ///
  /// Used by [getOffset] to compute its y-coordinate.
  double getOffsetY(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment);

  /// A function returning whether this [StandardFabLocation] is optimized for
  /// mini [FloatingActionButton]s.
  bool isMini () => false;

  @override
  Offset getOffset(ScaffoldPrelayoutGeometry scaffoldGeometry) {
    final double adjustment = isMini() ? kMiniButtonOffsetAdjustment : 0.0;
    return Offset(
      getOffsetX(scaffoldGeometry, adjustment),
      getOffsetY(scaffoldGeometry, adjustment),
    );
  }

  /// Calculates x-offset for left-aligned [FloatingActionButtonLocation]s.
  static double _leftOffsetX(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    return kFloatingActionButtonMargin
        + scaffoldGeometry.minInsets.left
        - adjustment;
  }

  /// Calculates x-offset for right-aligned [FloatingActionButtonLocation]s.
  static double _rightOffsetX(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    return scaffoldGeometry.scaffoldSize.width
        - kFloatingActionButtonMargin
        - scaffoldGeometry.minInsets.right
        - scaffoldGeometry.floatingActionButtonSize.width
        + adjustment;
  }


}

/// Mixin for a "top" floating action button location, such as
/// [FloatingActionButtonLocation.startTop].
///
/// The `adjustment`, typically [kMiniButtonOffsetAdjustment], is ignored in the
/// Y axis of "top" positions. For "top" positions, the X offset is adjusted to
/// move closer to the edge of the screen. This is so that a minified floating
/// action button appears to align with [CircleAvatar]s in the
/// [ListTile.leading] slot of a [ListTile] in a [ListView] in the
/// [Scaffold.body].
mixin FabTopOffsetY on StandardFabLocation {
  /// Calculates y-offset for [FloatingActionButtonLocation]s floating over
  /// the transition between the [Scaffold.appBar] and the [Scaffold.body].
  @override
  double getOffsetY(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    if (scaffoldGeometry.contentTop > scaffoldGeometry.minViewPadding.top) {
      final double fabHalfHeight = scaffoldGeometry.floatingActionButtonSize.height / 2.0;
      return scaffoldGeometry.contentTop - fabHalfHeight;
    }
    // Otherwise, ensure we are placed within the bounds of a safe area.
    return scaffoldGeometry.minViewPadding.top;
  }
}

/// Mixin for a "float" floating action button location, such as [FloatingActionButtonLocation.centerFloat].
mixin FabFloatOffsetY on StandardFabLocation {
  /// Calculates y-offset for [FloatingActionButtonLocation]s floating at
  /// the bottom of the screen.
  @override
  double getOffsetY(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    final double contentBottom = scaffoldGeometry.contentBottom;
    final double bottomContentHeight = scaffoldGeometry.scaffoldSize.height - contentBottom;
    final double bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height;
    final double fabHeight = scaffoldGeometry.floatingActionButtonSize.height;
    final double snackBarHeight = scaffoldGeometry.snackBarSize.height;
    final double safeMargin = math.max(
      kFloatingActionButtonMargin,
      scaffoldGeometry.minViewPadding.bottom - bottomContentHeight + kFloatingActionButtonMargin,
    );

    double fabY = contentBottom - fabHeight - safeMargin;
    if (snackBarHeight > 0.0) {
      fabY = math.min(fabY, contentBottom - snackBarHeight - fabHeight - kFloatingActionButtonMargin);
    }
    if (bottomSheetHeight > 0.0) {
      fabY = math.min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0);
    }
    return fabY + adjustment;
  }
}

/// Mixin for a "docked" floating action button location, such as [FloatingActionButtonLocation.endDocked].
mixin FabDockedOffsetY on StandardFabLocation {
  /// Calculates y-offset for [FloatingActionButtonLocation]s floating over the
  /// [Scaffold.bottomNavigationBar] so that the center of the floating
  /// action button lines up with the top of the bottom navigation bar.
  @override
  double getOffsetY(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    final double contentBottom = scaffoldGeometry.contentBottom;
    final double contentMargin = scaffoldGeometry.scaffoldSize.height - contentBottom;
    final double bottomViewPadding = scaffoldGeometry.minViewPadding.bottom;
    final double bottomSheetHeight = scaffoldGeometry.bottomSheetSize.height;
    final double fabHeight = scaffoldGeometry.floatingActionButtonSize.height;
    final double snackBarHeight = scaffoldGeometry.snackBarSize.height;
    final double bottomMinInset = scaffoldGeometry.minInsets.bottom;

    double safeMargin;

    if (contentMargin > bottomMinInset + fabHeight / 2.0) {
      // If contentMargin is higher than bottomMinInset enough to display the
      // FAB without clipping, don't provide a margin
      safeMargin = 0.0;
    } else if (bottomMinInset == 0.0) {
      // If bottomMinInset is zero(the software keyboard is not on the screen)
      // provide bottomViewPadding as margin
      safeMargin = bottomViewPadding;
    } else {
      // Provide a margin that would shift the FAB enough so that it stays away
      // from the keyboard
      safeMargin = fabHeight / 2.0 + kFloatingActionButtonMargin;
    }

    double fabY = contentBottom - fabHeight / 2.0 - safeMargin;
    // The FAB should sit with a margin between it and the snack bar.
    if (snackBarHeight > 0.0) {
      fabY = math.min(fabY, contentBottom - snackBarHeight - fabHeight - kFloatingActionButtonMargin);
    }
    // The FAB should sit with its center in front of the top of the bottom sheet.
    if (bottomSheetHeight > 0.0) {
      fabY = math.min(fabY, contentBottom - bottomSheetHeight - fabHeight / 2.0);
    }
    final double maxFabY = scaffoldGeometry.scaffoldSize.height - fabHeight - safeMargin;
    return math.min(maxFabY, fabY);
  }
}

/// Mixin for a "contained" floating action button location, such as [FloatingActionButtonLocation.endContained].
mixin FabContainedOffsetY on StandardFabLocation {
  /// Calculates y-offset for [FloatingActionButtonLocation]s floating over the
  /// [Scaffold.bottomNavigationBar] so that the center of the floating
  /// action button lines up with the center of the bottom navigation bar.
  @override
  double getOffsetY(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    final double contentBottom = scaffoldGeometry.contentBottom;
    final double contentMargin = scaffoldGeometry.scaffoldSize.height - contentBottom;
    final double bottomViewPadding = scaffoldGeometry.minViewPadding.bottom;
    final double fabHeight = scaffoldGeometry.floatingActionButtonSize.height;

    double safeMargin;
    if (contentMargin > bottomViewPadding + fabHeight) {
      // If contentMargin is higher than bottomViewPadding enough to display the
      // FAB without clipping, don't provide a margin
      safeMargin = 0.0;
    } else {
      safeMargin = bottomViewPadding;
    }

    // This is to compute the distance between the content bottom to the top edge
    // of the floating action button. This can be negative if content margin is
    // too small.
    final double contentBottomToFabTop = (contentMargin - bottomViewPadding - fabHeight) / 2.0;
    final double fabY = contentBottom + contentBottomToFabTop;
    final double maxFabY = scaffoldGeometry.scaffoldSize.height - fabHeight - safeMargin;

    return math.min(maxFabY, fabY);
  }
}

/// Mixin for a "start" floating action button location, such as [FloatingActionButtonLocation.startTop].
mixin FabStartOffsetX on StandardFabLocation {
  /// Calculates x-offset for start-aligned [FloatingActionButtonLocation]s.
  @override
  double getOffsetX(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    switch (scaffoldGeometry.textDirection) {
      case TextDirection.rtl:
        return StandardFabLocation._rightOffsetX(scaffoldGeometry, adjustment);
      case TextDirection.ltr:
        return StandardFabLocation._leftOffsetX(scaffoldGeometry, adjustment);
    }
  }
}

/// Mixin for a "center" floating action button location, such as [FloatingActionButtonLocation.centerFloat].
mixin FabCenterOffsetX on StandardFabLocation {
  /// Calculates x-offset for center-aligned [FloatingActionButtonLocation]s.
  @override
  double getOffsetX(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    return (scaffoldGeometry.scaffoldSize.width - scaffoldGeometry.floatingActionButtonSize.width) / 2.0;
  }
}

/// Mixin for an "end" floating action button location, such as [FloatingActionButtonLocation.endDocked].
mixin FabEndOffsetX on StandardFabLocation {
  /// Calculates x-offset for end-aligned [FloatingActionButtonLocation]s.
  @override
  double getOffsetX(ScaffoldPrelayoutGeometry scaffoldGeometry, double adjustment) {
    switch (scaffoldGeometry.textDirection) {
      case TextDirection.rtl:
        return StandardFabLocation._leftOffsetX(scaffoldGeometry, adjustment);
      case TextDirection.ltr:
        return StandardFabLocation._rightOffsetX(scaffoldGeometry, adjustment);
    }
  }
}

/// Mixin for a "mini" floating action button location, such as [FloatingActionButtonLocation.miniStartTop].
mixin FabMiniOffsetAdjustment on StandardFabLocation {
  @override
  bool isMini () => true;
}

class _StartTopFabLocation extends StandardFabLocation
    with FabStartOffsetX, FabTopOffsetY {
  const _StartTopFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.startTop';
}

class _MiniStartTopFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabStartOffsetX, FabTopOffsetY {
  const _MiniStartTopFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniStartTop';
}

class _CenterTopFabLocation extends StandardFabLocation
    with FabCenterOffsetX, FabTopOffsetY {
  const _CenterTopFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.centerTop';
}

class _MiniCenterTopFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabCenterOffsetX, FabTopOffsetY {
  const _MiniCenterTopFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniCenterTop';
}

class _EndTopFabLocation extends StandardFabLocation
    with FabEndOffsetX, FabTopOffsetY {
  const _EndTopFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.endTop';
}

class _MiniEndTopFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabEndOffsetX, FabTopOffsetY {
  const _MiniEndTopFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniEndTop';
}

class _StartFloatFabLocation extends StandardFabLocation
    with FabStartOffsetX, FabFloatOffsetY {
  const _StartFloatFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.startFloat';
}

class _MiniStartFloatFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabStartOffsetX, FabFloatOffsetY {
  const _MiniStartFloatFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniStartFloat';
}

class _CenterFloatFabLocation extends StandardFabLocation
    with FabCenterOffsetX, FabFloatOffsetY {
  const _CenterFloatFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.centerFloat';
}

class _MiniCenterFloatFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabCenterOffsetX, FabFloatOffsetY {
  const _MiniCenterFloatFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniCenterFloat';
}

class _EndFloatFabLocation extends StandardFabLocation
    with FabEndOffsetX, FabFloatOffsetY {
  const _EndFloatFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.endFloat';
}

class _MiniEndFloatFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabEndOffsetX, FabFloatOffsetY {
  const _MiniEndFloatFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniEndFloat';
}

class _StartDockedFabLocation extends StandardFabLocation
    with FabStartOffsetX, FabDockedOffsetY {
  const _StartDockedFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.startDocked';
}

class _MiniStartDockedFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabStartOffsetX, FabDockedOffsetY {
  const _MiniStartDockedFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniStartDocked';
}

class _CenterDockedFabLocation extends StandardFabLocation
    with FabCenterOffsetX, FabDockedOffsetY {
  const _CenterDockedFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.centerDocked';
}

class _MiniCenterDockedFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabCenterOffsetX, FabDockedOffsetY {
  const _MiniCenterDockedFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniCenterDocked';
}

class _EndDockedFabLocation extends StandardFabLocation
    with FabEndOffsetX, FabDockedOffsetY {
  const _EndDockedFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.endDocked';
}

class _MiniEndDockedFabLocation extends StandardFabLocation
    with FabMiniOffsetAdjustment, FabEndOffsetX, FabDockedOffsetY {
  const _MiniEndDockedFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.miniEndDocked';
}

class _EndContainedFabLocation extends StandardFabLocation
    with FabEndOffsetX, FabContainedOffsetY {
  const _EndContainedFabLocation();

  @override
  String toString() => 'FloatingActionButtonLocation.endContained';
}

/// Provider of animations to move the [FloatingActionButton] between [FloatingActionButtonLocation]s.
///
/// The [Scaffold] uses [Scaffold.floatingActionButtonAnimator] to define:
///
///  * The [Offset] of the [FloatingActionButton] between the old and new
///    [FloatingActionButtonLocation]s as part of the transition animation.
///  * An [Animation] to scale the [FloatingActionButton] during the transition.
///  * An [Animation] to rotate the [FloatingActionButton] during the transition.
///  * Where to start a new animation from if an animation is interrupted.
///
/// See also:
///
///  * [FloatingActionButton], which is a circular button typically shown in the
///    bottom right corner of the app.
///  * [FloatingActionButtonLocation], which the [Scaffold] uses to place the
///    [Scaffold.floatingActionButton] within the [Scaffold]'s layout.
abstract class FloatingActionButtonAnimator {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.
  const FloatingActionButtonAnimator();

  /// Moves the [FloatingActionButton] by scaling out and then in at a new
  /// [FloatingActionButtonLocation].
  ///
  /// This animator shrinks the [FloatingActionButton] down until it disappears, then
  /// grows it back to full size at its new [FloatingActionButtonLocation].
  ///
  /// This is the default [FloatingActionButton] motion animation.
  static const FloatingActionButtonAnimator scaling = _ScalingFabMotionAnimator();

  /// Gets the [FloatingActionButton]'s position relative to the origin of the
  /// [Scaffold] based on [progress].
  ///
  /// [begin] is the [Offset] provided by the previous
  /// [FloatingActionButtonLocation].
  ///
  /// [end] is the [Offset] provided by the new
  /// [FloatingActionButtonLocation].
  ///
  /// [progress] is the current progress of the transition animation.
  /// When [progress] is 0.0, the returned [Offset] should be equal to [begin].
  /// when [progress] is 1.0, the returned [Offset] should be equal to [end].
  Offset getOffset({ required Offset begin, required Offset end, required double progress });

  /// Animates the scale of the [FloatingActionButton].
  ///
  /// The animation should both start and end with a value of 1.0.
  ///
  /// For example, to create an animation that linearly scales out and then back in,
  /// you could join animations that pass each other:
  ///
  /// ```dart
  ///   @override
  ///   Animation<double> getScaleAnimation({required Animation<double> parent}) {
  ///     // The animations will cross at value 0, and the train will return to 1.0.
  ///     return TrainHoppingAnimation(
  ///       Tween<double>(begin: 1.0, end: -1.0).animate(parent),
  ///       Tween<double>(begin: -1.0, end: 1.0).animate(parent),
  ///     );
  ///   }
  /// ```
  Animation<double> getScaleAnimation({ required Animation<double> parent });

  /// Animates the rotation of [Scaffold.floatingActionButton].
  ///
  /// The animation should both start and end with a value of 0.0 or 1.0.
  ///
  /// The animation values are a fraction of a full circle, with 0.0 and 1.0
  /// corresponding to 0 and 360 degrees, while 0.5 corresponds to 180 degrees.
  ///
  /// For example, to create a rotation animation that rotates the
  /// [FloatingActionButton] through a full circle:
  ///
  /// ```dart
  /// @override
  /// Animation<double> getRotationAnimation({required Animation<double> parent}) {
  ///   return Tween<double>(begin: 0.0, end: 1.0).animate(parent);
  /// }
  /// ```
  Animation<double> getRotationAnimation({ required Animation<double> parent });

  /// Gets the progress value to restart a motion animation from when the animation is interrupted.
  ///
  /// [previousValue] is the value of the animation before it was interrupted.
  ///
  /// The restart of the animation will affect all three parts of the motion animation:
  /// offset animation, scale animation, and rotation animation.
  ///
  /// An interruption triggers if the [Scaffold] is given a new [FloatingActionButtonLocation]
  /// while it is still animating a transition between two previous [FloatingActionButtonLocation]s.
  ///
  /// A sensible default is usually 0.0, which is the same as restarting
  /// the animation from the beginning, regardless of the original state of the animation.
  double getAnimationRestart(double previousValue) => 0.0;

  @override
  String toString() => objectRuntimeType(this, 'FloatingActionButtonAnimator');
}

class _ScalingFabMotionAnimator extends FloatingActionButtonAnimator {
  const _ScalingFabMotionAnimator();

  @override
  Offset getOffset({ required Offset begin, required Offset end, required double progress }) {
    if (progress < 0.5) {
      return begin;
    } else {
      return end;
    }
  }

  @override
  Animation<double> getScaleAnimation({ required Animation<double> parent }) {
    // Animate the scale down from 1 to 0 in the first half of the animation
    // then from 0 back to 1 in the second half.
    const Curve curve = Interval(0.5, 1.0, curve: Curves.ease);
    return _AnimationSwap<double>(
      ReverseAnimation(parent.drive(CurveTween(curve: curve.flipped))),
      parent.drive(CurveTween(curve: curve)),
      parent,
      0.5,
    );
  }

  // Because we only see the last half of the rotation tween,
  // it needs to go twice as far.
  static final Animatable<double> _rotationTween = Tween<double>(
    begin: 1.0 - kFloatingActionButtonTurnInterval * 2.0,
    end: 1.0,
  );

  static final Animatable<double> _thresholdCenterTween = CurveTween(curve: const Threshold(0.5));

  @override
  Animation<double> getRotationAnimation({ required Animation<double> parent }) {
    // This rotation will turn on the way in, but not on the way out.
    return _AnimationSwap<double>(
      parent.drive(_rotationTween),
      ReverseAnimation(parent.drive(_thresholdCenterTween)),
      parent,
      0.5,
    );
  }

  // If the animation was just starting, we'll continue from where we left off.
  // If the animation was finishing, we'll treat it as if we were starting at that point in reverse.
  // This avoids a size jump during the animation.
  @override
  double getAnimationRestart(double previousValue) => math.min(1.0 - previousValue, previousValue);
}

/// An animation that swaps from one animation to the next when the [parent] passes [swapThreshold].
///
/// The [value] of this animation is the value of [first] when [parent.value] < [swapThreshold]
/// and the value of [next] otherwise.
class _AnimationSwap<T> extends CompoundAnimation<T> {
  /// Creates an [_AnimationSwap].
  ///
  /// Both arguments must be non-null. Either can be an [_AnimationSwap] itself
  /// to combine multiple animations.
  _AnimationSwap(Animation<T> first, Animation<T> next, this.parent, this.swapThreshold) : super(first: first, next: next);

  final Animation<double> parent;
  final double swapThreshold;

  @override
  T get value => parent.value < swapThreshold ? first.value : next.value;
}
