// 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' hide TextStyle;
import '../../common.dart';
import '../screenshot.dart';

// TODO(yjbanov): unskip Firefox tests when Firefox implements WebGL in headless mode.
// https://github.com/flutter/flutter/issues/86623

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

Future<void> testMain() async {
  const double screenWidth = 500.0;
  const double screenHeight = 500.0;
  const Rect screenRect = Rect.fromLTWH(0, 0, screenWidth, screenHeight);

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

  test('Should draw linear gradient using rectangle.', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
    const Rect shaderRect = Rect.fromLTRB(50, 50, 300, 300);
    final SurfacePaint paint = SurfacePaint()..shader = Gradient.linear(
        Offset(shaderRect.left, shaderRect.top),
        Offset(shaderRect.right, shaderRect.bottom),
        const <Color>[Color(0xFFcfdfd2), Color(0xFF042a85)]);
    rc.drawRect(shaderRect, paint);
    expect(rc.renderStrategy.hasArbitraryPaint, isTrue);
    await canvasScreenshot(rc, 'linear_gradient_rect',
        region: screenRect,
        maxDiffRatePercent: 0.01);
  });

  test('Should blend linear gradient with alpha channel correctly.', () async {
    const Rect canvasRect = Rect.fromLTRB(0, 0, 500, 500);
    final RecordingCanvas rc =
        RecordingCanvas(canvasRect);
    final SurfacePaint backgroundPaint = SurfacePaint()
      ..style = PaintingStyle.fill
      ..color = const Color(0xFFFF0000);
    rc.drawRect(canvasRect, backgroundPaint);

    const Rect shaderRect = Rect.fromLTRB(50, 50, 300, 300);
    final SurfacePaint paint = SurfacePaint()..shader = Gradient.linear(
        Offset(shaderRect.left, shaderRect.top),
        Offset(shaderRect.right, shaderRect.bottom),
        const <Color>[Color(0x00000000), Color(0xFF0000FF)]);
    rc.drawRect(shaderRect, paint);
    expect(rc.renderStrategy.hasArbitraryPaint, isTrue);
    await canvasScreenshot(rc, 'linear_gradient_rect_alpha',
        region: screenRect,
        maxDiffRatePercent: 0.01);
  });

  test('Should draw linear gradient with transform.', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
    final List<double> angles = <double>[0.0, 90.0, 180.0];
    double yOffset = 0;
    for (final double angle in angles) {
      final Rect shaderRect = Rect.fromLTWH(50, 50 + yOffset, 100, 100);
      final Matrix4 matrix = Matrix4.identity();
      matrix.translate(shaderRect.left, shaderRect.top);
      matrix.multiply(Matrix4
          .rotationZ((angle / 180) * math.pi));
      final Matrix4 post = Matrix4.identity();
      post.translate(-shaderRect.left, -shaderRect.top);
      matrix.multiply(post);
      final SurfacePaint paint = SurfacePaint()
        ..shader = Gradient.linear(
            Offset(shaderRect.left, shaderRect.top),
            Offset(shaderRect.right, shaderRect.bottom),
            const <Color>[Color(0xFFFF0000), Color(0xFF042a85)],
            null,
            TileMode.clamp,
            matrix.toFloat64());
      rc.drawRect(shaderRect, SurfacePaint()
        ..color = const Color(0xFF000000));
      rc.drawOval(shaderRect, paint);
      yOffset += 120;
    }
    expect(rc.renderStrategy.hasArbitraryPaint, isTrue);
    await canvasScreenshot(rc, 'linear_gradient_oval_matrix',
        region: screenRect,
        maxDiffRatePercent: 0.2);
  });

  // Regression test for https://github.com/flutter/flutter/issues/50010
  test('Should draw linear gradient using rounded rect.', () async {
    final RecordingCanvas rc =
        RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
    const Rect shaderRect = Rect.fromLTRB(50, 50, 300, 300);
    final SurfacePaint paint = SurfacePaint()..shader = Gradient.linear(
        Offset(shaderRect.left, shaderRect.top),
        Offset(shaderRect.right, shaderRect.bottom),
        const <Color>[Color(0xFFcfdfd2), Color(0xFF042a85)]);
    rc.drawRRect(RRect.fromRectAndRadius(shaderRect, const Radius.circular(16)), paint);
    expect(rc.renderStrategy.hasArbitraryPaint, isTrue);
    await canvasScreenshot(rc, 'linear_gradient_rounded_rect',
        region: screenRect,
        maxDiffRatePercent: 0.1);
  });

  test('Should draw tiled repeated linear gradient with transform.', () async {
    final RecordingCanvas rc =
    RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
    final List<double> angles = <double>[0.0, 30.0, 210.0];
    double yOffset = 0;
    for (final double angle in angles) {
      final Rect shaderRect = Rect.fromLTWH(50, 50 + yOffset, 100, 100);
      final SurfacePaint paint = SurfacePaint()
        ..shader = Gradient.linear(
            Offset(shaderRect.left, shaderRect.top),
            Offset(shaderRect.left + shaderRect.width / 2, shaderRect.top),
            const <Color>[Color(0xFFFF0000), Color(0xFF042a85)],
            null,
            TileMode.repeated,
            Matrix4
                .rotationZ((angle / 180) * math.pi)
                .toFloat64());
      rc.drawRect(shaderRect, SurfacePaint()
        ..color = const Color(0xFF000000));
      rc.drawOval(shaderRect, paint);
      yOffset += 120;
    }
    expect(rc.renderStrategy.hasArbitraryPaint, isTrue);
    await canvasScreenshot(rc, 'linear_gradient_tiled_repeated_rect',
        region: screenRect);
  }, skip: isFirefox);

  test('Should draw tiled mirrored linear gradient with transform.', () async {
    final RecordingCanvas rc =
    RecordingCanvas(const Rect.fromLTRB(0, 0, 500, 500));
    final List<double> angles = <double>[0.0, 30.0, 210.0];
    double yOffset = 0;
    for (final double angle in angles) {
      final Rect shaderRect = Rect.fromLTWH(50, 50 + yOffset, 100, 100);
      final SurfacePaint paint = SurfacePaint()
        ..shader = Gradient.linear(
            Offset(shaderRect.left, shaderRect.top),
            Offset(shaderRect.left + shaderRect.width / 2, shaderRect.top),
            const <Color>[Color(0xFFFF0000), Color(0xFF042a85)],
            null,
            TileMode.mirror,
            Matrix4
                .rotationZ((angle / 180) * math.pi)
                .toFloat64());
      rc.drawRect(shaderRect, SurfacePaint()
        ..color = const Color(0xFF000000));
      rc.drawOval(shaderRect, paint);
      yOffset += 120;
    }
    expect(rc.renderStrategy.hasArbitraryPaint, isTrue);
    await canvasScreenshot(rc, 'linear_gradient_tiled_mirrored_rect',
        region: screenRect);
  }, skip: isFirefox);
}
