// 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 'basic.dart';
import 'framework.dart';
import 'icon_theme_data.dart';
import 'inherited_theme.dart';

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

/// Controls the default properties of icons in a widget subtree.
///
/// The icon theme is honored by [Icon] and [ImageIcon] widgets.
class IconTheme extends InheritedTheme {
  /// Creates an icon theme that controls properties of descendant widgets.
  ///
  /// Both [data] and [child] arguments must not be null.
  const IconTheme({
    super.key,
    required this.data,
    required super.child,
  }) : assert(data != null),
       assert(child != null);

  /// Creates an icon theme that controls the properties of
  /// descendant widgets, and merges in the current icon theme, if any.
  ///
  /// The [data] and [child] arguments must not be null.
  static Widget merge({
    Key? key,
    required IconThemeData data,
    required Widget child,
  }) {
    return Builder(
      builder: (BuildContext context) {
        return IconTheme(
          key: key,
          data: _getInheritedIconThemeData(context).merge(data),
          child: child,
        );
      },
    );
  }

  /// The set of properties to use for icons in this subtree.
  final IconThemeData data;

  /// The data from the closest instance of this class that encloses the given
  /// context, if any.
  ///
  /// If there is no ambient icon theme, defaults to [IconThemeData.fallback].
  /// The returned [IconThemeData] is concrete (all values are non-null; see
  /// [IconThemeData.isConcrete]). Any properties on the ambient icon theme that
  /// are null get defaulted to the values specified on
  /// [IconThemeData.fallback].
  ///
  /// The [Theme] widget from the `material` library introduces an [IconTheme]
  /// widget set to the [ThemeData.iconTheme], so in a Material Design
  /// application, this will typically default to the icon theme from the
  /// ambient [Theme].
  ///
  /// Typical usage is as follows:
  ///
  /// ```dart
  /// IconThemeData theme = IconTheme.of(context);
  /// ```
  static IconThemeData of(BuildContext context) {
    final IconThemeData iconThemeData = _getInheritedIconThemeData(context).resolve(context);
    return iconThemeData.isConcrete
      ? iconThemeData
      : iconThemeData.copyWith(
        size: iconThemeData.size ?? const IconThemeData.fallback().size,
        fill: iconThemeData.fill ?? const IconThemeData.fallback().fill,
        weight: iconThemeData.weight ?? const IconThemeData.fallback().weight,
        grade: iconThemeData.grade ?? const IconThemeData.fallback().grade,
        opticalSize: iconThemeData.opticalSize ?? const IconThemeData.fallback().opticalSize,
        color: iconThemeData.color ?? const IconThemeData.fallback().color,
        opacity: iconThemeData.opacity ?? const IconThemeData.fallback().opacity,
        shadows: iconThemeData.shadows ?? const IconThemeData.fallback().shadows,
      );
  }

  static IconThemeData _getInheritedIconThemeData(BuildContext context) {
    final IconTheme? iconTheme = context.dependOnInheritedWidgetOfExactType<IconTheme>();
    return iconTheme?.data ?? const IconThemeData.fallback();
  }

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

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

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    data.debugFillProperties(properties);
  }
}
