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

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';

import '../screenshot.dart';

const Rect region = Rect.fromLTWH(0, 0, 500, 100);

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

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

Future<void> testMain() async {
  setUp(() async {
    debugShowClipLayers = true;
    SurfaceSceneBuilder.debugForgetFrameScene();
    await webOnlyInitializePlatform();
    webOnlyFontCollection.debugRegisterTestFonts();
    await webOnlyFontCollection.ensureFontsLoaded();
  });

  group('Add picture to scene', () {
    test('draw growing picture across frames', () async {
      final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
      builder.pushClipRect(
        const Rect.fromLTRB(0, 0, 100, 100),
      );

      _drawTestPicture(builder, 100, false);
      builder.pop();

      final html.Element elm1 = builder
          .build()
          .webOnlyRootElement!;
      html.document.body!.append(elm1);

      // Now draw picture again but at larger size.
      final SurfaceSceneBuilder builder2 = SurfaceSceneBuilder();
      builder2.pushClipRect(
        const Rect.fromLTRB(0, 0, 100, 100),
      );
      // Now draw the picture at original target size, which will use a
      // different code path that should normally not have width/height set
      // on image element.
      _drawTestPicture(builder2, 20, false);
      builder2.pop();

      elm1.remove();
      await sceneScreenshot(builder2, 'canvas_draw_picture_acrossframes',
        region: region);
    });

    test('draw growing picture across frames clipped', () async {
      final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
      builder.pushClipRect(
        const Rect.fromLTRB(0, 0, 100, 100),
      );

      _drawTestPicture(builder, 100, true);
      builder.pop();

      final html.Element elm1 = builder
          .build()
          .webOnlyRootElement!;
      html.document.body!.append(elm1);

      // Now draw picture again but at larger size.
      final SurfaceSceneBuilder builder2 = SurfaceSceneBuilder();
      builder2.pushClipRect(
        const Rect.fromLTRB(0, 0, 100, 100),
      );
      _drawTestPicture(builder2, 20, true);
      builder2.pop();

      elm1.remove();
      await sceneScreenshot(builder2, 'canvas_draw_picture_acrossframes_clipped',
          region: region);
    });

    test('PictureInPicture', () async {
      final SurfaceSceneBuilder builder = SurfaceSceneBuilder();
      final Picture greenRectPicture = _drawGreenRectIntoPicture();

      final EnginePictureRecorder recorder = PictureRecorder() as EnginePictureRecorder;
      final RecordingCanvas canvas =
      recorder.beginRecording(const Rect.fromLTRB(0, 0, 100, 100));
      canvas.drawPicture(greenRectPicture);
      builder.addPicture(const Offset(10, 10), recorder.endRecording());

      await sceneScreenshot(builder, 'canvas_draw_picture_in_picture_rect',
          region: region);
    });
  });
}

HtmlImage? sharedImage;

void _drawTestPicture(SceneBuilder builder, double targetSize, bool clipped) {
  sharedImage ??= _createRealTestImage();
  final EnginePictureRecorder recorder = PictureRecorder() as EnginePictureRecorder;
  final RecordingCanvas canvas =
      recorder.beginRecording(const Rect.fromLTRB(0, 0, 100, 100));
  canvas.debugEnforceArbitraryPaint();
  if (clipped) {
    canvas.clipRRect(
        RRect.fromLTRBR(0, 0, targetSize, targetSize, const Radius.circular(4)));
  }
  canvas.drawImageRect(sharedImage!, const Rect.fromLTWH(0, 0, 20, 20),
      Rect.fromLTWH(0, 0, targetSize, targetSize), makePaint());
  final Picture picture = recorder.endRecording();
  builder.addPicture(
    Offset.zero,
    picture,
  );
}

Picture _drawGreenRectIntoPicture() {
  final EnginePictureRecorder recorder = PictureRecorder() as EnginePictureRecorder;
  final RecordingCanvas canvas =
    recorder.beginRecording(const Rect.fromLTRB(0, 0, 100, 100));
  canvas.drawRect(const Rect.fromLTWH(20, 20, 50, 50),
    makePaint()..color = const Color(0xFF00FF00));
  return recorder.endRecording();
}

typedef PaintCallback = void Function(RecordingCanvas canvas);

const String _base64Encoded20x20TestImage =
    'iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAIAAAAC64paAAAACXBIWXMAAC4jAAAuIwF4pT92AAAA'
    'B3RJTUUH5AMFFBksg4i3gQAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAAj'
    'SURBVDjLY2TAC/7jlWVioACMah4ZmhnxpyHG0QAb1UyZZgBjWAIm/clP0AAAAABJRU5ErkJggg==';

HtmlImage _createRealTestImage() {
  return HtmlImage(
    html.ImageElement()
      ..src = 'data:text/plain;base64,$_base64Encoded20x20TestImage',
    20,
    20,
  );
}
