// 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' hide TextStyle;

import '../screenshot.dart';
import '../testimage.dart';

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

SurfacePaint makePaint() => Paint() as SurfacePaint;

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();
    renderer.fontCollection.debugRegisterTestFonts();
    await renderer.fontCollection.ensureFontsLoaded();
  });

  const Color red = Color(0xFFFF0000);
  const Color green = Color(0xFF00FF00);
  const Color blue = Color(0xFF2196F3);
  const Color white = Color(0xFFFFFFFF);
  const Color grey = Color(0xFF808080);
  const Color black = Color(0xFF000000);

  final List<List<BlendMode>> modes = <List<BlendMode>>[
    <BlendMode>[BlendMode.clear, BlendMode.src, BlendMode.dst,
      BlendMode.srcOver, BlendMode.dstOver, BlendMode.srcIn, BlendMode.dstIn,
      BlendMode.srcOut],
    <BlendMode>[BlendMode.dstOut, BlendMode.srcATop, BlendMode.dstATop,
      BlendMode.xor, BlendMode.plus, BlendMode.modulate, BlendMode.screen,
      BlendMode.overlay],
    <BlendMode>[BlendMode.darken, BlendMode.lighten, BlendMode.colorDodge,
      BlendMode.hardLight, BlendMode.softLight, BlendMode.difference,
      BlendMode.exclusion, BlendMode.multiply],
    <BlendMode>[BlendMode.hue, BlendMode.saturation, BlendMode.color,
      BlendMode.luminosity],
  ];

  for (int blendGroup = 0; blendGroup < 4; ++blendGroup) {
    test('Draw image with Group$blendGroup blend modes', () async {
      final RecordingCanvas rc = RecordingCanvas(
          const Rect.fromLTRB(0, 0, 400, 400));
      rc.save();
      final List<BlendMode> blendModes = modes[blendGroup];
      for (int row = 0; row < blendModes.length; row++) {
        // draw white background for first 4, black for next 4 blends.
        final double top = row * 50.0;
        rc.drawRect(Rect.fromLTWH(0, top, 200, 50), makePaint()
          ..color = white);
        rc.drawRect(Rect.fromLTWH(200, top, 200, 50), makePaint()
          ..color = grey);
        final BlendMode blendMode = blendModes[row];
        rc.drawImage(createFlutterLogoTestImage(), Offset(0, top),
            makePaint()
              ..colorFilter = EngineColorFilter.mode(red, blendMode));
        rc.drawImage(createFlutterLogoTestImage(), Offset(50, top),
            makePaint()
              ..colorFilter = EngineColorFilter.mode(green, blendMode));
        rc.drawImage(createFlutterLogoTestImage(), Offset(100, top),
            makePaint()
              ..colorFilter = EngineColorFilter.mode(blue, blendMode));
        rc.drawImage(createFlutterLogoTestImage(), Offset(150, top),
            makePaint()
              ..colorFilter = EngineColorFilter.mode(black, blendMode));
        rc.drawImage(createFlutterLogoTestImage(), Offset(200, top),
            makePaint()
              ..colorFilter = EngineColorFilter.mode(red, blendMode));
        rc.drawImage(createFlutterLogoTestImage(), Offset(250, top),
            makePaint()
              ..colorFilter = EngineColorFilter.mode(green, blendMode));
        rc.drawImage(createFlutterLogoTestImage(), Offset(300, top),
            makePaint()
              ..colorFilter = EngineColorFilter.mode(blue, blendMode));
        rc.drawImage(createFlutterLogoTestImage(), Offset(350, top),
            makePaint()
              ..colorFilter = EngineColorFilter.mode(black, blendMode));
      }
      rc.restore();
      await canvasScreenshot(rc, 'canvas_image_blend_group$blendGroup',
          maxDiffRatePercent: 8.0, region: screenRect);
    },
        skip: isSafari);
  }

  // Regression test for https://github.com/flutter/flutter/issues/56971
  test('Draws image and paragraph at same vertical position', () async {
    final RecordingCanvas rc = RecordingCanvas(
        const Rect.fromLTRB(0, 0, 400, 400));
    rc.save();
    rc.drawRect(const Rect.fromLTWH(0, 50, 200, 50), makePaint()
      ..color = white);
    rc.drawImage(createFlutterLogoTestImage(), const Offset(0, 50),
        makePaint()
          ..colorFilter = const EngineColorFilter.mode(red, BlendMode.srcIn));

    final Paragraph paragraph = createTestParagraph();
    const double textLeft = 80.0;
    const double textTop = 50.0;
    const double widthConstraint = 300.0;
    paragraph.layout(const ParagraphConstraints(width: widthConstraint));
    rc.drawParagraph(paragraph, const Offset(textLeft, textTop));

    rc.restore();
    await canvasScreenshot(rc, 'canvas_image_blend_and_text',
        maxDiffRatePercent: 8.0, region: screenRect);
  });
}

Paragraph createTestParagraph() {
  final ParagraphBuilder builder = ParagraphBuilder(ParagraphStyle(
    fontFamily: 'Ahem',
    fontStyle: FontStyle.normal,
    fontWeight: FontWeight.normal,
    fontSize: 14.0,
  ));
  builder.addText('FOO');
  return builder.build();
}
