// 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.6
part of engine;

class DomRenderer {
  DomRenderer() {
    if (assertionsEnabled) {
      _debugFrameStatistics = DebugDomRendererFrameStatistics();
    }

    reset();

    TextMeasurementService.initialize(rulerCacheCapacity: 10);

    assert(() {
      _setupHotRestart();
      return true;
    }());
  }

  static const int vibrateLongPress = 50;
  static const int vibrateLightImpact = 10;
  static const int vibrateMediumImpact = 20;
  static const int vibrateHeavyImpact = 30;
  static const int vibrateSelectionClick = 10;

  /// Listens to window resize events.
  StreamSubscription<html.Event> _resizeSubscription;

  /// Contains Flutter-specific CSS rules, such as default margins and
  /// paddings.
  html.StyleElement _styleElement;

  /// Configures the screen, such as scaling.
  html.MetaElement _viewportMeta;

  /// The canvaskit script, downloaded from a CDN. Only created if
  /// [experimentalUseSkia] is set to true.
  html.ScriptElement get canvasKitScript => _canvasKitScript;
  html.ScriptElement _canvasKitScript;

  /// The element that contains the [sceneElement].
  ///
  /// This element is created and inserted in the HTML DOM once. It is never
  /// removed or moved. However the [sceneElement] may be replaced inside it.
  ///
  /// This element precedes the [glassPaneElement] so that it never receives
  /// input events. All input events are processed by [glassPaneElement] and the
  /// semantics tree.
  html.Element get sceneHostElement => _sceneHostElement;
  html.Element _sceneHostElement;

  /// The last scene element rendered by the [render] method.
  html.Element get sceneElement => _sceneElement;
  html.Element _sceneElement;

  /// This is state persistant across hot restarts that indicates what
  /// to clear.  We delay removal of old visible state to make the
  /// transition appear smooth.
  static const String _staleHotRestartStore = '__flutter_state';
  List<html.Element> _staleHotRestartState;

  /// Used to decide if the browser tab still has the focus.
  ///
  /// This information is useful for deciding on the blur behavior.
  /// See [DefaultTextEditingStrategy].
  ///
  /// This getter calls the `hasFocus` method of the `Document` interface.
  /// See for more details:
  /// https://developer.mozilla.org/en-US/docs/Web/API/Document/hasFocus
  bool get windowHasFocus => js_util.callMethod(html.document, 'hasFocus', <dynamic>[]);

  void _setupHotRestart() {
    // This persists across hot restarts to clear stale DOM.
    _staleHotRestartState =
        js_util.getProperty(html.window, _staleHotRestartStore);
    if (_staleHotRestartState == null) {
      _staleHotRestartState = <html.Element>[];
      js_util.setProperty(
          html.window, _staleHotRestartStore, _staleHotRestartState);
    }

    registerHotRestartListener(() {
      _resizeSubscription?.cancel();
      _staleHotRestartState.addAll(<html.Element>[
        _glassPaneElement,
        _styleElement,
        _viewportMeta,
        _canvasKitScript,
      ]);
    });
  }

  void _clearOnHotRestart() {
    if (_staleHotRestartState.isNotEmpty) {
      for (html.Element element in _staleHotRestartState) {
        element?.remove();
      }
      _staleHotRestartState.clear();
    }
  }

  /// We don't want to unnecessarily move DOM nodes around. If a DOM node is
  /// already in the right place, skip DOM mutation. This is both faster and
  /// more correct, because moving DOM nodes loses internal state, such as
  /// text selection.
  void renderScene(html.Element sceneElement) {
    if (sceneElement != _sceneElement) {
      _sceneElement?.remove();
      _sceneElement = sceneElement;
      append(_sceneHostElement, sceneElement);
    }
    assert(() {
      _clearOnHotRestart();
      return true;
    }());
  }

  /// The element that captures input events, such as pointer events.
  ///
  /// If semantics is enabled this element also contains the semantics DOM tree,
  /// which captures semantics input events. The semantics DOM tree must be a
  /// child of the glass pane element so that events bubble up to the glass pane
  /// if they are not handled by semantics.
  html.Element get glassPaneElement => _glassPaneElement;
  html.Element _glassPaneElement;

  final html.Element rootElement = html.document.body;

  void addElementClass(html.Element element, String className) {
    element.classes.add(className);
  }

  void attachBeforeElement(
      html.Element parent, html.Element before, html.Element newElement) {
    assert(parent != null);
    if (parent != null) {
      assert(() {
        if (before == null) {
          return true;
        }
        if (before.parent != parent) {
          throw Exception(
            'attachBeforeElement was called with `before` element that\'s '
            'not a child of the `parent` element:\n'
            '  before: $before\n'
            '  parent: $parent',
          );
        }
        return true;
      }());
      parent.insertBefore(newElement, before);
    }
  }

  html.Element createElement(String tagName, {html.Element parent}) {
    final html.Element element = html.document.createElement(tagName);
    parent?.append(element);
    return element;
  }

  void append(html.Element parent, html.Element child) {
    parent.append(child);
  }

  void appendText(html.Element parent, String text) {
    parent.appendText(text);
  }

  void detachElement(html.Element element) {
    element.remove();
  }

  void removeElementClass(html.Element element, String className) {
    element.classes.remove(className);
  }

  void setElementAttribute(html.Element element, String name, String value) {
    element.setAttribute(name, value);
  }

  void setElementProperty(html.Element element, String name, Object value) {
    js_util.setProperty(element, name, value);
  }

  void setElementStyle(html.Element element, String name, String value) {
    if (value == null) {
      element.style.removeProperty(name);
    } else {
      element.style.setProperty(name, value);
    }
  }

  void setText(html.Element element, String text) {
    element.text = text;
  }

  void removeAllChildren(html.Element element) {
    element.children.clear();
  }

  html.Element getParent(html.Element element) => element.parent;

  void setTitle(String title) {
    html.document.title = title;
  }

  void setThemeColor(ui.Color color) {
    html.MetaElement theme = html.document.querySelector('#flutterweb-theme');
    if (theme == null) {
      theme = html.MetaElement()
        ..id = 'flutterweb-theme'
        ..name = 'theme-color';
      html.document.head.append(theme);
    }
    theme.content = colorToCssString(color);
  }

  static const String defaultFontStyle = 'normal';
  static const String defaultFontWeight = 'normal';
  static const String defaultFontSize = '14px';
  static const String defaultFontFamily = 'sans-serif';
  static const String defaultCssFont =
      '$defaultFontStyle $defaultFontWeight $defaultFontSize $defaultFontFamily';

  void reset() {
    _styleElement?.remove();
    _styleElement = html.StyleElement();
    html.document.head.append(_styleElement);
    final html.CssStyleSheet sheet = _styleElement.sheet;
    final bool isWebKit = browserEngine == BrowserEngine.webkit;
    final bool isFirefox = browserEngine == BrowserEngine.firefox;
    // TODO(butterfly): use more efficient CSS selectors; descendant selectors
    //                  are slow. More info:
    //
    //                  https://csswizardry.com/2011/09/writing-efficient-css-selectors/

    // This undoes browser's default layout attributes for paragraphs. We
    // compute paragraph layout ourselves.
    if (isFirefox) {
      // For firefox set line-height, otherwise textx at same font-size will
      // measure differently in ruler.
      sheet.insertRule(
          'flt-ruler-host p, flt-scene p '
          '{ margin: 0; line-height: 100%;}',
          sheet.cssRules.length);
    } else {
      sheet.insertRule(
          'flt-ruler-host p, flt-scene p '
          '{ margin: 0; }',
          sheet.cssRules.length);
    }

    // This undoes browser's default painting and layout attributes of range
    // input, which is used in semantics.
    sheet.insertRule('''
flt-semantics input[type=range] {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  position: absolute;
  border: none;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}''', sheet.cssRules.length);

    if (isWebKit) {
      sheet.insertRule(
          'flt-semantics input[type=range]::-webkit-slider-thumb {'
          '  -webkit-appearance: none;'
          '}',
          sheet.cssRules.length);
    }

    if (isFirefox) {
      sheet.insertRule(
          'input::-moz-selection {'
          '  background-color: transparent;'
          '}',
          sheet.cssRules.length);
      sheet.insertRule(
          'textarea::-moz-selection {'
          '  background-color: transparent;'
          '}',
          sheet.cssRules.length);
    } else {
      // On iOS, the invisible semantic text field has a visible cursor and
      // selection highlight. The following 2 CSS rules force everything to be
      // transparent.
      sheet.insertRule(
          'input::selection {'
          '  background-color: transparent;'
          '}',
          sheet.cssRules.length);
      sheet.insertRule(
          'textarea::selection {'
          '  background-color: transparent;'
          '}',
          sheet.cssRules.length);
    }
    sheet.insertRule('''
flt-semantics input,
flt-semantics textarea,
flt-semantics [contentEditable="true"] {
  caret-color: transparent;
}
''', sheet.cssRules.length);

    // By default on iOS, Safari would highlight the element that's being tapped
    // on using gray background. This CSS rule disables that.
    if (isWebKit) {
      sheet.insertRule('''
flt-glass-pane * {
  -webkit-tap-highlight-color: transparent;
}
''', sheet.cssRules.length);
    }

    final html.BodyElement bodyElement = html.document.body;
    setElementStyle(bodyElement, 'position', 'fixed');
    setElementStyle(bodyElement, 'top', '0');
    setElementStyle(bodyElement, 'right', '0');
    setElementStyle(bodyElement, 'bottom', '0');
    setElementStyle(bodyElement, 'left', '0');
    setElementStyle(bodyElement, 'overflow', 'hidden');
    setElementStyle(bodyElement, 'padding', '0');
    setElementStyle(bodyElement, 'margin', '0');

    // TODO(yjbanov): fix this when we support KVM I/O. Currently we scroll
    //                using drag, and text selection interferes.
    setElementStyle(bodyElement, 'user-select', 'none');
    setElementStyle(bodyElement, '-webkit-user-select', 'none');
    setElementStyle(bodyElement, '-ms-user-select', 'none');
    setElementStyle(bodyElement, '-moz-user-select', 'none');

    // This is required to prevent the browser from doing any native touch
    // handling. If we don't do this, the browser doesn't report 'pointermove'
    // events properly.
    setElementStyle(bodyElement, 'touch-action', 'none');

    // These are intentionally outrageous font parameters to make sure that the
    // apps fully specify their text styles.
    setElementStyle(bodyElement, 'font', defaultCssFont);
    setElementStyle(bodyElement, 'color', 'red');

    // TODO(flutter_web): Disable spellcheck until changes in the framework and
    // engine are complete.
    bodyElement.spellcheck = false;

    for (html.Element viewportMeta
        in html.document.head.querySelectorAll('meta[name="viewport"]')) {
      if (assertionsEnabled) {
        // Filter out the meta tag that we ourselves placed on the page. This is
        // to avoid UI flicker during hot restart. Hot restart will clean up the
        // old meta tag synchronously with the first post-restart frame.
        if (!viewportMeta.hasAttribute('flt-viewport')) {
          print(
            'WARNING: found an existing <meta name="viewport"> tag. Flutter '
            'Web uses its own viewport configuration for better compatibility '
            'with Flutter. This tag will be replaced.',
          );
        }
      }
      viewportMeta.remove();
    }

    // This removes a previously created meta tag. Note, however, that this does
    // not remove the meta tag during hot restart. Hot restart resets all static
    // variables, so this will be null upon hot restart. Instead, this tag is
    // removed by _clearOnHotRestart.
    _viewportMeta?.remove();
    _viewportMeta = html.MetaElement()
      ..setAttribute('flt-viewport', '')
      ..name = 'viewport'
      ..content = 'width=device-width, initial-scale=1.0, '
          'maximum-scale=1.0, user-scalable=no';
    html.document.head.append(_viewportMeta);

    // IMPORTANT: the glass pane element must come after the scene element in the DOM node list so
    //            it can intercept input events.
    _glassPaneElement?.remove();
    _glassPaneElement = createElement('flt-glass-pane');
    _glassPaneElement.style
      ..position = 'absolute'
      ..top = '0'
      ..right = '0'
      ..bottom = '0'
      ..left = '0';
    bodyElement.append(_glassPaneElement);

    _sceneHostElement = createElement('flt-scene-host');

    // Don't allow the scene to receive pointer events.
    _sceneHostElement.style.pointerEvents = 'none';

    _glassPaneElement.append(_sceneHostElement);

    final html.Element _accesibilityPlaceholder = EngineSemanticsOwner
        .instance.semanticsHelper
        .prepareAccesibilityPlaceholder();

    // Insert the semantics placeholder after the scene host. For all widgets
    // in the scene, except for platform widgets, the scene host will pass the
    // pointer events through to the semantics tree. However, for platform
    // views, the pointer events will not pass through, and will be handled
    // by the platform view.
    glassPaneElement
        .insertBefore(_accesibilityPlaceholder, _sceneHostElement);

    PointerBinding.initInstance(_glassPaneElement);

    // Hide the DOM nodes used to render the scene from accessibility, because
    // the accessibility tree is built from the SemanticsNode tree as a parallel
    // DOM tree.
    setElementAttribute(_sceneHostElement, 'aria-hidden', 'true');

    if (html.window.visualViewport == null && isWebKit) {
      // Safari sometimes gives us bogus innerWidth/innerHeight values when the
      // page loads. When it changes the values to correct ones it does not
      // notify of the change via `onResize`. As a workaround, we setup a
      // temporary periodic timer that polls innerWidth and triggers the
      // resizeListener so that the framework can react to the change.
      //
      // Safari 13 has implemented visualViewport API so it doesn't need this
      // timer.
      //
      // VisualViewport API is not enabled in Firefox as well. On the other hand
      // Firefox returns correct values for innerHeight, innerWidth.
      // Firefox also triggers html.window.onResize therefore we don't need this
      // timer setup for Firefox.
      final int initialInnerWidth = html.window.innerWidth;
      // Counts how many times we checked screen size. We check up to 5 times.
      int checkCount = 0;
      Timer.periodic(const Duration(milliseconds: 100), (Timer t) {
        checkCount += 1;
        if (initialInnerWidth != html.window.innerWidth) {
          // Window size changed. Notify.
          t.cancel();
          _metricsDidChange(null);
        } else if (checkCount > 5) {
          // Checked enough times. Stop.
          t.cancel();
        }
      });
    }

    if (experimentalUseSkia) {
      _canvasKitScript?.remove();
      _canvasKitScript = html.ScriptElement();
      _canvasKitScript.src = canvasKitBaseUrl + 'canvaskit.js';
      html.document.head.append(_canvasKitScript);
    }

    if (html.window.visualViewport != null) {
      _resizeSubscription =
          html.window.visualViewport.onResize.listen(_metricsDidChange);
    } else {
      _resizeSubscription = html.window.onResize.listen(_metricsDidChange);
    }
  }

  /// Called immediately after browser window metrics change.
  ///
  /// When there is a text editing going on in mobile devices, do not change
  /// the physicalSize, change the [window.viewInsets]. See:
  /// https://api.flutter.dev/flutter/dart-ui/Window/viewInsets.html
  /// https://api.flutter.dev/flutter/dart-ui/Window/physicalSize.html
  ///
  /// Note: always check for rotations for a mobile device. Update the physical
  /// size if the change is caused by a rotation.
  void _metricsDidChange(html.Event event) {
    if(isMobile && !window.isRotation() && textEditing.isEditing) {
      window.computeOnScreenKeyboardInsets();
      window.invokeOnMetricsChanged();
    } else {
      window._computePhysicalSize();
      // When physical size changes this value has to be recalculated.
      window.computeOnScreenKeyboardInsets();
      window.invokeOnMetricsChanged();
    }
  }

  void focus(html.Element element) {
    element.focus();
  }

  /// Removes all children of a DOM node.
  void clearDom(html.Node node) {
    while (node.lastChild != null) {
      node.lastChild.remove();
    }
  }

  static bool _ellipseFeatureDetected;

  /// Draws CanvasElement ellipse with fallback.
  static void ellipse(html.CanvasRenderingContext2D context,
      double centerX, double centerY, double radiusX, double radiusY,
      double rotation, double startAngle, double endAngle, bool antiClockwise) {
    _ellipseFeatureDetected ??= js_util.getProperty(context, 'ellipse') != null;
    if (_ellipseFeatureDetected) {
      context.ellipse(centerX, centerY, radiusX, radiusY,
          rotation, startAngle, endAngle, antiClockwise);
    } else {
      context.save();
      context.translate(centerX, centerY);
      context.rotate(rotation);
      context.scale(radiusX, radiusY);
      context.arc(0, 0, 1, startAngle, endAngle, antiClockwise);
      context.restore();
    }
  }

  /// The element corresponding to the only child of the root surface.
  html.Element get _rootApplicationElement {
    final html.Element lastElement = rootElement.children.last;
    return lastElement.children.singleWhere((html.Element element) {
      return element.tagName == 'FLT-SCENE';
    }, orElse: () => null);
  }

  /// Provides haptic feedback.
  void vibrate(int durationMs) {
    final html.Navigator navigator = html.window.navigator;
    if (js_util.hasProperty(navigator, 'vibrate')) {
      js_util.callMethod(navigator, 'vibrate', <num>[durationMs]);
    }
  }

  String get currentHtml => _rootApplicationElement?.outerHtml ?? '';

  DebugDomRendererFrameStatistics _debugFrameStatistics;

  DebugDomRendererFrameStatistics debugFlushFrameStatistics() {
    if (!assertionsEnabled) {
      throw Exception('This code should not be reachable in production.');
    }
    final DebugDomRendererFrameStatistics current = _debugFrameStatistics;
    _debugFrameStatistics = DebugDomRendererFrameStatistics();
    return current;
  }

  void debugRulerCacheHit() => _debugFrameStatistics.paragraphRulerCacheHits++;
  void debugRulerCacheMiss() =>
      _debugFrameStatistics.paragraphRulerCacheMisses++;
  void debugRichTextLayout() => _debugFrameStatistics.richTextLayouts++;
  void debugPlainTextLayout() => _debugFrameStatistics.plainTextLayouts++;
}

/// Miscellaneous statistics collecting during a single frame's execution.
///
/// This is useful when profiling the app. This class should only be used when
/// assertions are enabled and therefore is not suitable for collecting any
/// time measurements. It is mostly useful for counting certain events.
class DebugDomRendererFrameStatistics {
  /// The number of times we reused a previously initialized paragraph ruler to
  /// measure a paragraph of text.
  int paragraphRulerCacheHits = 0;

  /// The number of times we had to create a new paragraph ruler to measure a
  /// paragraph of text.
  int paragraphRulerCacheMisses = 0;

  /// The number of times we used a paragraph ruler to measure a paragraph of
  /// text.
  int get totalParagraphRulerAccesses =>
      paragraphRulerCacheHits + paragraphRulerCacheMisses;

  /// The number of times a paragraph of rich text was laid out this frame.
  int richTextLayouts = 0;

  /// The number of times a paragraph of plain text was laid out this frame.
  int plainTextLayouts = 0;

  @override
  String toString() {
    return '''
Frame statistics:
  Paragraph ruler cache hits: $paragraphRulerCacheHits
  Paragraph ruler cache misses: $paragraphRulerCacheMisses
  Paragraph ruler accesses: $totalParagraphRulerAccesses
  Rich text layouts: $richTextLayouts
  Plain text layouts: $plainTextLayouts
'''
        .trim();
  }
}

// TODO(yjbanov): Replace this with an explicit initialization function. The
//                lazy initialization of statics makes it very unpredictable, as
//                the constructor has side-effects.
/// Singleton DOM renderer.
final DomRenderer domRenderer = DomRenderer();
