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

import 'utils.dart';

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

Future<void> testMain() async {
  setUpUiTest();

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

  group('Gradients', () {
    test('Using a linear gradient on a paint', () async {
      final PictureRecorder recorder = PictureRecorder();
      final Canvas canvas = Canvas(recorder, region);
      canvas.drawRect(
        const Rect.fromLTRB(50, 50, 250, 250),
        Paint()
          ..shader = Gradient.linear(
            const Offset(50, 50),
            const Offset(250, 250),
            <Color>[
              const Color(0xFFFF0000),
              const Color(0xFF00FF00),
              const Color(0xFF0000FF),
            ],
            <double>[0.0, 0.5, 1.0],
          )
        );

      await drawPictureUsingCurrentRenderer(recorder.endRecording());

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

    test('Using a radial gradient on a paint', () async {
      final PictureRecorder recorder = PictureRecorder();
      final Canvas canvas = Canvas(recorder, region);
      canvas.drawRect(
        const Rect.fromLTRB(50, 50, 250, 250),
        Paint()
          ..shader = Gradient.radial(
            const Offset(150, 150),
            100,
            <Color>[
              const Color(0xFFFF0000),
              const Color(0xFF00FF00),
              const Color(0xFF0000FF),
            ],
            <double>[0.0, 0.5, 1.0],
          )
        );

      await drawPictureUsingCurrentRenderer(recorder.endRecording());

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

    test('Using a conical gradient on a paint', () async {
      final PictureRecorder recorder = PictureRecorder();
      final Canvas canvas = Canvas(recorder, region);
      canvas.drawRect(
        const Rect.fromLTRB(50, 50, 250, 250),
        Paint()
          ..shader = Gradient.radial(
            const Offset(200, 200),
            100,
            <Color>[
              const Color(0xFFFF0000),
              const Color(0xFF00FF00),
              const Color(0xFF0000FF),
            ],
            <double>[0.0, 0.5, 1.0],
            TileMode.clamp,
            null,
            const Offset(50, 50),
            5,
          )
        );

      await drawPictureUsingCurrentRenderer(recorder.endRecording());

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

    test('Using a sweep gradient on a paint', () async {
      final PictureRecorder recorder = PictureRecorder();
      final Canvas canvas = Canvas(recorder, region);
      canvas.drawRect(
        const Rect.fromLTRB(50, 50, 250, 250),
        Paint()
          ..shader = Gradient.sweep(
            const Offset(150, 150),
            <Color>[
              const Color(0xFFFF0000),
              const Color(0xFF00FF00),
              const Color(0xFF0000FF),
            ],
            <double>[0.0, 0.5, 1.0],
            TileMode.clamp,
            math.pi / 3.0,
            4.0 * math.pi / 3.0,
          )
        );

      await drawPictureUsingCurrentRenderer(recorder.endRecording());

      await matchGoldenFile('sweep_gradient_paint.png', region: region);
    });
  }, skip: isFirefox && isHtml); // https://github.com/flutter/flutter/issues/86623
}
