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

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' hide TextStyle;
import 'package:web_engine_tester/golden_tester.dart';

import '../matchers.dart';

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

Future<void> testMain() async {
  const double screenWidth = 600.0;
  const double screenHeight = 800.0;
  const Rect screenRect = Rect.fromLTWH(0, 0, screenWidth, screenHeight);
  const Color black12Color = Color(0x1F000000);
  const Color redAccentColor = Color(0xFFFF1744);
  const double kDashLength = 5.0;

  // Commit a recording canvas to a bitmap, and compare with the expected
  Future<void> checkScreenshot(RecordingCanvas rc, String fileName,
      {Rect region = const Rect.fromLTWH(0, 0, 500, 500)}) async {
    final EngineCanvas engineCanvas = BitmapCanvas(screenRect,
        RenderStrategy());
    rc.endRecording();
    rc.apply(engineCanvas, screenRect);

    // Wrap in <flt-scene> so that our CSS selectors kick in.
    final DomElement sceneElement = createDomElement('flt-scene');
    if (isIosSafari) {
      // Shrink to fit on the iPhone screen.
      sceneElement.style.position = 'absolute';
      sceneElement.style.transformOrigin = '0 0 0';
      sceneElement.style.transform = 'scale(0.3)';
    }
    try {
      sceneElement.append(engineCanvas.rootElement);
      domDocument.body!.append(sceneElement);
      await matchGoldenFile('$fileName.png', region: region);
    } finally {
      // The page is reused across tests, so remove the element after taking the
      // Scuba screenshot.
      sceneElement.remove();
    }
  }

  setUpAll(() async {
    debugEmulateFlutterTesterEnvironment = true;
    await webOnlyInitializePlatform();
    renderer.fontCollection.debugRegisterTestFonts();
    await renderer.fontCollection.ensureFontsLoaded();
  });

  test('Should calculate tangent on line', () async {
    final Path path = Path();
    path.moveTo(50, 130);
    path.lineTo(150, 20);

    final PathMetric metric = path.computeMetrics().first;
    final Tangent t = metric.getTangentForOffset(50.0)!;
    expect(t.position.dx, within(from: 83.633, distance: 0.01));
    expect(t.position.dy, within(from: 93.0, distance: 0.01));
    expect(t.vector.dx, within(from: 0.672, distance: 0.01));
    expect(t.vector.dy, within(from: -0.739, distance: 0.01));
  });

  test('Should calculate tangent on cubic curve', () async {
    final Path path = Path();
    const double p1x = 240;
    const double p1y = 120;
    const double p2x = 320;
    const double p2y = 25;
    path.moveTo(150, 20);
    path.quadraticBezierTo(p1x, p1y, p2x, p2y);
    final PathMetric metric = path.computeMetrics().first;
    final Tangent t = metric.getTangentForOffset(50.0)!;
    expect(t.position.dx, within(from: 187.25, distance: 0.01));
    expect(t.position.dy, within(from: 53.33, distance: 0.01));
    expect(t.vector.dx, within(from: 0.82, distance: 0.01));
    expect(t.vector.dy, within(from: 0.56, distance: 0.01));
  });

  test('Should calculate tangent on quadratic curve', () async {
    final Path path = Path();
    const double p0x = 150;
    const double p0y = 20;
    const double p1x = 320;
    const double p1y = 25;
    path.moveTo(150, 20);
    path.quadraticBezierTo(p0x, p0y, p1x, p1y);
    final PathMetric metric = path.computeMetrics().first;
    final Tangent t = metric.getTangentForOffset(50.0)!;
    expect(t.position.dx, within(from: 199.82, distance: 0.01));
    expect(t.position.dy, within(from: 21.46, distance: 0.01));
    expect(t.vector.dx, within(from: 0.99, distance: 0.01));
    expect(t.vector.dy, within(from: 0.02, distance: 0.01));
  });

  // Test for extractPath to draw 5 pixel length dashed line using quad curve.
  test('Should draw dashed line on quadratic curve.', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));

    final SurfacePaint paint = SurfacePaint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 3
      ..color = black12Color;
    final SurfacePaint redPaint = SurfacePaint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1
      ..color = redAccentColor;

    final SurfacePath path = SurfacePath();
    path.moveTo(50, 130);
    path.lineTo(150, 20);
    const double p1x = 240;
    const double p1y = 120;
    const double p2x = 320;
    const double p2y = 25;
    path.quadraticBezierTo(p1x, p1y, p2x, p2y);

    rc.drawPath(path, paint);

    const double t0 = 0.2;
    const double t1 = 0.7;

    final List<PathMetric> metrics = path.computeMetrics().toList();
    double totalLength = 0;
    for (final PathMetric m in metrics) {
      totalLength += m.length;
    }
    final Path dashedPath = Path();
    for (final PathMetric measurePath in path.computeMetrics()) {
      double distance = totalLength * t0;
      bool draw = true;
      while (distance < measurePath.length * t1) {
        const double length = kDashLength;
        if (draw) {
          dashedPath.addPath(
              measurePath.extractPath(distance, distance + length),
              Offset.zero);
        }
        distance += length;
        draw = !draw;
      }
    }
    rc.drawPath(dashedPath, redPaint);
    await checkScreenshot(rc, 'path_dash_quadratic');
  });

  // Test for extractPath to draw 5 pixel length dashed line using cubic curve.
  test('Should draw dashed line on cubic curve.', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));

    final SurfacePaint paint = SurfacePaint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 3
      ..color = black12Color;
    final SurfacePaint redPaint = SurfacePaint()
      ..style = PaintingStyle.stroke
      ..strokeWidth = 1
      ..color = redAccentColor;

    final Path path = Path();
    path.moveTo(50, 130);
    path.lineTo(150, 20);
    const double p1x = 40;
    const double p1y = 120;
    const double p2x = 300;
    const double p2y = 130;
    const double p3x = 320;
    const double p3y = 25;
    path.cubicTo(p1x, p1y, p2x, p2y, p3x, p3y);

    rc.drawPath(path, paint);

    const double t0 = 0.2;
    const double t1 = 0.7;

    final List<PathMetric> metrics = path.computeMetrics().toList();
    double totalLength = 0;
    for (final PathMetric m in metrics) {
      totalLength += m.length;
    }
    final Path dashedPath = Path();
    for (final PathMetric measurePath in path.computeMetrics()) {
      double distance = totalLength * t0;
      bool draw = true;
      while (distance < measurePath.length * t1) {
        const double length = kDashLength;
        if (draw) {
          dashedPath.addPath(
              measurePath.extractPath(distance, distance + length),
              Offset.zero);
        }
        distance += length;
        draw = !draw;
      }
    }
    rc.drawPath(dashedPath, redPaint);
    await checkScreenshot(rc, 'path_dash_cubic');
  });
}
