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

// @dart = 2.12
part of engine;

/// When set to true, all platform messages will be printed to the console.
const bool/*!*/ _debugPrintPlatformMessages = false;

/// Whether [_customUrlStrategy] has been set or not.
///
/// It is valid to set [_customUrlStrategy] to null, so we can't use a null
/// check to determine whether it was set or not. We need an extra boolean.
bool _isUrlStrategySet = false;

/// A custom URL strategy set by the app before running.
UrlStrategy? _customUrlStrategy;
set customUrlStrategy(UrlStrategy? strategy) {
  assert(!_isUrlStrategySet, 'Cannot set URL strategy more than once.');
  _isUrlStrategySet = true;
  _customUrlStrategy = strategy;
}

/// The Web implementation of [ui.SingletonFlutterWindow].
class EngineFlutterWindow extends ui.SingletonFlutterWindow {
  EngineFlutterWindow(this._windowId, this.platformDispatcher) {
    final EnginePlatformDispatcher engineDispatcher = platformDispatcher as EnginePlatformDispatcher;
    engineDispatcher._windows[_windowId] = this;
    engineDispatcher._windowConfigurations[_windowId] = ui.ViewConfiguration();
    if (_isUrlStrategySet) {
      _browserHistory =
          MultiEntriesBrowserHistory(urlStrategy: _customUrlStrategy);
    }
    registerHotRestartListener(() {
      window.resetHistory();
    });
  }

  final Object _windowId;
  final ui.PlatformDispatcher platformDispatcher;

  /// Handles the browser history integration to allow users to use the back
  /// button, etc.
  @visibleForTesting
  BrowserHistory get browserHistory {
    return _browserHistory ??=
        MultiEntriesBrowserHistory(urlStrategy: _urlStrategyForInitialization);
  }

  UrlStrategy? get _urlStrategyForInitialization {
    final UrlStrategy? urlStrategy = _isUrlStrategySet
        ? _customUrlStrategy
        : _createDefaultUrlStrategy();
    // Prevent any further customization of URL strategy.
    _isUrlStrategySet = true;
    return urlStrategy;
  }

  BrowserHistory? _browserHistory;
  bool _usingRouter = false;
  Future<void> _useSingleEntryBrowserHistory() async {
    if (_browserHistory is SingleEntryBrowserHistory) {
      return;
    }

    final UrlStrategy? strategy;
    if (_browserHistory == null) {
      strategy = _urlStrategyForInitialization;
    } else {
      strategy = _browserHistory?.urlStrategy;
      await _browserHistory?.tearDown();
    }
    _browserHistory = SingleEntryBrowserHistory(urlStrategy: strategy);
  }

  Future<void> _useMultiEntryBrowserHistory() async {
    if (_browserHistory is MultiEntriesBrowserHistory) {
      return;
    }

    final UrlStrategy? strategy;
    if (_browserHistory == null) {
      strategy = _urlStrategyForInitialization;
    } else {
      strategy = _browserHistory?.urlStrategy;
      await _browserHistory?.tearDown();
    }
    _browserHistory = MultiEntriesBrowserHistory(urlStrategy: strategy);
  }

  @visibleForTesting
  Future<void> debugInitializeHistory(
    UrlStrategy? strategy, {
    required bool useSingle,
  }) async {
    // Prevent any further customization of URL strategy.
    _isUrlStrategySet = true;
    _usingRouter = false;
    await _browserHistory?.tearDown();
    if (useSingle) {
      _browserHistory = SingleEntryBrowserHistory(urlStrategy: strategy);
    } else {
      _browserHistory = MultiEntriesBrowserHistory(urlStrategy: strategy);
    }
  }

  Future<void> resetHistory() async {
    await _browserHistory?.tearDown();
    _browserHistory = null;
    // Reset the globals too.
    _usingRouter = false;
    _isUrlStrategySet = false;
    _customUrlStrategy = null;
  }

  Future<bool> handleNavigationMessage(
      ByteData? data,
      ) async {
    final MethodCall decoded = JSONMethodCodec().decodeMethodCall(data);
    final Map<String, dynamic> arguments = decoded.arguments;

    switch (decoded.method) {
      case 'routeUpdated':
        if (!_usingRouter) {
          await _useSingleEntryBrowserHistory();
          browserHistory.setRouteName(arguments['routeName']);
        } else {
          assert(
            false,
            'Receives old navigator update in a router application. '
            'This can happen if you use non-router versions of MaterialApp/'
            'CupertinoApp/WidgetsApp together with the router versions of them.'
          );
          return false;
        }
        return true;
      case 'routeInformationUpdated':
        await _useMultiEntryBrowserHistory();
        _usingRouter = true;
        browserHistory.setRouteName(
          arguments['location'],
          state: arguments['state'],
        );
        return true;
    }
    return false;
  }

  @override
  ui.ViewConfiguration get viewConfiguration {
    final EnginePlatformDispatcher engineDispatcher = platformDispatcher as EnginePlatformDispatcher;
    assert(engineDispatcher._windowConfigurations.containsKey(_windowId));
    return engineDispatcher._windowConfigurations[_windowId] ?? ui.ViewConfiguration();
  }

  @override
  ui.Size get physicalSize {
    if (_physicalSize == null) {
      _computePhysicalSize();
    }
    assert(_physicalSize != null);
    return _physicalSize!;
  }

  /// Computes the physical size of the screen from [html.window].
  ///
  /// This function is expensive. It triggers browser layout if there are
  /// pending DOM writes.
  void _computePhysicalSize() {
    bool override = false;

    assert(() {
      if (webOnlyDebugPhysicalSizeOverride != null) {
        _physicalSize = webOnlyDebugPhysicalSizeOverride;
        override = true;
      }
      return true;
    }());

    if (!override) {
      double windowInnerWidth;
      double windowInnerHeight;
      final html.VisualViewport? viewport = html.window.visualViewport;
      if (viewport != null) {
        windowInnerWidth = viewport.width!.toDouble() * devicePixelRatio;
        windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio;
      } else {
        windowInnerWidth = html.window.innerWidth! * devicePixelRatio;
        windowInnerHeight = html.window.innerHeight! * devicePixelRatio;
      }
      _physicalSize = ui.Size(
        windowInnerWidth,
        windowInnerHeight,
      );
    }
  }

  void computeOnScreenKeyboardInsets() {
    double windowInnerHeight;
    final html.VisualViewport? viewport = html.window.visualViewport;
    if (viewport != null) {
      windowInnerHeight = viewport.height!.toDouble() * devicePixelRatio;
    } else {
      windowInnerHeight = html.window.innerHeight! * devicePixelRatio;
    }
    final double bottomPadding = _physicalSize!.height - windowInnerHeight;
    _viewInsets =
        WindowPadding(bottom: bottomPadding, left: 0, right: 0, top: 0);
  }

  /// Uses the previous physical size and current innerHeight/innerWidth
  /// values to decide if a device is rotating.
  ///
  /// During a rotation the height and width values will (almost) swap place.
  /// Values can slightly differ due to space occupied by the browser header.
  /// For example the following values are collected for Pixel 3 rotation:
  ///
  /// height: 658 width: 393
  /// new height: 313 new width: 738
  ///
  /// The following values are from a changed caused by virtual keyboard.
  ///
  /// height: 658 width: 393
  /// height: 368 width: 393
  bool isRotation() {
    double height = 0;
    double width = 0;
    if (html.window.visualViewport != null) {
      height =
          html.window.visualViewport!.height!.toDouble() * devicePixelRatio;
      width = html.window.visualViewport!.width!.toDouble() * devicePixelRatio;
    } else {
      height = html.window.innerHeight! * devicePixelRatio;
      width = html.window.innerWidth! * devicePixelRatio;
    }

    // This method compares the new dimensions with the previous ones.
    // Return false if the previous dimensions are not set.
    if (_physicalSize != null) {
      // First confirm both height and width are effected.
      if (_physicalSize!.height != height && _physicalSize!.width != width) {
        // If prior to rotation height is bigger than width it should be the
        // opposite after the rotation and vice versa.
        if ((_physicalSize!.height > _physicalSize!.width && height < width) ||
            (_physicalSize!.width > _physicalSize!.height && width < height)) {
          // Rotation detected
          return true;
        }
      }
    }
    return false;
  }

  @override
  WindowPadding get viewInsets => _viewInsets;
  WindowPadding _viewInsets = ui.WindowPadding.zero as WindowPadding;

  /// Lazily populated and cleared at the end of the frame.
  ui.Size? _physicalSize;

  /// Overrides the value of [physicalSize] in tests.
  ui.Size? webOnlyDebugPhysicalSizeOverride;
}

typedef _JsSetUrlStrategy = void Function(JsUrlStrategy?);

/// A JavaScript hook to customize the URL strategy of a Flutter app.
//
// Keep this js name in sync with flutter_web_plugins. Find it at:
// https://github.com/flutter/flutter/blob/custom_location_strategy/packages/flutter_web_plugins/lib/src/navigation/js_url_strategy.dart
//
// TODO: Add integration test https://github.com/flutter/flutter/issues/66852
@JS('_flutter_web_set_location_strategy')
external set _jsSetUrlStrategy(_JsSetUrlStrategy? newJsSetUrlStrategy);

UrlStrategy? _createDefaultUrlStrategy() {
  return ui.debugEmulateFlutterTesterEnvironment
      ? TestUrlStrategy.fromEntry(TestHistoryEntry('default', null, '/'))
      : const HashUrlStrategy();
}

/// The Web implementation of [ui.SingletonFlutterWindow].
class EngineSingletonFlutterWindow extends EngineFlutterWindow {
  EngineSingletonFlutterWindow(Object windowId, ui.PlatformDispatcher platformDispatcher) : super(windowId, platformDispatcher);

  @override
  double get devicePixelRatio => _debugDevicePixelRatio ?? EnginePlatformDispatcher.browserDevicePixelRatio;

  /// Overrides the default device pixel ratio.
  ///
  /// This is useful in tests to emulate screens of different dimensions.
  void debugOverrideDevicePixelRatio(double value) {
    _debugDevicePixelRatio = value;
  }

  double? _debugDevicePixelRatio;
}

/// A type of [FlutterView] that can be hosted inside of a [FlutterWindow].
class EngineFlutterWindowView extends ui.FlutterWindow {
  EngineFlutterWindowView._(this._viewId, this.platformDispatcher);

  final Object _viewId;

  final ui.PlatformDispatcher platformDispatcher;

  @override
  ui.ViewConfiguration get viewConfiguration {
    final EnginePlatformDispatcher engineDispatcher = platformDispatcher as EnginePlatformDispatcher;
    assert(engineDispatcher._windowConfigurations.containsKey(_viewId));
    return engineDispatcher._windowConfigurations[_viewId] ?? ui.ViewConfiguration();
  }
}

/// The window singleton.
///
/// `dart:ui` window delegates to this value. However, this value has a wider
/// API surface, providing Web-specific functionality that the standard
/// `dart:ui` version does not.
final EngineSingletonFlutterWindow window = EngineSingletonFlutterWindow(0, EnginePlatformDispatcher.instance);

/// The Web implementation of [ui.WindowPadding].
class WindowPadding implements ui.WindowPadding {
  const WindowPadding({
    required this.left,
    required this.top,
    required this.right,
    required this.bottom,
  });

  final double left;
  final double top;
  final double right;
  final double bottom;
}
