// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

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

import 'button_style.dart';
import 'theme.dart';

// Examples can assume:
// late BuildContext context;

/// A [ButtonStyle] that overrides the default appearance of
/// [FilledButton]s when it's used with [FilledButtonTheme] or with the
/// overall [Theme]'s [ThemeData.filledButtonTheme].
///
/// The [style]'s properties override [FilledButton]'s default style,
/// i.e. the [ButtonStyle] returned by [FilledButton.defaultStyleOf]. Only
/// the style's non-null property values or resolved non-null
/// [MaterialStateProperty] values are used.
///
/// See also:
///
///  * [FilledButtonTheme], the theme which is configured with this class.
///  * [FilledButton.defaultStyleOf], which returns the default [ButtonStyle]
///    for text buttons.
///  * [FilledButton.styleFrom], which converts simple values into a
///    [ButtonStyle] that's consistent with [FilledButton]'s defaults.
///  * [MaterialStateProperty.resolve], "resolve" a material state property
///    to a simple value based on a set of [MaterialState]s.
///  * [ThemeData.filledButtonTheme], which can be used to override the default
///    [ButtonStyle] for [FilledButton]s below the overall [Theme].
@immutable
class FilledButtonThemeData with Diagnosticable {
  /// Creates an [FilledButtonThemeData].
  ///
  /// The [style] may be null.
  const FilledButtonThemeData({ this.style });

  /// Overrides for [FilledButton]'s default style.
  ///
  /// Non-null properties or non-null resolved [MaterialStateProperty]
  /// values override the [ButtonStyle] returned by
  /// [FilledButton.defaultStyleOf].
  ///
  /// If [style] is null, then this theme doesn't override anything.
  final ButtonStyle? style;

  /// Linearly interpolate between two filled button themes.
  static FilledButtonThemeData? lerp(FilledButtonThemeData? a, FilledButtonThemeData? b, double t) {
    if (a == null && b == null) {
      return null;
    }
    return FilledButtonThemeData(
      style: ButtonStyle.lerp(a?.style, b?.style, t),
    );
  }

  @override
  int get hashCode => style.hashCode;

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is FilledButtonThemeData && other.style == style;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(DiagnosticsProperty<ButtonStyle>('style', style, defaultValue: null));
  }
}

/// Overrides the default [ButtonStyle] of its [FilledButton] descendants.
///
/// See also:
///
///  * [FilledButtonThemeData], which is used to configure this theme.
///  * [FilledButton.defaultStyleOf], which returns the default [ButtonStyle]
///    for filled buttons.
///  * [FilledButton.styleFrom], which converts simple values into a
///    [ButtonStyle] that's consistent with [FilledButton]'s defaults.
///  * [ThemeData.filledButtonTheme], which can be used to override the default
///    [ButtonStyle] for [FilledButton]s below the overall [Theme].
class FilledButtonTheme extends InheritedTheme {
  /// Create a [FilledButtonTheme].
  ///
  /// The [data] parameter must not be null.
  const FilledButtonTheme({
    super.key,
    required this.data,
    required super.child,
  });

  /// The configuration of this theme.
  final FilledButtonThemeData data;

  /// The closest instance of this class that encloses the given context.
  ///
  /// If there is no enclosing [FilledButtonTheme] widget, then
  /// [ThemeData.filledButtonTheme] is used.
  ///
  /// Typical usage is as follows:
  ///
  /// ```dart
  /// FilledButtonThemeData theme = FilledButtonTheme.of(context);
  /// ```
  static FilledButtonThemeData of(BuildContext context) {
    final FilledButtonTheme? buttonTheme = context.dependOnInheritedWidgetOfExactType<FilledButtonTheme>();
    return buttonTheme?.data ?? Theme.of(context).filledButtonTheme;
  }

  @override
  Widget wrap(BuildContext context, Widget child) {
    return FilledButtonTheme(data: data, child: child);
  }

  @override
  bool updateShouldNotify(FilledButtonTheme oldWidget) => data != oldWidget.data;
}
