// 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' as ui;

import 'common.dart';

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

const ui.Rect region = ui.Rect.fromLTRB(0, 0, 500, 250);

void testMain() {
  group('ColorFilter', () {
    setUpCanvasKitTest();

    test('ColorFilter.matrix applies a color filter', () async {
      final LayerSceneBuilder builder = LayerSceneBuilder();

      builder.pushOffset(0, 0);

      // Draw a red circle and apply it to the scene.
      final CkPictureRecorder recorder = CkPictureRecorder();
      final CkCanvas canvas = recorder.beginRecording(region);

      canvas.drawCircle(
        const ui.Offset(75, 125),
        50,
        CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
      );
      final CkPicture redCircle = recorder.endRecording();

      builder.addPicture(ui.Offset.zero, redCircle);

      // Apply a "greyscale" color filter.
      builder.pushColorFilter(const ui.ColorFilter.matrix(<double>[
        0.2126, 0.7152, 0.0722, 0, 0, //
        0.2126, 0.7152, 0.0722, 0, 0, //
        0.2126, 0.7152, 0.0722, 0, 0, //
        0, 0, 0, 1, 0, //
      ]));

      // Draw another red circle and apply it to the scene.
      // This one should be grey since we have the color filter.
      final CkPictureRecorder recorder2 = CkPictureRecorder();
      final CkCanvas canvas2 = recorder2.beginRecording(region);

      canvas2.drawCircle(
        const ui.Offset(425, 125),
        50,
        CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
      );
      final CkPicture greyCircle = recorder2.endRecording();

      builder.addPicture(ui.Offset.zero, greyCircle);

      await matchSceneGolden('canvaskit_colorfilter.png', builder.build(), region: region);
    });

    test('invertColors inverts the colors', () async {
      final LayerSceneBuilder builder = LayerSceneBuilder();

      builder.pushOffset(0, 0);

      // Draw a red circle and apply it to the scene.
      final CkPictureRecorder recorder = CkPictureRecorder();
      final CkCanvas canvas = recorder.beginRecording(region);

      canvas.drawCircle(
        const ui.Offset(75, 125),
        50,
        CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
      );
      final CkPicture redCircle = recorder.endRecording();

      builder.addPicture(ui.Offset.zero, redCircle);

      // Draw another red circle with invertColors.
      final CkPictureRecorder recorder2 = CkPictureRecorder();
      final CkCanvas canvas2 = recorder2.beginRecording(region);

      canvas2.drawCircle(
        const ui.Offset(425, 125),
        50,
        CkPaint()
          ..color = const ui.Color.fromARGB(255, 255, 0, 0)
          ..invertColors = true,
      );
      final CkPicture invertedCircle = recorder2.endRecording();

      builder.addPicture(ui.Offset.zero, invertedCircle);

      await matchSceneGolden('canvaskit_invertcolors.png', builder.build(), region: region);
    });

    test('ColorFilter.matrix works for inverse matrix', () async {
      final LayerSceneBuilder builder = LayerSceneBuilder();

      builder.pushOffset(0, 0);

      // Draw a red, green, and blue square with the inverted color matrix.
      builder.pushColorFilter(const ui.ColorFilter.matrix(<double>[
        -1, 0, 0, 0, 255, //
        0, -1, 0, 0, 255, //
        0, 0, -1, 0, 255, //
        0, 0, 0, 1, 0, //
      ]));

      final CkPictureRecorder recorder = CkPictureRecorder();

      final CkCanvas canvas = recorder.beginRecording(region);
      canvas.drawRect(const ui.Rect.fromLTWH(50, 50, 100, 100),
          CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0));
      canvas.drawRect(const ui.Rect.fromLTWH(200, 50, 100, 100),
          CkPaint()..color = const ui.Color.fromARGB(255, 0, 255, 0));
      canvas.drawRect(const ui.Rect.fromLTWH(350, 50, 100, 100),
          CkPaint()..color = const ui.Color.fromARGB(255, 0, 0, 255));
      final CkPicture invertedSquares = recorder.endRecording();

      builder.addPicture(ui.Offset.zero, invertedSquares);

      await matchSceneGolden('canvaskit_inverse_colormatrix.png', builder.build(), region: region);
    });

    test('ColorFilter color with 0 opacity', () async {
      final LayerSceneBuilder builder = LayerSceneBuilder();
      builder.pushOffset(0,0);
      final CkPictureRecorder recorder = CkPictureRecorder();
      final CkCanvas canvas = recorder.beginRecording(region);

      canvas.drawCircle(
        const ui.Offset(75, 125),
        50,
        CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
      );
      final CkPicture redCircle1 = recorder.endRecording();
      builder.addPicture(ui.Offset.zero, redCircle1);

      builder.pushColorFilter(ui.ColorFilter.mode(const ui.Color(0x00000000).withOpacity(0), ui.BlendMode.srcOver));

      // Draw another red circle and apply it to the scene.
      // This one should also be red with the color filter doing nothing
      final CkPictureRecorder recorder2 = CkPictureRecorder();
      final CkCanvas canvas2 = recorder2.beginRecording(region);
      canvas2.drawCircle(
        const ui.Offset(425, 125),
        50,
        CkPaint()..color = const ui.Color.fromARGB(255, 255, 0, 0),
      );
      final CkPicture redCircle2 = recorder2.endRecording();

      builder.addPicture(ui.Offset.zero, redCircle2);

      await matchSceneGolden('canvaskit_transparent_colorfilter.png', builder.build(), region: region);
    });
    // TODO(hterkelsen): https://github.com/flutter/flutter/issues/71520
  }, skip: isSafari || isFirefox);
}
