// 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/ui.dart';
import 'package:web_engine_tester/golden_tester.dart';

import '../common/test_initialization.dart';
import 'utils.dart';

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

Future<void> testMain() async {
  setUpUnitTests(
    setUpTestViewDimensions: false,
  );

  const Rect region = Rect.fromLTWH(0, 0, 300, 300);

  test('draws lines with varying strokeWidth', () async {
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder, region);
    paintLines(canvas);

    await drawPictureUsingCurrentRenderer(recorder.endRecording());

    await matchGoldenFile('canvas_lines_thickness.png', region: region);
  });

  test('draws lines with negative Offset values', () async {
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder, region);

    // test rendering lines correctly with negative offset when using DOM
    final Paint paintWithStyle = Paint()
    ..color = const Color(0xFFE91E63) // Colors.pink
    ..style = PaintingStyle.stroke
    ..strokeWidth = 16
    ..strokeCap = StrokeCap.round;

    // canvas.drawLine ignores paint.style (defaults to fill) according to api docs.
    // expect lines are rendered the same regardless of the set paint.style
    final Paint paintWithoutStyle = Paint()
    ..color = const Color(0xFF4CAF50) // Colors.green
    ..strokeWidth = 16
    ..strokeCap = StrokeCap.round;

    // test vertical, horizontal, and diagonal lines
    final List<Offset> points = <Offset>[
      const Offset(-25, 50), const Offset(45, 50),
      const Offset(100, -25), const Offset(100, 200),
      const Offset(-150, -145), const Offset(100, 200),
    ];
    final List<Offset> shiftedPoints = points.map((Offset point) => point.translate(20, 20)).toList();

    paintLinesFromPoints(canvas, paintWithStyle, points);
    paintLinesFromPoints(canvas, paintWithoutStyle, shiftedPoints);

    await drawPictureUsingCurrentRenderer(recorder.endRecording());
    await matchGoldenFile('canvas_lines_with_negative_offset.png', region: region);
  });

  test('drawLines method respects strokeCap', () async {
    final PictureRecorder recorder = PictureRecorder();
    final Canvas canvas = Canvas(recorder, region);

    final Paint paintStrokeCapRound = Paint()
    ..color = const Color(0xFFE91E63) // Colors.pink
    ..strokeWidth = 16
    ..strokeCap = StrokeCap.round;

    final Paint paintStrokeCapSquare = Paint()
    ..color = const Color(0xFF4CAF50) // Colors.green
    ..strokeWidth = 16
    ..strokeCap = StrokeCap.square;

    final Paint paintStrokeCapButt = Paint()
    ..color = const Color(0xFFFF9800) // Colors.orange
    ..strokeWidth = 16
    ..strokeCap = StrokeCap.butt;

    // test vertical, horizontal, and diagonal lines
    final List<Offset> points = <Offset>[
      const Offset(5, 50), const Offset(45, 50),
      const Offset(100, 5), const Offset(100, 200),
      const Offset(5, 10), const Offset(100, 200),
    ];
    final List<Offset> shiftedPoints = points.map((Offset point) => point.translate(50, 50)).toList();
    final List<Offset> twiceShiftedPoints = shiftedPoints.map((Offset point) => point.translate(50, 50)).toList();

    paintLinesFromPoints(canvas, paintStrokeCapRound, points);
    paintLinesFromPoints(canvas, paintStrokeCapSquare, shiftedPoints);
    paintLinesFromPoints(canvas, paintStrokeCapButt, twiceShiftedPoints);

    await drawPictureUsingCurrentRenderer(recorder.endRecording());
    await matchGoldenFile('canvas_lines_with_strokeCap.png', region: region);
  });
}

void paintLines(Canvas canvas) {
  final Paint nullPaint = Paint()
    ..strokeWidth = 1.0
    ..style = PaintingStyle.stroke;
  final Paint paint1 = Paint()
      ..color = const Color(0xFF9E9E9E) // Colors.grey
      ..strokeWidth = 1.0
      ..style = PaintingStyle.stroke;
  final Paint paint2 = Paint()
      ..color = const Color(0x7fff0000)
      ..strokeWidth = 1.0
      ..style = PaintingStyle.stroke;
  final Paint paint3 = Paint()
      ..color = const Color(0xFF4CAF50) //Colors.green
      ..strokeWidth = 1.0
      ..style = PaintingStyle.stroke;
  // Draw markers around 100x100 box
  canvas.drawLine(const Offset(50, 40), const Offset(148, 40), nullPaint);
  canvas.drawLine(const Offset(50, 50), const Offset(52, 50), paint1);
  canvas.drawLine(const Offset(150, 50), const Offset(148, 50), paint1);
  canvas.drawLine(const Offset(50, 150), const Offset(52, 150), paint1);
  canvas.drawLine(const Offset(150, 150), const Offset(148, 150), paint1);
  // Draw diagonal
  canvas.drawLine(const Offset(50, 50), const Offset(150, 150), paint2);
  // Draw horizontal
  paint3.strokeWidth = 1.0;
  paint3.color = const Color(0xFFFF0000);
  canvas.drawLine(const Offset(50, 55), const Offset(150, 55), paint3);
  paint3.strokeWidth = 2.0;
  paint3.color = const Color(0xFF2196F3); // Colors.blue;
  canvas.drawLine(const Offset(50, 60), const Offset(150, 60), paint3);
  paint3.strokeWidth = 4.0;
  paint3.color = const Color(0xFFFF9800); // Colors.orange;
  canvas.drawLine(const Offset(50, 70), const Offset(150, 70), paint3);
}

void paintLinesFromPoints(Canvas canvas, Paint paint, List<Offset> points) {
  // points list contains pairs of Offset points, so for loop step is 2
  for (int i = 0; i < points.length - 1; i += 2) {
    canvas.drawLine(points[i], points[i + 1], paint);
  }
}
