// Copyright 2014 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';

import 'package:flutter/painting.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:vector_math/vector_math_64.dart';

void main() {
  test('MatrixUtils.transformRect handles very large finite values', () {
    const Rect evilRect = Rect.fromLTRB(0.0, -1.7976931348623157e+308, 800.0, 1.7976931348623157e+308);
    final Matrix4 transform = Matrix4.identity()..translate(10.0);
    final Rect transformedRect = MatrixUtils.transformRect(transform, evilRect);
    expect(transformedRect.isFinite, true);
  });

  test('MatrixUtils.getAsTranslation()', () {
    Matrix4 test;
    test = Matrix4.identity();
    expect(MatrixUtils.getAsTranslation(test), equals(Offset.zero));
    test = Matrix4.zero();
    expect(MatrixUtils.getAsTranslation(test), isNull);
    test = Matrix4.rotationX(1.0);
    expect(MatrixUtils.getAsTranslation(test), isNull);
    test = Matrix4.rotationZ(1.0);
    expect(MatrixUtils.getAsTranslation(test), isNull);
    test = Matrix4.translationValues(1.0, 2.0, 0.0);
    expect(MatrixUtils.getAsTranslation(test), equals(const Offset(1.0, 2.0)));
    test = Matrix4.translationValues(1.0, 2.0, 3.0);
    expect(MatrixUtils.getAsTranslation(test), isNull);

    test = Matrix4.identity();
    expect(MatrixUtils.getAsTranslation(test), equals(Offset.zero));
    test.rotateX(2.0);
    expect(MatrixUtils.getAsTranslation(test), isNull);

    test = Matrix4.identity();
    expect(MatrixUtils.getAsTranslation(test), equals(Offset.zero));
    test.scale(2.0);
    expect(MatrixUtils.getAsTranslation(test), isNull);

    test = Matrix4.identity();
    expect(MatrixUtils.getAsTranslation(test), equals(Offset.zero));
    test.translate(2.0, -2.0);
    expect(MatrixUtils.getAsTranslation(test), equals(const Offset(2.0, -2.0)));
    test.translate(4.0, 8.0);
    expect(MatrixUtils.getAsTranslation(test), equals(const Offset(6.0, 6.0)));
  });

  test('cylindricalProjectionTransform identity', () {
    final Matrix4 initialState = MatrixUtils.createCylindricalProjectionTransform(
      radius: 0.0,
      angle: 0.0,
      perspective: 0.0,
    );

    expect(initialState, Matrix4.identity());
  });

  test('cylindricalProjectionTransform rotate with no radius', () {
    final Matrix4 simpleRotate = MatrixUtils.createCylindricalProjectionTransform(
      radius: 0.0,
      angle: pi / 2.0,
      perspective: 0.0,
    );

    expect(simpleRotate, Matrix4.rotationX(pi / 2.0));
  });

  test('cylindricalProjectionTransform radius does not change scale', () {
    final Matrix4 noRotation = MatrixUtils.createCylindricalProjectionTransform(
      radius: 1000000.0,
      angle: 0.0,
      perspective: 0.0,
    );

    expect(noRotation, Matrix4.identity());
  });

  test('cylindricalProjectionTransform calculation spot check', () {
    final Matrix4 actual = MatrixUtils.createCylindricalProjectionTransform(
      radius: 100.0,
      angle: pi / 3.0,
    );

    expect(actual.storage, <dynamic>[
      1.0, 0.0, 0.0, 0.0,
      0.0, moreOrLessEquals(0.5), moreOrLessEquals(0.8660254037844386), moreOrLessEquals(-0.0008660254037844386),
      0.0, moreOrLessEquals(-0.8660254037844386), moreOrLessEquals(0.5), moreOrLessEquals(-0.0005),
      0.0, moreOrLessEquals(-86.60254037844386), moreOrLessEquals(-50.0), 1.05,
    ]);
  });

  test('forceToPoint', () {
    const Offset forcedOffset = Offset(20, -30);
    final Matrix4 forcedTransform = MatrixUtils.forceToPoint(forcedOffset);

    expect(
      MatrixUtils.transformPoint(forcedTransform, forcedOffset),
      forcedOffset,
    );

    expect(
      MatrixUtils.transformPoint(forcedTransform, Offset.zero),
      forcedOffset,
    );

    expect(
      MatrixUtils.transformPoint(forcedTransform, const Offset(1, 1)),
      forcedOffset,
    );

    expect(
      MatrixUtils.transformPoint(forcedTransform, const Offset(-1, -1)),
      forcedOffset,
    );

    expect(
      MatrixUtils.transformPoint(forcedTransform, const Offset(-20, 30)),
      forcedOffset,
    );

    expect(
      MatrixUtils.transformPoint(forcedTransform, const Offset(-1.2344, 1422434.23)),
      forcedOffset,
    );
  });

  test('transformRect with no perspective (w = 1)', () {
    const Rect rectangle20x20 = Rect.fromLTRB(10, 20, 30, 40);

    // Identity
    expect(
      MatrixUtils.transformRect(Matrix4.identity(), rectangle20x20),
      rectangle20x20,
    );

    // 2D Scaling
    expect(
      MatrixUtils.transformRect(Matrix4.diagonal3Values(2, 2, 2), rectangle20x20),
      const Rect.fromLTRB(20, 40, 60, 80),
    );

    // Rotation
    expect(
      MatrixUtils.transformRect(Matrix4.rotationZ(pi / 2.0), rectangle20x20),
      within<Rect>(distance: 0.00001, from: const Rect.fromLTRB(-40.0, 10.0, -20.0, 30.0)),
    );
  });

  test('transformRect with perspective (w != 1)', () {
    final Matrix4 transform = MatrixUtils.createCylindricalProjectionTransform(
      radius: 10.0,
      angle: pi / 8.0,
      perspective: 0.3,
    );

    for (int i = 1; i < 10000; i++) {
      final Rect rect = Rect.fromLTRB(11.0 * i, 12.0 * i, 15.0 * i, 18.0 * i);
      final Rect golden = _vectorWiseTransformRect(transform, rect);
      expect(
        MatrixUtils.transformRect(transform, rect),
        within<Rect>(distance: 0.00001, from: golden),
      );
    }
  });
}

// Produces the same computation as `MatrixUtils.transformPoint` but it uses
// the built-in perspective transform methods in the Matrix4 class as a
// golden implementation of the optimized `MatrixUtils.transformPoint`
// to make sure optimizations do not contain bugs.
Offset _transformPoint(Matrix4 transform, Offset point) {
  final Vector3 position3 = Vector3(point.dx, point.dy, 0.0);
  final Vector3 transformed3 = transform.perspectiveTransform(position3);
  return Offset(transformed3.x, transformed3.y);
}

// Produces the same computation as `MatrixUtils.transformRect` but it does this
// one point at a time. This function is used as the golden implementation of the
// optimized `MatrixUtils.transformRect` to make sure optimizations do not contain
// bugs.
Rect _vectorWiseTransformRect(Matrix4 transform, Rect rect) {
  final Offset point1 = _transformPoint(transform, rect.topLeft);
  final Offset point2 = _transformPoint(transform, rect.topRight);
  final Offset point3 = _transformPoint(transform, rect.bottomLeft);
  final Offset point4 = _transformPoint(transform, rect.bottomRight);
  return Rect.fromLTRB(
    _min4(point1.dx, point2.dx, point3.dx, point4.dx),
    _min4(point1.dy, point2.dy, point3.dy, point4.dy),
    _max4(point1.dx, point2.dx, point3.dx, point4.dx),
    _max4(point1.dy, point2.dy, point3.dy, point4.dy),
  );
}

double _min4(double a, double b, double c, double d) {
  return min(a, min(b, min(c, d)));
}

double _max4(double a, double b, double c, double d) {
  return max(a, max(b, max(c, d)));
}
