// 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:math' as math;
import 'dart:ui' show DisplayFeature, DisplayFeatureState;

import 'basic.dart';
import 'debug.dart';
import 'framework.dart';
import 'media_query.dart';

/// Positions [child] such that it avoids overlapping any [DisplayFeature] that
/// splits the screen into sub-screens.
///
/// A [DisplayFeature] splits the screen into sub-screens when both these
/// conditions are met:
///
///   * it obstructs the screen, meaning the area it occupies is not 0 or the
///     `state` is [DisplayFeatureState.postureHalfOpened].
///   * it is at least as tall as the screen, producing a left and right
///     sub-screen or it is at least as wide as the screen, producing a top and
///     bottom sub-screen
///
/// After determining the sub-screens, the closest one to [anchorPoint] is used
/// to render the content.
///
/// If no [anchorPoint] is provided, then [Directionality] is used:
///
///   * for [TextDirection.ltr], [anchorPoint] is `Offset.zero`, which will
///     cause the content to appear in the top-left sub-screen.
///   * for [TextDirection.rtl], [anchorPoint] is `Offset(double.maxFinite, 0)`,
///     which will cause the content to appear in the top-right sub-screen.
///
/// If no [anchorPoint] is provided, and there is no [Directionality] ancestor
/// widget in the tree, then the widget asserts during build in debug mode.
///
/// Similarly to [SafeArea], this widget assumes there is no added padding
/// between it and the first [MediaQuery] ancestor. The [child] is wrapped in a
/// new [MediaQuery] instance containing the [DisplayFeature]s that exist in the
/// selected sub-screen, with coordinates relative to the sub-screen. Padding is
/// also adjusted to zero out any sides that were avoided by this widget.
///
/// See also:
///
///  * [showDialog], which is a way to display a [DialogRoute].
///  * [showCupertinoDialog], which displays an iOS-style dialog.
class DisplayFeatureSubScreen extends StatelessWidget {
  /// Creates a widget that positions its child so that it avoids display
  /// features.
  const DisplayFeatureSubScreen({
    super.key,
    this.anchorPoint,
    required this.child,
  });

  /// {@template flutter.widgets.DisplayFeatureSubScreen.anchorPoint}
  /// The anchor point used to pick the closest sub-screen.
  ///
  /// If the anchor point sits inside one of these sub-screens, then that
  /// sub-screen is picked. If not, then the sub-screen with the closest edge to
  /// the point is used.
  ///
  /// [Offset.zero] is the top-left corner of the available screen space. For a
  /// vertically split dual-screen device, this is the top-left corner of the
  /// left screen.
  ///
  /// When this is null, [Directionality] is used:
  ///
  ///   * for [TextDirection.ltr], [anchorPoint] is [Offset.zero], which will
  ///     cause the top-left sub-screen to be picked.
  ///   * for [TextDirection.rtl], [anchorPoint] is
  ///     `Offset(double.maxFinite, 0)`, which will cause the top-right
  ///     sub-screen to be picked.
  /// {@endtemplate}
  final Offset? anchorPoint;

  /// The widget below this widget in the tree.
  ///
  /// The padding on the [MediaQuery] for the [child] will be suitably adjusted
  /// to zero out any sides that were avoided by this widget. The [MediaQuery]
  /// for the [child] will no longer contain any display features that split the
  /// screen into sub-screens.
  ///
  /// {@macro flutter.widgets.ProxyWidget.child}
  final Widget child;

  @override
  Widget build(BuildContext context) {
    assert(anchorPoint != null || debugCheckHasDirectionality(
        context,
        why: 'to determine which sub-screen DisplayFeatureSubScreen uses',
        alternative: "Alternatively, consider specifying the 'anchorPoint' argument on the DisplayFeatureSubScreen.",
    ));
    final MediaQueryData mediaQuery = MediaQuery.of(context);
    final Size parentSize = mediaQuery.size;
    final Rect wantedBounds = Offset.zero & parentSize;
    final Offset resolvedAnchorPoint = _capOffset(anchorPoint ?? _fallbackAnchorPoint(context), parentSize);
    final Iterable<Rect> subScreens = subScreensInBounds(wantedBounds, avoidBounds(mediaQuery));
    final Rect closestSubScreen = _closestToAnchorPoint(subScreens, resolvedAnchorPoint);

    return Padding(
      padding: EdgeInsets.only(
        left: closestSubScreen.left,
        top: closestSubScreen.top,
        right: parentSize.width - closestSubScreen.right,
        bottom: parentSize.height - closestSubScreen.bottom,
      ),
      child: MediaQuery(
        data: mediaQuery.removeDisplayFeatures(closestSubScreen),
        child: child,
      ),
    );
  }

  static Offset _fallbackAnchorPoint(BuildContext context) {
    final TextDirection textDirection = Directionality.of(context);
    switch (textDirection) {
      case TextDirection.rtl:
        return const Offset(double.maxFinite, 0);
      case TextDirection.ltr:
        return Offset.zero;
    }
  }

  /// Returns the areas of the screen that are obstructed by display features.
  ///
  /// A [DisplayFeature] obstructs the screen when the area it occupies is
  /// not 0 or the `state` is [DisplayFeatureState.postureHalfOpened].
  static Iterable<Rect> avoidBounds(MediaQueryData mediaQuery) {
    return mediaQuery.displayFeatures
        .where((DisplayFeature d) => d.bounds.shortestSide > 0 ||
            d.state == DisplayFeatureState.postureHalfOpened)
        .map((DisplayFeature d) => d.bounds);
  }

  /// Returns the closest sub-screen to the [anchorPoint].
  static Rect _closestToAnchorPoint(Iterable<Rect> subScreens, Offset anchorPoint) {
    Rect closestScreen = subScreens.first;
    double closestDistance = _distanceFromPointToRect(anchorPoint, closestScreen);
    for (final Rect screen in subScreens) {
      final double subScreenDistance = _distanceFromPointToRect(anchorPoint, screen);
      if (subScreenDistance < closestDistance) {
        closestScreen = screen;
        closestDistance = subScreenDistance;
      }
    }
    return closestScreen;
  }

  static double _distanceFromPointToRect(Offset point, Rect rect) {
    // Cases for point position relative to rect:
    // 1  2  3
    // 4 [R] 5
    // 6  7  8
    if (point.dx < rect.left) {
      if (point.dy < rect.top) {
        // Case 1
        return (point - rect.topLeft).distance;
      } else if (point.dy > rect.bottom) {
        // Case 6
        return (point - rect.bottomLeft).distance;
      } else {
        // Case 4
        return rect.left - point.dx;
      }
    } else if (point.dx > rect.right) {
      if (point.dy < rect.top) {
        // Case 3
        return (point - rect.topRight).distance;
      } else if (point.dy > rect.bottom) {
        // Case 8
        return (point - rect.bottomRight).distance;
      } else {
        // Case 5
        return point.dx - rect.right;
      }
    } else {
      if (point.dy < rect.top) {
        // Case 2
        return rect.top - point.dy;
      } else if (point.dy > rect.bottom) {
        // Case 7
        return point.dy - rect.bottom;
      } else {
        // Case R
        return 0;
      }
    }
  }

  /// Returns sub-screens resulted by dividing [wantedBounds] along items of
  /// [avoidBounds] that are at least as tall or as wide.
  static Iterable<Rect> subScreensInBounds(Rect wantedBounds, Iterable<Rect> avoidBounds) {
    Iterable<Rect> subScreens = <Rect>[wantedBounds];
    for (final Rect bounds in avoidBounds) {
      final List<Rect> newSubScreens = <Rect>[];
      for (final Rect screen in subScreens) {
        if (screen.top >= bounds.top && screen.bottom <= bounds.bottom) {
          // Display feature splits the screen vertically
          if (screen.left < bounds.left) {
            // There is a smaller sub-screen, left of the display feature
            newSubScreens.add(Rect.fromLTWH(
              screen.left,
              screen.top,
              bounds.left - screen.left,
              screen.height,
            ));
          }
          if (screen.right > bounds.right) {
            // There is a smaller sub-screen, right of the display feature
            newSubScreens.add(Rect.fromLTWH(
              bounds.right,
              screen.top,
              screen.right - bounds.right,
              screen.height,
            ));
          }
        } else if (screen.left >= bounds.left && screen.right <= bounds.right) {
          // Display feature splits the sub-screen horizontally
          if (screen.top < bounds.top) {
            // There is a smaller sub-screen, above the display feature
            newSubScreens.add(Rect.fromLTWH(
              screen.left,
              screen.top,
              screen.width,
              bounds.top - screen.top,
            ));
          }
          if (screen.bottom > bounds.bottom) {
            // There is a smaller sub-screen, below the display feature
            newSubScreens.add(Rect.fromLTWH(
              screen.left,
              bounds.bottom,
              screen.width,
              screen.bottom - bounds.bottom,
            ));
          }
        } else {
          newSubScreens.add(screen);
        }
      }
      subScreens = newSubScreens;
    }
    return subScreens;
  }

  static Offset _capOffset(Offset offset, Size maximum) {
    if (offset.dx >= 0 && offset.dx <= maximum.width
        && offset.dy >=0 && offset.dy <= maximum.height) {
      return offset;
    } else {
      return Offset(
        math.min(math.max(0, offset.dx), maximum.width),
        math.min(math.max(0, offset.dy), maximum.height),
      );
    }
  }
}
