// 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:ui' show lerpDouble;

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

import 'theme.dart';

/// Defines where a [SnackBar] should appear within a [Scaffold] and how its
/// location should be adjusted when the scaffold also includes a
/// [FloatingActionButton] or a [BottomNavigationBar].
enum SnackBarBehavior {
  /// Fixes the [SnackBar] at the bottom of the [Scaffold].
  ///
  /// The exception is that the [SnackBar] will be shown above a
  /// [BottomNavigationBar]. Additionally, the [SnackBar] will cause other
  /// non-fixed widgets inside [Scaffold] to be pushed above (for example, the
  /// [FloatingActionButton]).
  fixed,

  /// This behavior will cause [SnackBar] to be shown above other widgets in the
  /// [Scaffold]. This includes being displayed above a [BottomNavigationBar]
  /// and a [FloatingActionButton].
  ///
  /// See <https://material.io/design/components/snackbars.html> for more details.
  floating,
}

/// Customizes default property values for [SnackBar] widgets.
///
/// Descendant widgets obtain the current [SnackBarThemeData] object using
/// `Theme.of(context).snackBarTheme`. Instances of [SnackBarThemeData] can be
/// customized with [SnackBarThemeData.copyWith].
///
/// Typically a [SnackBarThemeData] is specified as part of the overall [Theme]
/// with [ThemeData.snackBarTheme]. The default for [ThemeData.snackBarTheme]
/// provides all `null` properties.
///
/// All [SnackBarThemeData] properties are `null` by default. When null, the
/// [SnackBar] will provide its own defaults.
///
/// See also:
///
///  * [ThemeData], which describes the overall theme information for the
///    application.
@immutable
class SnackBarThemeData with Diagnosticable {

  /// Creates a theme that can be used for [ThemeData.snackBarTheme].
  ///
  /// The [elevation] must be null or non-negative.
  const SnackBarThemeData({
    this.backgroundColor,
    this.actionTextColor,
    this.disabledActionTextColor,
    this.contentTextStyle,
    this.elevation,
    this.shape,
    this.behavior,
  }) : assert(elevation == null || elevation >= 0.0);

  /// Default value for [SnackBar.backgroundColor].
  ///
  /// If null, [SnackBar] defaults to dark grey: `Color(0xFF323232)`.
  final Color? backgroundColor;

  /// Default value for [SnackBarAction.textColor].
  ///
  /// If null, [SnackBarAction] defaults to [ColorScheme.secondary] of
  /// [ThemeData.colorScheme] .
  final Color? actionTextColor;

  /// Default value for [SnackBarAction.disabledTextColor].
  ///
  /// If null, [SnackBarAction] defaults to [ColorScheme.onSurface] with its
  /// opacity set to 0.30 if the [Theme]'s brightness is [Brightness.dark], 0.38
  /// otherwise.
  final Color? disabledActionTextColor;

  /// Used to configure the [DefaultTextStyle] for the [SnackBar.content] widget.
  ///
  /// If null, [SnackBar] defines its default.
  final TextStyle? contentTextStyle;

  /// Default value for [SnackBar.elevation].
  ///
  /// If null, [SnackBar] uses a default of 6.0.
  final double? elevation;

  /// Default value for [SnackBar.shape].
  ///
  /// If null, [SnackBar] provides different defaults depending on the
  /// [SnackBarBehavior]. For [SnackBarBehavior.fixed], no overriding shape is
  /// specified, so the [SnackBar] is rectangular. For
  /// [SnackBarBehavior.floating], it uses a [RoundedRectangleBorder] with a
  /// circular corner radius of 4.0.
  final ShapeBorder? shape;

  /// Default value for [SnackBar.behavior].
  ///
  /// If null, [SnackBar] will default to [SnackBarBehavior.fixed].
  final SnackBarBehavior? behavior;

  /// Creates a copy of this object with the given fields replaced with the
  /// new values.
  SnackBarThemeData copyWith({
    Color? backgroundColor,
    Color? actionTextColor,
    Color? disabledActionTextColor,
    TextStyle? contentTextStyle,
    double? elevation,
    ShapeBorder? shape,
    SnackBarBehavior? behavior,
  }) {
    return SnackBarThemeData(
      backgroundColor: backgroundColor ?? this.backgroundColor,
      actionTextColor: actionTextColor ?? this.actionTextColor,
      disabledActionTextColor: disabledActionTextColor ?? this.disabledActionTextColor,
      contentTextStyle: contentTextStyle ?? this.contentTextStyle,
      elevation: elevation ?? this.elevation,
      shape: shape ?? this.shape,
      behavior: behavior ?? this.behavior,
    );
  }

  /// Linearly interpolate between two SnackBar Themes.
  ///
  /// The argument `t` must not be null.
  ///
  /// {@macro dart.ui.shadow.lerp}
  static SnackBarThemeData lerp(SnackBarThemeData? a, SnackBarThemeData? b, double t) {
    assert(t != null);
    return SnackBarThemeData(
      backgroundColor: Color.lerp(a?.backgroundColor, b?.backgroundColor, t),
      actionTextColor: Color.lerp(a?.actionTextColor, b?.actionTextColor, t),
      disabledActionTextColor: Color.lerp(a?.disabledActionTextColor, b?.disabledActionTextColor, t),
      contentTextStyle: TextStyle.lerp(a?.contentTextStyle, b?.contentTextStyle, t),
      elevation: lerpDouble(a?.elevation, b?.elevation, t),
      shape: ShapeBorder.lerp(a?.shape, b?.shape, t),
      behavior: t < 0.5 ? a?.behavior : b?.behavior,
    );
  }

  @override
  int get hashCode {
    return hashValues(
      backgroundColor,
      actionTextColor,
      disabledActionTextColor,
      contentTextStyle,
      elevation,
      shape,
      behavior,
    );
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other))
      return true;
    if (other.runtimeType != runtimeType)
      return false;
    return other is SnackBarThemeData
        && other.backgroundColor == backgroundColor
        && other.actionTextColor == actionTextColor
        && other.disabledActionTextColor == disabledActionTextColor
        && other.contentTextStyle == contentTextStyle
        && other.elevation == elevation
        && other.shape == shape
        && other.behavior == behavior;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(ColorProperty('backgroundColor', backgroundColor, defaultValue: null));
    properties.add(ColorProperty('actionTextColor', actionTextColor, defaultValue: null));
    properties.add(ColorProperty('disabledActionTextColor', disabledActionTextColor, defaultValue: null));
    properties.add(DiagnosticsProperty<TextStyle>('contentTextStyle', contentTextStyle, defaultValue: null));
    properties.add(DoubleProperty('elevation', elevation, defaultValue: null));
    properties.add(DiagnosticsProperty<ShapeBorder>('shape', shape, defaultValue: null));
    properties.add(DiagnosticsProperty<SnackBarBehavior>('behavior', behavior, defaultValue: null));
  }
}
