// 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();

  /// 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 "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) {
    assert(scaffoldGeometry.textDirection != null);
    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) {
    assert(scaffoldGeometry.textDirection != null);
    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';
}

/// 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;
}
