// 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.

/// @docImport 'package:flutter/semantics.dart';
/// @docImport 'package:flutter/widgets.dart';
/// @docImport 'package:flutter_test/flutter_test.dart';
library;

import 'dart:io' show Platform;
import 'dart:ui' as ui show FlutterView, Scene, SceneBuilder, SemanticsUpdate;

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

import 'binding.dart';
import 'box.dart';
import 'debug.dart';
import 'layer.dart';
import 'object.dart';

/// The layout constraints for the root render object.
@immutable
class ViewConfiguration {
  /// Creates a view configuration.
  ///
  /// By default, the view has [logicalConstraints] and [physicalConstraints]
  /// with all dimensions set to zero (i.e. the view is forced to [Size.zero])
  /// and a [devicePixelRatio] of 1.0.
  ///
  /// [ViewConfiguration.fromView] is a more convenient way for deriving a
  /// [ViewConfiguration] from a given [ui.FlutterView].
  const ViewConfiguration({
    this.physicalConstraints = const BoxConstraints(maxWidth: 0, maxHeight: 0),
    this.logicalConstraints = const BoxConstraints(maxWidth: 0, maxHeight: 0),
    this.devicePixelRatio = 1.0,
  });

  /// Creates a view configuration for the provided [ui.FlutterView].
  factory ViewConfiguration.fromView(ui.FlutterView view) {
    final physicalConstraints = BoxConstraints.fromViewConstraints(view.physicalConstraints);
    final double devicePixelRatio = view.devicePixelRatio;
    return ViewConfiguration(
      physicalConstraints: physicalConstraints,
      logicalConstraints: physicalConstraints / devicePixelRatio,
      devicePixelRatio: devicePixelRatio,
    );
  }

  /// The constraints of the output surface in logical pixel.
  ///
  /// The constraints are passed to the child of the root render object.
  final BoxConstraints logicalConstraints;

  /// The constraints of the output surface in physical pixel.
  ///
  /// These constraints are enforced in [toPhysicalSize] when translating
  /// the logical size of the root render object back to physical pixels for
  /// the [ui.FlutterView.render] method.
  final BoxConstraints physicalConstraints;

  /// The pixel density of the output surface.
  final double devicePixelRatio;

  /// Creates a transformation matrix that applies the [devicePixelRatio].
  ///
  /// The matrix translates points from the local coordinate system of the
  /// app (in logical pixels) to the global coordinate system of the
  /// [ui.FlutterView] (in physical pixels).
  Matrix4 toMatrix() {
    return Matrix4.diagonal3Values(devicePixelRatio, devicePixelRatio, 1.0);
  }

  /// Returns whether [toMatrix] would return a different value for this
  /// configuration than it would for the given `oldConfiguration`.
  bool shouldUpdateMatrix(ViewConfiguration oldConfiguration) {
    if (oldConfiguration.runtimeType != runtimeType) {
      // New configuration could have different logic, so we don't know
      // whether it will need a new transform. Return a conservative result.
      return true;
    }
    // For this class, the only input to toMatrix is the device pixel ratio,
    // so we return true if they differ and false otherwise.
    return oldConfiguration.devicePixelRatio != devicePixelRatio;
  }

  /// Transforms the provided [Size] in logical pixels to physical pixels.
  ///
  /// The [ui.FlutterView.render] method accepts only sizes in physical pixels, but
  /// the framework operates in logical pixels. This method is used to transform
  /// the logical size calculated for a [RenderView] back to a physical size
  /// suitable to be passed to [ui.FlutterView.render].
  ///
  /// By default, this method just multiplies the provided [Size] with the
  /// [devicePixelRatio] and constraints the results to the
  /// [physicalConstraints].
  Size toPhysicalSize(Size logicalSize) {
    return physicalConstraints.constrain(logicalSize * devicePixelRatio);
  }

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is ViewConfiguration &&
        other.logicalConstraints == logicalConstraints &&
        other.physicalConstraints == physicalConstraints &&
        other.devicePixelRatio == devicePixelRatio;
  }

  @override
  int get hashCode => Object.hash(logicalConstraints, physicalConstraints, devicePixelRatio);

  @override
  String toString() => '$logicalConstraints at ${debugFormatDouble(devicePixelRatio)}x';
}

/// The root of the render tree.
///
/// The view represents the total output surface of the render tree and handles
/// bootstrapping the rendering pipeline. The view has a unique child
/// [RenderBox], which is required to fill the entire output surface.
///
/// This object must be bootstrapped in a specific order:
///
///  1. First, set the [configuration] (either in the constructor or after
///     construction).
///  2. Second, [attach] the object to a [PipelineOwner].
///  3. Third, use [prepareInitialFrame] to bootstrap the layout and paint logic.
///
/// After the bootstrapping is complete, the [compositeFrame] method may be used
/// to obtain the rendered output.
class RenderView extends RenderObject with RenderObjectWithChildMixin<RenderBox> {
  /// Creates the root of the render tree.
  ///
  /// Typically created by the binding (e.g., [RendererBinding]).
  ///
  /// Providing a [configuration] is optional, but a configuration must be set
  /// before calling [prepareInitialFrame]. This decouples creating the
  /// [RenderView] object from configuring it. Typically, the object is created
  /// by the [View] widget and configured by the [RendererBinding] when the
  /// [RenderView] is registered with it by the [View] widget.
  RenderView({RenderBox? child, ViewConfiguration? configuration, required ui.FlutterView view})
    : _view = view {
    if (configuration != null) {
      this.configuration = configuration;
    }
    this.child = child;
  }

  /// The current layout size of the view.
  Size get size => _size;
  Size _size = Size.zero;

  /// The constraints used for the root layout.
  ///
  /// Typically, this configuration is set by the [RendererBinding], when the
  /// [RenderView] is registered with it. It will also update the configuration
  /// if necessary. Therefore, if used in conjunction with the [RendererBinding]
  /// this property must not be set manually as the [RendererBinding] will just
  /// override it.
  ///
  /// For tests that want to change the size of the view, set
  /// [TestFlutterView.physicalSize] on the appropriate [TestFlutterView]
  /// (typically [WidgetTester.view]) instead of setting a configuration
  /// directly on the [RenderView].
  ///
  /// A [configuration] must be set (either directly or by passing one to the
  /// constructor) before calling [prepareInitialFrame].
  ViewConfiguration get configuration => _configuration!;
  ViewConfiguration? _configuration;
  set configuration(ViewConfiguration value) {
    if (_configuration == value) {
      return;
    }
    final ViewConfiguration? oldConfiguration = _configuration;
    _configuration = value;
    if (_rootTransform == null) {
      // [prepareInitialFrame] has not been called yet, nothing more to do for now.
      return;
    }
    if (oldConfiguration == null || configuration.shouldUpdateMatrix(oldConfiguration)) {
      replaceRootLayer(_updateMatricesAndCreateNewRootLayer());
    }
    assert(_rootTransform != null);
    markNeedsLayout();
  }

  /// Whether a [configuration] has been set.
  ///
  /// This must be true before calling [prepareInitialFrame].
  bool get hasConfiguration => _configuration != null;

  @override
  BoxConstraints get constraints {
    if (!hasConfiguration) {
      throw StateError(
        'Constraints are not available because RenderView has not been given a configuration yet.',
      );
    }
    return configuration.logicalConstraints;
  }

  /// The [ui.FlutterView] into which this [RenderView] will render.
  ui.FlutterView get flutterView => _view;
  final ui.FlutterView _view;

  /// Whether Flutter should automatically compute the desired system UI.
  ///
  /// When this setting is enabled, Flutter will hit-test the layer tree at the
  /// top and bottom of the screen on each frame looking for an
  /// [AnnotatedRegionLayer] with an instance of a [SystemUiOverlayStyle]. The
  /// hit-test result from the top of the screen provides the status bar settings
  /// and the hit-test result from the bottom of the screen provides the system
  /// nav bar settings.
  ///
  /// If there is no [AnnotatedRegionLayer] on the bottom, the hit-test result
  /// from the top provides the system nav bar settings. If there is no
  /// [AnnotatedRegionLayer] on the top, the hit-test result from the bottom
  /// provides the system status bar settings.
  ///
  /// Setting this to false does not cause previous automatic adjustments to be
  /// reset, nor does setting it to true cause the app to update immediately.
  ///
  /// If you want to imperatively set the system ui style instead, it is
  /// recommended that [automaticSystemUiAdjustment] is set to false.
  ///
  /// See also:
  ///
  ///  * [AnnotatedRegion], for placing [SystemUiOverlayStyle] in the layer tree.
  ///  * [SystemChrome.setSystemUIOverlayStyle], for imperatively setting the system ui style.
  bool automaticSystemUiAdjustment = true;

  /// Bootstrap the rendering pipeline by preparing the first frame.
  ///
  /// This should only be called once. It is typically called immediately after
  /// setting the [configuration] the first time (whether by passing one to the
  /// constructor, or setting it directly). The [configuration] must have been
  /// set before calling this method, and the [RenderView] must have been
  /// attached to a [PipelineOwner] using [attach].
  ///
  /// This does not actually schedule the first frame. Call
  /// [PipelineOwner.requestVisualUpdate] on the [owner] to do that.
  ///
  /// This should be called before using any methods that rely on the [layer]
  /// being initialized, such as [compositeFrame].
  ///
  /// This method calls [scheduleInitialLayout] and [scheduleInitialPaint].
  void prepareInitialFrame() {
    assert(
      owner != null,
      'attach the RenderView to a PipelineOwner before calling prepareInitialFrame',
    );
    assert(
      _rootTransform == null,
      'prepareInitialFrame must only be called once',
    ); // set by _updateMatricesAndCreateNewRootLayer
    assert(hasConfiguration, 'set a configuration before calling prepareInitialFrame');
    scheduleInitialLayout();
    scheduleInitialPaint(_updateMatricesAndCreateNewRootLayer());
    assert(_rootTransform != null);
  }

  Matrix4? _rootTransform;

  TransformLayer _updateMatricesAndCreateNewRootLayer() {
    assert(hasConfiguration);
    _rootTransform = configuration.toMatrix();
    final rootLayer = TransformLayer(transform: _rootTransform);
    rootLayer.attach(this);
    assert(_rootTransform != null);
    return rootLayer;
  }

  // We never call layout() on this class, so this should never get
  // checked. (This class is laid out using scheduleInitialLayout().)
  @override
  void debugAssertDoesMeetConstraints() {
    assert(false);
  }

  @override
  void performResize() {
    assert(false);
  }

  @override
  void performLayout() {
    assert(_rootTransform != null);
    final bool sizedByChild = !constraints.isTight;
    child?.layout(constraints, parentUsesSize: sizedByChild);
    _size = sizedByChild && child != null ? child!.size : constraints.smallest;
    assert(size.isFinite);
    assert(constraints.isSatisfiedBy(size));
  }

  /// Determines the set of render objects located at the given position.
  ///
  /// Returns true if the given point is contained in this render object or one
  /// of its descendants. Adds any render objects that contain the point to the
  /// given hit test result.
  ///
  /// The [position] argument is in the coordinate system of the render view,
  /// which is to say, in logical pixels. This is not necessarily the same
  /// coordinate system as that expected by the root [Layer], which will
  /// normally be in physical (device) pixels.
  bool hitTest(HitTestResult result, {required Offset position}) {
    child?.hitTest(BoxHitTestResult.wrap(result), position: position);
    result.add(HitTestEntry(this));
    return true;
  }

  @override
  bool get isRepaintBoundary => true;

  @override
  void paint(PaintingContext context, Offset offset) {
    if (child != null) {
      context.paintChild(child!, offset);
    }
    assert(() {
      final List<DebugPaintCallback> localCallbacks = _debugPaintCallbacks.toList();
      for (final paintCallback in localCallbacks) {
        if (_debugPaintCallbacks.contains(paintCallback)) {
          paintCallback(context, offset, this);
        }
      }
      return true;
    }());
  }

  @override
  void applyPaintTransform(RenderBox child, Matrix4 transform) {
    assert(_rootTransform != null);
    transform.multiply(_rootTransform!);
    super.applyPaintTransform(child, transform);
  }

  /// Uploads the composited layer tree to the engine.
  ///
  /// Actually causes the output of the rendering pipeline to appear on screen.
  ///
  /// Before calling this method, the [owner] must be set by calling [attach],
  /// the [configuration] must be set to a non-null value, and the
  /// [prepareInitialFrame] method must have been called.
  void compositeFrame() {
    if (!kReleaseMode) {
      FlutterTimeline.startSync('COMPOSITING');
    }
    try {
      assert(hasConfiguration, 'set the RenderView configuration before calling compositeFrame');
      assert(_rootTransform != null, 'call prepareInitialFrame before calling compositeFrame');
      assert(layer != null, 'call prepareInitialFrame before calling compositeFrame');
      final ui.SceneBuilder builder = RendererBinding.instance.createSceneBuilder();
      final ui.Scene scene = layer!.buildScene(builder);
      if (automaticSystemUiAdjustment) {
        _updateSystemChrome();
      }
      assert(configuration.logicalConstraints.isSatisfiedBy(size));
      _view.render(scene, size: configuration.toPhysicalSize(size));
      scene.dispose();
      assert(() {
        if (debugRepaintRainbowEnabled || debugRepaintTextRainbowEnabled) {
          debugCurrentRepaintColor = debugCurrentRepaintColor.withHue(
            (debugCurrentRepaintColor.hue + 2.0) % 360.0,
          );
        }
        return true;
      }());
    } finally {
      if (!kReleaseMode) {
        FlutterTimeline.finishSync();
      }
    }
  }

  /// Sends the provided [ui.SemanticsUpdate] to the [ui.FlutterView] associated with
  /// this [RenderView].
  ///
  /// A [ui.SemanticsUpdate] is produced by a [SemanticsOwner] during the
  /// [EnginePhase.flushSemantics] phase.
  void updateSemantics(ui.SemanticsUpdate update) {
    _view.updateSemantics(update);
  }

  void _updateSystemChrome() {
    // Take overlay style from the place where a system status bar and system
    // navigation bar are placed to update system style overlay.
    // The center of the system navigation bar and the center of the status bar
    // are used to get SystemUiOverlayStyle's to update system overlay appearance.
    //
    //         Horizontal center of the screen
    //                 V
    //    ++++++++++++++++++++++++++
    //    |                        |
    //    |    System status bar   |  <- Vertical center of the status bar
    //    |                        |
    //    ++++++++++++++++++++++++++
    //    |                        |
    //    |        Content         |
    //    ~                        ~
    //    |                        |
    //    ++++++++++++++++++++++++++
    //    |                        |
    //    |  System navigation bar | <- Vertical center of the navigation bar
    //    |                        |
    //    ++++++++++++++++++++++++++ <- bounds.bottom
    final Rect bounds = paintBounds;
    // Center of the status bar
    final top = Offset(
      // Horizontal center of the screen
      bounds.center.dx,
      // The vertical center of the system status bar. The system status bar
      // height is kept as top window padding.
      _view.padding.top / 2.0,
    );
    // Center of the navigation bar
    final bottom = Offset(
      // Horizontal center of the screen
      bounds.center.dx,
      // Vertical center of the system navigation bar. The system navigation bar
      // height is kept as bottom window padding. The "1" needs to be subtracted
      // from the bottom because available pixels are in (0..bottom) range.
      // I.e. for a device with 1920 height, bound.bottom is 1920, but the most
      // bottom drawn pixel is at 1919 position.
      bounds.bottom - 1.0 - _view.padding.bottom / 2.0,
    );
    final SystemUiOverlayStyle? upperOverlayStyle = layer!.find<SystemUiOverlayStyle>(top);
    // Only android has a customizable system navigation bar.
    SystemUiOverlayStyle? lowerOverlayStyle;
    switch (defaultTargetPlatform) {
      case TargetPlatform.android:
        lowerOverlayStyle = layer!.find<SystemUiOverlayStyle>(bottom);
      case TargetPlatform.fuchsia:
      case TargetPlatform.iOS:
      case TargetPlatform.linux:
      case TargetPlatform.macOS:
      case TargetPlatform.windows:
        break;
    }
    // If there are no overlay style in the UI don't bother updating.
    if (upperOverlayStyle == null && lowerOverlayStyle == null) {
      return;
    }

    // If both are not null, the upper provides the status bar properties and the lower provides
    // the system navigation bar properties. This is done for advanced use cases where a widget
    // on the top (for instance an app bar) will create an annotated region to set the status bar
    // style and another widget on the bottom will create an annotated region to set the system
    // navigation bar style.
    if (upperOverlayStyle != null && lowerOverlayStyle != null) {
      final overlayStyle = SystemUiOverlayStyle(
        statusBarBrightness: upperOverlayStyle.statusBarBrightness,
        statusBarIconBrightness: upperOverlayStyle.statusBarIconBrightness,
        statusBarColor: upperOverlayStyle.statusBarColor,
        systemStatusBarContrastEnforced: upperOverlayStyle.systemStatusBarContrastEnforced,
        systemNavigationBarColor: lowerOverlayStyle.systemNavigationBarColor,
        systemNavigationBarDividerColor: lowerOverlayStyle.systemNavigationBarDividerColor,
        systemNavigationBarIconBrightness: lowerOverlayStyle.systemNavigationBarIconBrightness,
        systemNavigationBarContrastEnforced: lowerOverlayStyle.systemNavigationBarContrastEnforced,
      );
      SystemChrome.setSystemUIOverlayStyle(overlayStyle);
      return;
    }
    // If only one of the upper or the lower overlay style is not null, it provides all properties.
    // This is done for developer convenience as it allows setting both status bar style and
    // navigation bar style using only one annotated region layer (for instance the one
    // automatically created by an [AppBar]).
    final isAndroid = defaultTargetPlatform == TargetPlatform.android;
    final SystemUiOverlayStyle definedOverlayStyle = (upperOverlayStyle ?? lowerOverlayStyle)!;
    final overlayStyle = SystemUiOverlayStyle(
      statusBarBrightness: definedOverlayStyle.statusBarBrightness,
      statusBarIconBrightness: definedOverlayStyle.statusBarIconBrightness,
      statusBarColor: definedOverlayStyle.statusBarColor,
      systemStatusBarContrastEnforced: definedOverlayStyle.systemStatusBarContrastEnforced,
      systemNavigationBarColor: isAndroid ? definedOverlayStyle.systemNavigationBarColor : null,
      systemNavigationBarDividerColor: isAndroid
          ? definedOverlayStyle.systemNavigationBarDividerColor
          : null,
      systemNavigationBarIconBrightness: isAndroid
          ? definedOverlayStyle.systemNavigationBarIconBrightness
          : null,
      systemNavigationBarContrastEnforced: isAndroid
          ? definedOverlayStyle.systemNavigationBarContrastEnforced
          : null,
    );
    SystemChrome.setSystemUIOverlayStyle(overlayStyle);
  }

  @override
  Rect get paintBounds => Offset.zero & (size * configuration.devicePixelRatio);

  @override
  Rect get semanticBounds {
    assert(_rootTransform != null);
    return MatrixUtils.transformRect(_rootTransform!, Offset.zero & size);
  }

  @override
  void debugFillProperties(DiagnosticPropertiesBuilder properties) {
    // call to ${super.debugFillProperties(description)} is omitted because the
    // root superclasses don't include any interesting information for this
    // class
    assert(() {
      properties.add(
        DiagnosticsNode.message(
          'debug mode enabled - ${kIsWeb ? 'Web' : Platform.operatingSystem}',
        ),
      );
      return true;
    }());
    properties.add(
      DiagnosticsProperty<Size>('view size', _view.physicalSize, tooltip: 'in physical pixels'),
    );
    properties.add(
      DoubleProperty(
        'device pixel ratio',
        _view.devicePixelRatio,
        tooltip: 'physical pixels per logical pixel',
      ),
    );
    properties.add(
      DiagnosticsProperty<ViewConfiguration>(
        'configuration',
        configuration,
        tooltip: 'in logical pixels',
      ),
    );
    if (_view.platformDispatcher.semanticsEnabled) {
      properties.add(DiagnosticsNode.message('semantics enabled'));
    }
  }

  static final List<DebugPaintCallback> _debugPaintCallbacks = <DebugPaintCallback>[];

  /// Registers a [DebugPaintCallback] that is called every time a [RenderView]
  /// repaints in debug mode.
  ///
  /// The callback may paint a debug overlay on top of the content of the
  /// [RenderView] provided to the callback. Callbacks are invoked in the
  /// order they were registered in.
  ///
  /// Neither registering a callback nor the continued presence of a callback
  /// changes how often [RenderView]s are repainted. It is up to the owner of
  /// the callback to call [markNeedsPaint] on any [RenderView] for which it
  /// wants to update the painted overlay.
  ///
  /// Does nothing in release mode.
  static void debugAddPaintCallback(DebugPaintCallback callback) {
    assert(() {
      _debugPaintCallbacks.add(callback);
      return true;
    }());
  }

  /// Removes a callback registered with [debugAddPaintCallback].
  ///
  /// It does not schedule a frame to repaint the [RenderView]s without the
  /// overlay painted by the removed callback. It is up to the owner of the
  /// callback to call [markNeedsPaint] on the relevant [RenderView]s to
  /// repaint them without the overlay.
  ///
  /// Does nothing in release mode.
  static void debugRemovePaintCallback(DebugPaintCallback callback) {
    assert(() {
      _debugPaintCallbacks.remove(callback);
      return true;
    }());
  }
}

/// A callback for painting a debug overlay on top of the provided [RenderView].
///
/// Used by [RenderView.debugAddPaintCallback] and
/// [RenderView.debugRemovePaintCallback].
typedef DebugPaintCallback =
    void Function(PaintingContext context, Offset offset, RenderView renderView);
