// 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 'dart:math' as math;
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';

import 'package:web_engine_tester/golden_tester.dart';

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

Future<void> testMain() async {
  const Rect region = Rect.fromLTWH(0, 0, 400, 600);

  late BitmapCanvas canvas;

  setUp(() {
    canvas = BitmapCanvas(region, RenderStrategy());
  });

  tearDown(() {
    canvas.rootElement.remove();
  });

  test('draws arcs with largeArc , anticlockwise variations', () async {
    paintArc(canvas, Offset.zero, distance: 20);
    paintArc(canvas, const Offset(200, 0),
        largeArc: true, distance: 20);
    paintArc(canvas, const Offset(0, 150), clockwise: true, distance: 20);
    paintArc(canvas, const Offset(200, 150),
        largeArc: true, clockwise: true, distance: 20);
    paintArc(canvas, const Offset(0, 300), distance: -20);
    paintArc(canvas, const Offset(200, 300),
        largeArc: true, distance: -20);
    paintArc(canvas, const Offset(0, 400), clockwise: true, distance: -20);
    paintArc(canvas, const Offset(200, 400),
        largeArc: true, clockwise: true, distance: -20);


    domDocument.body!.append(canvas.rootElement);
    await matchGoldenFile('canvas_arc_to_point.png', region: region);
  });

  test('Path.addArc that starts new path has correct start point', () async {
    const Rect rect = Rect.fromLTWH(20, 20, 200, 200);
    final Path p = Path()
      ..fillType = PathFillType.evenOdd
      ..addRect(rect)
      ..addArc(Rect.fromCircle(center: rect.center,
          radius: rect.size.shortestSide / 2), 0.25 * math.pi, 1.5 * math.pi);
    canvas.drawPath(p, SurfacePaintData()
      ..color = const Color(0xFFFF9800) // orange
      ..style = PaintingStyle.fill);

    domDocument.body!.append(canvas.rootElement);
    await matchGoldenFile('canvas_addarc.png', region: region);
  });

  test('Should render counter clockwise arcs', () async {
    final Path path = Path();
    path.moveTo(149.999999999999997, 50);
    path.lineTo(149.999999999999997, 20);
    path.arcTo(const Rect.fromLTRB(20, 20, 280, 280), 4.71238898038469,
        5.759586531581287 - 4.71238898038469, true);
    path.lineTo(236.60254037844385, 99.99999999999999);
    path.arcTo(const Rect.fromLTRB(50, 50, 250, 250), 5.759586531581287,
        4.71238898038469 - 5.759586531581287, true);
    path.lineTo(149.999999999999997, 20);
    canvas.drawPath(path, SurfacePaintData()
      ..color = const Color(0xFFFF9800) // orange
      ..style = PaintingStyle.fill);

    domDocument.body!.append(canvas.rootElement);
    await matchGoldenFile('canvas_addarc_ccw.png', region: region);
  });
}

void paintArc(BitmapCanvas canvas, Offset offset,
      {bool largeArc = false, bool clockwise = false, double distance = 0}) {

  final Offset startP =
      Offset(75 - distance + offset.dx, 75 - distance + offset.dy);
  final Offset endP =
      Offset(75.0 + distance + offset.dx, 75.0 + distance + offset.dy);
  canvas.drawRect(
      Rect.fromLTRB(startP.dx, startP.dy, endP.dx, endP.dy),
      SurfacePaintData()
        ..strokeWidth = 1
        ..color = const Color(0xFFFF9800) // orange
        ..style = PaintingStyle.stroke);
  final Path path = Path();
  path.moveTo(startP.dx, startP.dy);
  path.arcToPoint(endP,
      rotation: 45,
      radius: const Radius.elliptical(40, 60),
      largeArc: largeArc,
      clockwise: clockwise);
  canvas.drawPath(
      path,
      SurfacePaintData()
        ..strokeWidth = 2
        ..color = const Color(0x61000000) // black38
        ..style = PaintingStyle.stroke);
}
