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

/// Indicates the visual level for a piece of content. Equivalent to `UIUserInterfaceLevel`
/// from `UIKit`.
///
/// See also:
///
///  * `UIUserInterfaceLevel`, the UIKit equivalent: https://developer.apple.com/documentation/uikit/uiuserinterfacelevel.
enum CupertinoUserInterfaceLevelData {
  /// The level for your window's main content.
  base,

  /// The level for content visually above [base].
  elevated,
}

/// Establishes a subtree in which [CupertinoUserInterfaceLevel.of] resolves to
/// the given data.
///
/// Querying the current elevation status using [CupertinoUserInterfaceLevel.of]
/// will cause your widget to rebuild automatically whenever the
/// [CupertinoUserInterfaceLevelData] changes.
///
/// If no [CupertinoUserInterfaceLevel] is in scope then the
/// [CupertinoUserInterfaceLevel.of] method will throw an exception.
/// Alternatively, [CupertinoUserInterfaceLevel.maybeOf] can be used, which
/// returns null instead of throwing if no [CupertinoUserInterfaceLevel] is in
/// scope.
///
/// See also:
///
///  * [CupertinoUserInterfaceLevelData], specifies the visual level for the content
///    in the subtree [CupertinoUserInterfaceLevel] established.
class CupertinoUserInterfaceLevel extends InheritedWidget {
  /// Creates a [CupertinoUserInterfaceLevel] to change descendant Cupertino widget's
  /// visual level.
  const CupertinoUserInterfaceLevel({
    Key? key,
    required CupertinoUserInterfaceLevelData data,
    required Widget child,
  }) : assert(data != null),
      _data = data,
      super(key: key, child: child);

  final CupertinoUserInterfaceLevelData _data;

  @override
  bool updateShouldNotify(CupertinoUserInterfaceLevel oldWidget) => oldWidget._data != _data;

  /// The data from the closest instance of this class that encloses the given
  /// context.
  ///
  /// You can use this function to query the user interface elevation level within
  /// the given [BuildContext]. When that information changes, your widget will
  /// be scheduled to be rebuilt, keeping your widget up-to-date.
  ///
  /// See also:
  ///
  ///  * [maybeOf], which is similar, but will return null if no
  ///    [CupertinoUserInterfaceLevel] encloses the given context.
  static CupertinoUserInterfaceLevelData of(BuildContext context) {
    assert(context != null);
    final CupertinoUserInterfaceLevel? query = context.dependOnInheritedWidgetOfExactType<CupertinoUserInterfaceLevel>();
    if (query != null)
      return query._data;
    throw FlutterError(
      'CupertinoUserInterfaceLevel.of() called with a context that does not contain a CupertinoUserInterfaceLevel.\n'
      'No CupertinoUserInterfaceLevel ancestor could be found starting from the context that was passed '
      'to CupertinoUserInterfaceLevel.of(). This can happen because you do not have a WidgetsApp or '
      'MaterialApp widget (those widgets introduce a CupertinoUserInterfaceLevel), or it can happen '
      'if the context you use comes from a widget above those widgets.\n'
      'The context used was:\n'
      '  $context',
    );
  }

  /// The data from the closest instance of this class that encloses the given
  /// context, if there is one.
  ///
  /// Returns null if no [CupertinoUserInterfaceLevel] encloses the given context.
  ///
  /// You can use this function to query the user interface elevation level within
  /// the given [BuildContext]. When that information changes, your widget will
  /// be scheduled to be rebuilt, keeping your widget up-to-date.
  ///
  /// See also:
  ///
  ///  * [of], which is similar, but will throw an exception if no
  ///    [CupertinoUserInterfaceLevel] encloses the given context.
  static CupertinoUserInterfaceLevelData? maybeOf(BuildContext context) {
    assert(context != null);
    final CupertinoUserInterfaceLevel? query = context.dependOnInheritedWidgetOfExactType<CupertinoUserInterfaceLevel>();
    if (query != null)
      return query._data;
    return null;
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    super.debugFillProperties(properties);
    properties.add(EnumProperty<CupertinoUserInterfaceLevelData>('user interface level', _data));
  }
}
