// 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 'dart:typed_data';

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/ui.dart' as ui;
import 'package:web_engine_tester/golden_tester.dart';

import '../common/test_initialization.dart';
import 'utils.dart';

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

const ui.Rect kBlueSquareRegion = ui.Rect.fromLTRB(0, 0, 25, 25);
const ui.Rect kRedCircleRegion = ui.Rect.fromLTRB(25, 0, 50, 25);
const ui.Rect kMagentaStarRegion = ui.Rect.fromLTRB(0, 25, 30, 55);
const ui.Rect kGreenSquiggleRegion = ui.Rect.fromLTRB(30, 25, 50, 55);
const ui.Rect kTotalAtlasRegion = ui.Rect.fromLTRB(0, 0, 55, 55);

ui.Image generateAtlas() {
  final ui.PictureRecorder recorder = ui.PictureRecorder();
  final ui.Canvas canvas = ui.Canvas(recorder);

  canvas.drawColor(const ui.Color(0), ui.BlendMode.src);

  // Draw the square
  canvas.save();
  canvas.clipRect(kBlueSquareRegion);
  canvas.drawRect(
    // Inset the square by one pixel so it doesn't bleed into the other sprites.
    kBlueSquareRegion.deflate(1.0),
    ui.Paint()..color = const ui.Color(0xFF0000FF)
  );
  canvas.restore();

  // Draw the circle
  canvas.save();
  canvas.clipRect(kRedCircleRegion);
  canvas.drawCircle(
    kRedCircleRegion.center,
    // Make the circle one pixel smaller than the bounds to it doesn't bleed
    // into the other shapes.
    (kRedCircleRegion.width / 2.0) - 1.0,
    ui.Paint()..color = const ui.Color(0xFFFF0000));
  canvas.restore();

  // Draw the star
  canvas.save();
  canvas.clipRect(kMagentaStarRegion);
  final ui.Offset starCenter = kMagentaStarRegion.center;

  // Make the star one pixel smaller than the bounds so that it doesn't bleed
  // into the other shapes.
  final double radius = (kMagentaStarRegion.height / 2.0) - 1.0;

  // Start at the top (rotated 90 degrees)
  double theta = -math.pi / 2.0;

  // Rotate two fifths of the circle each time
  const double rotation = 4.0 * math.pi / 5.0;
  final ui.Path starPath = ui.Path();
  starPath.moveTo(
    starCenter.dx + radius * math.cos(theta),
    starCenter.dy + radius * math.sin(theta)
  );
  for (int i = 0; i < 5; i++) {
    theta += rotation;
    starPath.lineTo(
      starCenter.dx + radius * math.cos(theta),
      starCenter.dy + radius * math.sin(theta)
    );
  }
  canvas.drawPath(
    starPath,
    ui.Paint()
      ..color = const ui.Color(0xFFFF00FF)
      ..style = ui.PaintingStyle.fill
  );
  canvas.restore();

  // Draw the Squiggle
  canvas.save();
  canvas.clipRect(kGreenSquiggleRegion);
  final ui.Path squigglePath = ui.Path();
  squigglePath.moveTo(kGreenSquiggleRegion.topCenter.dx, kGreenSquiggleRegion.topCenter.dy + 2.0);
  squigglePath.cubicTo(
    kGreenSquiggleRegion.left - 10.0, kGreenSquiggleRegion.top + kGreenSquiggleRegion.height * 0.33,
    kGreenSquiggleRegion.right + 10.0, kGreenSquiggleRegion.top + kGreenSquiggleRegion.height * 0.66,
    kGreenSquiggleRegion.bottomCenter.dx, kGreenSquiggleRegion.bottomCenter.dy - 2.0
  );
  canvas.drawPath(
    squigglePath,
    ui.Paint()
      ..color = const ui.Color(0xFF00FF00)
      ..style = ui.PaintingStyle.stroke
      ..strokeWidth = 5.0
  );
  canvas.restore();

  final ui.Picture picture = recorder.endRecording();
  return picture.toImageSync(
    kTotalAtlasRegion.width.toInt(),
    kTotalAtlasRegion.height.toInt()
  );
}

Future<void> testMain() async {
  setUpUnitTests(
    setUpTestViewDimensions: false,
  );

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

  test('render atlas', () async {
    final ui.PictureRecorder recorder = ui.PictureRecorder();
    final ui.Canvas canvas = ui.Canvas(recorder, region);
    final ui.Image atlas = generateAtlas();
    canvas.drawImage(atlas, ui.Offset.zero, ui.Paint());
    await drawPictureUsingCurrentRenderer(recorder.endRecording());
    await matchGoldenFile('ui_atlas.png', region: region);
  }, skip: isHtml); // HTML renderer doesn't support drawAtlas

  test('drawAtlas', () async {
    final ui.PictureRecorder recorder = ui.PictureRecorder();
    final ui.Canvas canvas = ui.Canvas(recorder, region);
    final ui.Image atlas = generateAtlas();
    final List<ui.RSTransform> transforms = List<ui.RSTransform>.generate(
      12, (int index) {
        const double radius = 100;
        const double rotation = math.pi / 6.0;
        final double angle = rotation * index;
        final double scos = math.sin(angle);
        final double ssin = math.cos(angle);
        return ui.RSTransform(
          scos,
          ssin,
          region.center.dx + radius * scos,
          region.center.dy + radius * ssin,
        );
      }
    );
    final List<ui.Rect> rects = <ui.Rect>[
      kBlueSquareRegion,
      kRedCircleRegion,
      kMagentaStarRegion,
      kGreenSquiggleRegion,
      kBlueSquareRegion,
      kRedCircleRegion,
      kMagentaStarRegion,
      kGreenSquiggleRegion,
      kBlueSquareRegion,
      kRedCircleRegion,
      kMagentaStarRegion,
      kGreenSquiggleRegion,
    ];
    canvas.drawAtlas(
      atlas, transforms, rects, null, null, null, ui.Paint());

    await drawPictureUsingCurrentRenderer(recorder.endRecording());
    await matchGoldenFile('ui_draw_atlas.png', region: region);
  }, skip: isHtml); // HTML renderer doesn't support drawAtlas

  test('drawAtlasRaw', () async {
    final ui.PictureRecorder recorder = ui.PictureRecorder();
    final ui.Canvas canvas = ui.Canvas(recorder, region);
    final ui.Image atlas = generateAtlas();
    final Float32List transforms = Float32List(12 * 4);
    for (int i = 0; i < 12; i++) {
      const double radius = 100;
      const double rotation = math.pi / 6.0;
      final double angle = rotation * i;
      final double scos = math.sin(angle);
      final double ssin = math.cos(angle);
      transforms[i * 4] = scos;
      transforms[i * 4 + 1] = ssin;
      transforms[i * 4 + 2] = region.center.dx + radius * scos;
      transforms[i * 4 + 3] = region.center.dy + radius * ssin;
    }
    final List<ui.Rect> rects = <ui.Rect>[
      kBlueSquareRegion,
      kRedCircleRegion,
      kMagentaStarRegion,
      kGreenSquiggleRegion,
      kBlueSquareRegion,
      kRedCircleRegion,
      kMagentaStarRegion,
      kGreenSquiggleRegion,
      kBlueSquareRegion,
      kRedCircleRegion,
      kMagentaStarRegion,
      kGreenSquiggleRegion,
    ];
    final Float32List rawRects = Float32List(rects.length * 4);
    for (int i = 0; i < rects.length; i++) {
      rawRects[i * 4] = rects[i].left;
      rawRects[i * 4 + 1] = rects[i].top;
      rawRects[i * 4 + 2] = rects[i].right;
      rawRects[i * 4 + 3] = rects[i].bottom;
    }

    final Int32List colors = Int32List(12);
    for (int i = 0; i < 12; i++) {
      final int rgb = 0xFF << (8 * (i % 3));
      colors[i] = 0xFF000000 | rgb;
    }
    canvas.drawRawAtlas(
      atlas,
      transforms,
      rawRects,
      colors,
      ui.BlendMode.dstIn,
      null,
      ui.Paint()
    );

    await drawPictureUsingCurrentRenderer(recorder.endRecording());
    await matchGoldenFile('ui_draw_atlas_raw.png', region: region);
  }, skip: isHtml); // HTML renderer doesn't support drawAtlas
}
