// 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 'framework.dart';

// Examples can assume:
// TooltipThemeData data = const TooltipThemeData();

/// An [InheritedWidget] that defines visual properties like colors
/// and text styles, which the [child]'s subtree depends on.
///
/// The [wrap] method is used by [captureAll] and [CapturedThemes.wrap] to
/// construct a widget that will wrap a child in all of the inherited themes
/// which are present in a specified part of the widget tree.
///
/// A widget that's shown in a different context from the one it's built in,
/// like the contents of a new route or an overlay, will be able to see the
/// ancestor inherited themes of the context it was built in.
///
/// {@tool dartpad}
/// This example demonstrates how `InheritedTheme.capture()` can be used
/// to wrap the contents of a new route with the inherited themes that
/// are present when the route was built - but are not present when route
/// is actually shown.
///
/// If the same code is run without `InheritedTheme.capture(), the
/// new route's Text widget will inherit the "something must be wrong"
/// fallback text style, rather than the default text style defined in MyApp.
///
/// ** See code in examples/api/lib/widgets/inherited_theme/inherited_theme.0.dart **
/// {@end-tool}
abstract class InheritedTheme extends InheritedWidget {
  /// Abstract const constructor. This constructor enables subclasses to provide
  /// const constructors so that they can be used in const expressions.

  const InheritedTheme({
    super.key,
    required super.child,
  });

  /// Return a copy of this inherited theme with the specified [child].
  ///
  /// This implementation for [TooltipTheme] is typical:
  ///
  /// ```dart
  /// Widget wrap(BuildContext context, Widget child) {
  ///   return TooltipTheme(data: data, child: child);
  /// }
  /// ```
  Widget wrap(BuildContext context, Widget child);

  /// Returns a widget that will [wrap] `child` in all of the inherited themes
  /// which are present between `context` and the specified `to`
  /// [BuildContext].
  ///
  /// The `to` context must be an ancestor of `context`. If `to` is not
  /// specified, all inherited themes up to the root of the widget tree are
  /// captured.
  ///
  /// After calling this method, the themes present between `context` and `to`
  /// are frozen for the provided `child`. If the themes (or their theme data)
  /// change in the original subtree, those changes will not be visible to
  /// the wrapped `child` - unless this method is called again to re-wrap the
  /// child.
  static Widget captureAll(BuildContext context, Widget child, {BuildContext? to}) {

    return capture(from: context, to: to).wrap(child);
  }

  /// Returns a [CapturedThemes] object that includes all the [InheritedTheme]s
  /// between the given `from` and `to` [BuildContext]s.
  ///
  /// The `to` context must be an ancestor of the `from` context. If `to` is
  /// null, all ancestor inherited themes of `from` up to the root of the
  /// widget tree are captured.
  ///
  /// After calling this method, the themes present between `from` and `to` are
  /// frozen in the returned [CapturedThemes] object. If the themes (or their
  /// theme data) change in the original subtree, those changes will not be
  /// applied to the themes captured in the [CapturedThemes] object - unless
  /// this method is called again to re-capture the updated themes.
  ///
  /// To wrap a [Widget] in the captured themes, call [CapturedThemes.wrap].
  ///
  /// This method can be expensive if there are many widgets between `from` and
  /// `to` (it walks the element tree between those nodes).
  static CapturedThemes capture({ required BuildContext from, required BuildContext? to }) {

    if (from == to) {
      // Nothing to capture.
      return CapturedThemes._(const <InheritedTheme>[]);
    }

    final List<InheritedTheme> themes = <InheritedTheme>[];
    final Set<Type> themeTypes = <Type>{};
    late bool debugDidFindAncestor;
    assert(() {
      debugDidFindAncestor = to == null;
      return true;
    }());
    from.visitAncestorElements((Element ancestor) {
      if (ancestor == to) {
        assert(() {
          debugDidFindAncestor = true;
          return true;
        }());
        return false;
      }
      if (ancestor is InheritedElement && ancestor.widget is InheritedTheme) {
        final InheritedTheme theme = ancestor.widget as InheritedTheme;
        final Type themeType = theme.runtimeType;
        // Only remember the first theme of any type. This assumes
        // that inherited themes completely shadow ancestors of the
        // same type.
        if (!themeTypes.contains(themeType)) {
          themeTypes.add(themeType);
          themes.add(theme);
        }
      }
      return true;
    });

    assert(debugDidFindAncestor, 'The provided `to` context must be an ancestor of the `from` context.');
    return CapturedThemes._(themes);
  }
}

/// Stores a list of captured [InheritedTheme]s that can be wrapped around a
/// child [Widget].
///
/// Used as return type by [InheritedTheme.capture].
class CapturedThemes {
  CapturedThemes._(this._themes);

  final List<InheritedTheme> _themes;

  /// Wraps a `child` [Widget] in the [InheritedTheme]s captured in this object.
  Widget wrap(Widget child) {
    return _CaptureAll(themes: _themes, child: child);
  }
}

class _CaptureAll extends StatelessWidget {
  const _CaptureAll({
    required this.themes,
    required this.child,
  });

  final List<InheritedTheme> themes;
  final Widget child;

  @override
  Widget build(BuildContext context) {
    Widget wrappedChild = child;
    for (final InheritedTheme theme in themes) {
      wrappedChild = theme.wrap(context, wrappedChild);
    }
    return wrappedChild;
  }
}
