// 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:typed_data' show Float64List;
import 'dart:ui';

import 'package:test/test.dart';

void main() {
  test('path getBounds', () {
    const Rect r = Rect.fromLTRB(1.0, 3.0, 5.0, 7.0);
    final Path p = Path()..addRect(r);
    expect(p.getBounds(), equals(r));
    p.lineTo(20.0, 15.0);
    expect(p.getBounds(), equals(const Rect.fromLTRB(1.0, 3.0, 20.0, 15.0)));
  });

  test('path combine rect', () {
    final Rect c1 = Rect.fromCircle(center: const Offset(10.0, 10.0), radius: 10.0);
    final Rect c2 = Rect.fromCircle(center: const Offset(5.0, 5.0), radius: 10.0);
    final Rect c1UnionC2 = c1.expandToInclude(c2);
    final Rect c1IntersectC2 = c1.intersect(c2);
    final Path pathCircle1 = Path()..addRect(c1);
    final Path pathCircle2 = Path()..addRect(c2);

    final Path difference = Path.combine(PathOperation.difference, pathCircle1, pathCircle2);
    expect(difference.getBounds(), equals(c1));

    final Path reverseDifference = Path.combine(PathOperation.reverseDifference, pathCircle1, pathCircle2);
    expect(reverseDifference.getBounds(), equals(c2));

    final Path union = Path.combine(PathOperation.union, pathCircle1, pathCircle2);
    expect(union.getBounds(), equals(c1UnionC2));

    final Path intersect = Path.combine(PathOperation.intersect, pathCircle1, pathCircle2);
    expect(intersect.getBounds(), equals(c1IntersectC2));

    // the bounds on this will be the same as union - but would draw a missing inside piece.
    final Path xor = Path.combine(PathOperation.xor, pathCircle1, pathCircle2);
    expect(xor.getBounds(), equals(c1UnionC2));
  });

  test('path combine oval', () {
    final Rect c1 = Rect.fromCircle(center: const Offset(10.0, 10.0), radius: 10.0);
    final Rect c2 = Rect.fromCircle(center: const Offset(5.0, 5.0), radius: 10.0);
    final Rect c1UnionC2 = c1.expandToInclude(c2);
    final Rect c1IntersectC2 = c1.intersect(c2);
    final Path pathCircle1 = Path()..addOval(c1);
    final Path pathCircle2 = Path()..addOval(c2);

    final Path difference = Path.combine(PathOperation.difference, pathCircle1, pathCircle2);

    expect(difference.getBounds().top, closeTo(0.88, 0.01));

    final Path reverseDifference = Path.combine(PathOperation.reverseDifference, pathCircle1, pathCircle2);
    expect(reverseDifference.getBounds().right, closeTo(14.11, 0.01));

    final Path union = Path.combine(PathOperation.union, pathCircle1, pathCircle2);
    expect(union.getBounds(), equals(c1UnionC2));

    final Path intersect = Path.combine(PathOperation.intersect, pathCircle1, pathCircle2);
    expect(intersect.getBounds(), equals(c1IntersectC2));

    // the bounds on this will be the same as union - but would draw a missing inside piece.
    final Path xor = Path.combine(PathOperation.xor, pathCircle1, pathCircle2);
    expect(xor.getBounds(), equals(c1UnionC2));
  });

  test('path clone', () {
    final Path p1 = Path()..lineTo(20.0, 20.0);
    final Path p2 = Path.from(p1);

    expect(p1.getBounds(), equals(p2.getBounds()));

    p1.lineTo(10.0, 30.0);
    expect(p1.getBounds().bottom, equals(p2.getBounds().bottom + 10));
  });

  test('shift tests', () {
    const Rect bounds = Rect.fromLTRB(0.0, 0.0, 10.0, 10.0);
    final Path p = Path()..addRect(bounds);
    expect(p.getBounds(), equals(bounds));
    final Path shifted = p.shift(const Offset(10, 10));
    expect(shifted.getBounds(), equals(const Rect.fromLTRB(10, 10, 20, 20)));
  });

  test('transformation tests', () {
    const Rect bounds = Rect.fromLTRB(0.0, 0.0, 10.0, 10.0);
    final Path p = Path()..addRect(bounds);
    final Float64List scaleMatrix = Float64List.fromList(<double>[
      2.5, 0.0, 0.0, 0.0, // first col
      0.0, 0.5, 0.0, 0.0, // second col
      0.0, 0.0, 1.0, 0.0, // third col
      0.0, 0.0, 0.0, 1.0, // fourth col
    ]);

    expect(p.getBounds(), equals(bounds));
    final Path pTransformed = p.transform(scaleMatrix);

    expect(pTransformed.getBounds(),
        equals(const Rect.fromLTRB(0.0, 0.0, 10 * 2.5, 10 * 0.5)));

    final Path p2 = Path()..lineTo(10.0, 10.0);

    p.addPath(p2, const Offset(10.0, 10.0));
    expect(p.getBounds(), equals(const Rect.fromLTRB(0.0, 0.0, 20.0, 20.0)));

    p.addPath(p2, const Offset(20.0, 20.0), matrix4: scaleMatrix);
    expect(p.getBounds(),
        equals(const Rect.fromLTRB(0.0, 0.0, 20 + (10 * 2.5), 20 + (10 * .5))));

    p.extendWithPath(p2, Offset.zero);
    expect(p.getBounds(), equals(const Rect.fromLTRB(0.0, 0.0, 45.0, 25.0)));

    p.extendWithPath(p2, const Offset(45.0, 25.0), matrix4: scaleMatrix);
    expect(p.getBounds(), equals(const Rect.fromLTRB(0.0, 0.0, 70.0, 30.0)));
  });

  test('path metrics tests', () {
    final Path simpleHorizontalLine = Path()..lineTo(10.0, 0.0);

    // basic tests on horizontal line
    final PathMetrics simpleHorizontalMetrics = simpleHorizontalLine.computeMetrics();
    expect(() => simpleHorizontalMetrics.iterator.current, throwsRangeError);
    expect(simpleHorizontalMetrics.iterator.moveNext(), isTrue);
    expect(simpleHorizontalMetrics.iterator.current, isNotNull);
    expect(simpleHorizontalMetrics.iterator.current.length, equals(10.0));
    expect(simpleHorizontalMetrics.iterator.current.isClosed, isFalse);
    final Path simpleExtract = simpleHorizontalMetrics.iterator.current.extractPath(1.0, 9.0);
    expect(simpleExtract.getBounds(), equals(const Rect.fromLTRB(1.0, 0.0, 9.0, 0.0)));
    final Tangent posTan = simpleHorizontalMetrics.iterator.current.getTangentForOffset(1.0)!;
    expect(posTan.position, equals(const Offset(1.0, 0.0)));
    expect(posTan.angle, equals(0.0));

    expect(simpleHorizontalMetrics.iterator.moveNext(), isFalse);
    expect(() => simpleHorizontalMetrics.iterator.current, throwsRangeError);

    // test with forceClosed
    final PathMetrics simpleMetricsClosed = simpleHorizontalLine.computeMetrics(forceClosed: true);
    expect(() => simpleHorizontalMetrics.iterator.current, throwsRangeError);
    expect(simpleMetricsClosed.iterator.moveNext(), isTrue);
    expect(simpleMetricsClosed.iterator.current, isNotNull);
    expect(simpleMetricsClosed.iterator.current.length, equals(20.0)); // because we forced close
    expect(simpleMetricsClosed.iterator.current.isClosed, isTrue);
    final Path simpleExtract2 = simpleMetricsClosed.iterator.current.extractPath(1.0, 9.0);
    expect(simpleExtract2.getBounds(), equals(const Rect.fromLTRB(1.0, 0.0, 9.0, 0.0)));
    expect(simpleMetricsClosed.iterator.moveNext(), isFalse);

    // test getTangentForOffset with vertical line
    final Path simpleVerticalLine = Path()..lineTo(0.0, 10.0);
    final PathMetrics simpleMetricsVertical = simpleVerticalLine.computeMetrics()..iterator.moveNext();
    final Tangent posTanVertical = simpleMetricsVertical.iterator.current.getTangentForOffset(5.0)!;
    expect(posTanVertical.position, equals(const Offset(0.0, 5.0)));
    expect(posTanVertical.angle, closeTo(-1.5708, .0001)); // 90 degrees

    // test getTangentForOffset with diagonal line
    final Path simpleDiagonalLine = Path()..lineTo(10.0, 10.0);
    final PathMetrics simpleMetricsDiagonal = simpleDiagonalLine.computeMetrics()..iterator.moveNext();
    final double midPoint = simpleMetricsDiagonal.iterator.current.length / 2;
    final Tangent posTanDiagonal = simpleMetricsDiagonal.iterator.current.getTangentForOffset(midPoint)!;
    expect(posTanDiagonal.position, equals(const Offset(5.0, 5.0)));
    expect(posTanDiagonal.angle, closeTo(-0.7853981633974483, .00001)); // ~45 degrees

    // test a multi-contour path
    final Path multiContour = Path()
      ..lineTo(0.0, 10.0)
      ..moveTo(10.0, 10.0)
      ..lineTo(10.0, 15.0);

    final PathMetrics multiContourMetric = multiContour.computeMetrics();
    expect(() => multiContourMetric.iterator.current, throwsRangeError);
    expect(multiContourMetric.iterator.moveNext(), isTrue);
    expect(multiContourMetric.iterator.current, isNotNull);
    expect(multiContourMetric.iterator.current.length, equals(10.0));
    expect(multiContourMetric.iterator.moveNext(), isTrue);
    expect(multiContourMetric.iterator.current, isNotNull);
    expect(multiContourMetric.iterator.current.length, equals(5.0));
    expect(multiContourMetric.iterator.moveNext(), isFalse);
    expect(() => multiContourMetric.iterator.current, throwsRangeError);
  });

  test('PathMetrics can remember lengths and isClosed', () {
    final Path path = Path()..lineTo(0, 10)
                            ..close()
                            ..moveTo(0, 15)
                            ..lineTo(10, 15);
    final List<PathMetric> metrics = path.computeMetrics().toList();
    expect(metrics.length, 2);
    expect(metrics[0].length, 20);
    expect(metrics[0].isClosed, true);
    expect(metrics[0].getTangentForOffset(4.0)!.vector, const Offset(0.0, 1.0));
    expect(metrics[0].extractPath(4.0, 10.0).computeMetrics().first.length, 6.0);
    expect(metrics[1].length, 10);
    expect(metrics[1].isClosed, false);
    expect(metrics[1].getTangentForOffset(4.0)!.vector, const Offset(1.0, 0.0));
    expect(metrics[1].extractPath(4.0, 6.0).computeMetrics().first.length, 2.0);
  });

  test('PathMetrics on a mutated path', () {
    final Path path = Path()..lineTo(0, 10);
    final PathMetrics metrics = path.computeMetrics();
    final PathMetric firstMetric = metrics.first;
    // We've consumed the iterator.
    expect(metrics, isEmpty);
    expect(firstMetric.length, 10);
    expect(firstMetric.isClosed, false);
    expect(firstMetric.getTangentForOffset(4.0)!.vector, const Offset(0.0, 1.0));
    expect(firstMetric.extractPath(4.0, 10.0).computeMetrics().first.length, 6.0);

    path..lineTo(10, 10)..lineTo(10, 0)..close();
    // mutating the path shouldn't have added anything to the iterator.
    expect(metrics, isEmpty);
    expect(firstMetric.length, 10);
    expect(firstMetric.isClosed, false);
    expect(firstMetric.getTangentForOffset(4.0)!.vector, const Offset(0.0, 1.0));
    expect(firstMetric.extractPath(4.0, 10.0).computeMetrics().first.length, 6.0);

    // getting a new iterator should update us.
    final PathMetrics newMetrics = path.computeMetrics();
    final PathMetric newFirstMetric = newMetrics.first;
    expect(newMetrics, isEmpty);
    expect(newFirstMetric.length, 40);
    expect(newFirstMetric.isClosed, true);
    expect(newFirstMetric.getTangentForOffset(4.0)!.vector, const Offset(0.0, 1.0));
    expect(newFirstMetric.extractPath(4.0, 10.0).computeMetrics().first.length, 6.0);
  });

  test('PathMetrics on a mutated path', () {
    final Path path = Path()
      ..lineTo(0, 30)
      ..lineTo(40, 30)
      ..moveTo(100, 0)
      ..lineTo(100, 30)
      ..lineTo(140, 30)
      ..close();
    final PathMetrics metrics = path.computeMetrics();
    expect(metrics.toString(),
      '(PathMetric(length: 70.0, isClosed: false, contourIndex: 0), '
       'PathMetric(length: 120.0, isClosed: true, contourIndex: 1))',
    );
  });
}
