// 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.

// @dart = 2.12

import 'dart:math' as math;
import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/ui.dart' hide window;
import 'package:ui/src/engine.dart';

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

/// Test winding and convexity of a path.
void testMain() {
  group('Convexity', () {
    test('Empty path should be convex', () {
      final SurfacePath path = SurfacePath();
      expect(path.isConvex, true);
    });

    test('Circle should be convex', () {
      final SurfacePath path = SurfacePath();
      path.addOval(Rect.fromLTRB(0, 0, 20, 20));
      expect(path.isConvex, true);
      // 2nd circle.
      path.addOval(Rect.fromLTRB(0, 0, 20, 20));
      expect(path.isConvex, false);
    });

    test('addRect should be convex', () {
      SurfacePath path = SurfacePath();
      path.addRect(Rect.fromLTRB(0, 0, 20, 20));
      assert(path.isConvex, true);

      path = SurfacePath();
      path.addRectWithDirection(
          Rect.fromLTRB(0, 0, 20, 20), SPathDirection.kCW, 0);
      assert(path.isConvex, true);

      path = SurfacePath();
      path.addRectWithDirection(
          Rect.fromLTRB(0, 0, 20, 20), SPathDirection.kCCW, 0);
      assert(path.isConvex, true);
    });

    test('Quad should be convex', () {
      final SurfacePath path = SurfacePath();
      path.quadraticBezierTo(100, 100, 50, 50);
      expect(path.isConvex, true);
    });

    test('moveto/lineto convexity', () {
      final List<LineTestCase> testCases = <LineTestCase>[
        LineTestCase('', SPathConvexityType.kConvex, SPathDirection.kUnknown),
        LineTestCase(
            '0 0', SPathConvexityType.kConvex, SPathDirection.kUnknown),
        LineTestCase(
            '0 0 10 10', SPathConvexityType.kConvex, SPathDirection.kUnknown),
        LineTestCase('0 0 10 10 20 20 0 0 10 10', SPathConvexityType.kConcave,
            SPathDirection.kUnknown),
        LineTestCase(
            '0 0 10 10 10 20', SPathConvexityType.kConvex, SPathDirection.kCW),
        LineTestCase(
            '0 0 10 10 10 0', SPathConvexityType.kConvex, SPathDirection.kCCW),
        LineTestCase('0 0 10 10 10 0 0 10', SPathConvexityType.kConcave, null),
        LineTestCase('0 0 10 0 0 10 -10 -10', SPathConvexityType.kConcave,
            SPathDirection.kCW),
      ];

      for (LineTestCase testCase in testCases) {
        final SurfacePath path = SurfacePath();
        setFromString(path, testCase.pathContent);
        expect(path.convexityType, testCase.convexity);
      }
    });

    test('Convexity of path with infinite points should return unknown', () {
      final List<Offset> nonFinitePts = <Offset>[
        Offset(double.infinity, 0),
        Offset(0, double.infinity),
        Offset(double.infinity, double.infinity),
        Offset(double.negativeInfinity, 0),
        Offset(0, double.negativeInfinity),
        Offset(double.negativeInfinity, double.negativeInfinity),
        Offset(double.negativeInfinity, double.infinity),
        Offset(double.infinity, double.negativeInfinity),
        Offset(double.nan, 0),
        Offset(0, double.nan),
        Offset(double.nan, double.nan)
      ];
      final int nonFinitePointsCount = nonFinitePts.length;

      final List<Offset> axisAlignedPts = <Offset>[
        Offset(kScalarMax, 0),
        Offset(0, kScalarMax),
        Offset(kScalarMin, 0),
        Offset(0, kScalarMin)
      ];
      final int axisAlignedPointsCount = axisAlignedPts.length;

      final SurfacePath path = SurfacePath();

      for (int index = 0;
          index < (13 * nonFinitePointsCount * axisAlignedPointsCount);
          index++) {
        final int i = index % nonFinitePointsCount;
        final int f = index % axisAlignedPointsCount;
        final int g = (f + 1) % axisAlignedPointsCount;
        path.reset();
        switch (index % 13) {
          case 0:
            path.lineTo(nonFinitePts[i].dx, nonFinitePts[i].dy);
            break;
          case 1:
            path.quadraticBezierTo(nonFinitePts[i].dx, nonFinitePts[i].dy,
                nonFinitePts[i].dx, nonFinitePts[i].dy);
            break;
          case 2:
            path.quadraticBezierTo(nonFinitePts[i].dx, nonFinitePts[i].dy,
                axisAlignedPts[f].dx, axisAlignedPts[f].dy);
            break;
          case 3:
            path.quadraticBezierTo(axisAlignedPts[f].dx, axisAlignedPts[f].dy,
                nonFinitePts[i].dx, nonFinitePts[i].dy);
            break;
          case 4:
            path.cubicTo(
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy);
            break;
          case 5:
            path.cubicTo(
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy);
            break;
          case 6:
            path.cubicTo(
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                nonFinitePts[i].dx,
                nonFinitePts[i].dy);
            break;
          case 7:
            path.cubicTo(
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy);
            break;
          case 8:
            path.cubicTo(
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                nonFinitePts[i].dx,
                nonFinitePts[i].dy);
            break;
          case 9:
            path.cubicTo(
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                nonFinitePts[i].dx,
                nonFinitePts[i].dy);
            break;
          case 10:
            path.cubicTo(
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                nonFinitePts[i].dx,
                nonFinitePts[i].dy);
            break;
          case 11:
            path.cubicTo(
                nonFinitePts[i].dx,
                nonFinitePts[i].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[g].dx,
                axisAlignedPts[g].dy);
            break;
          case 12:
            path.moveTo(nonFinitePts[i].dx, nonFinitePts[i].dy);
            break;
        }
        expect(path.convexityType, SPathConvexityType.kUnknown);
      }

      for (int index = 0; index < (11 * axisAlignedPointsCount); ++index) {
        int f = index % axisAlignedPointsCount;
        int g = (f + 1) % axisAlignedPointsCount;
        path.reset();
        int curveSelect = index % 11;
        switch (curveSelect) {
          case 0:
            path.moveTo(axisAlignedPts[f].dx, axisAlignedPts[f].dy);
            break;
          case 1:
            path.lineTo(axisAlignedPts[f].dx, axisAlignedPts[f].dy);
            break;
          case 2:
            path.quadraticBezierTo(axisAlignedPts[f].dx, axisAlignedPts[f].dy,
                axisAlignedPts[f].dx, axisAlignedPts[f].dy);
            break;
          case 3:
            path.quadraticBezierTo(axisAlignedPts[f].dx, axisAlignedPts[f].dy,
                axisAlignedPts[g].dx, axisAlignedPts[g].dy);
            break;
          case 4:
            path.quadraticBezierTo(axisAlignedPts[g].dx, axisAlignedPts[g].dy,
                axisAlignedPts[f].dx, axisAlignedPts[f].dy);
            break;
          case 5:
            path.cubicTo(
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy);
            break;
          case 6:
            path.cubicTo(
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[g].dx,
                axisAlignedPts[g].dy);
            break;
          case 7:
            path.cubicTo(
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[g].dx,
                axisAlignedPts[g].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy);
            break;
          case 8:
            path.cubicTo(
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[g].dx,
                axisAlignedPts[g].dy,
                axisAlignedPts[g].dx,
                axisAlignedPts[g].dy);
            break;
          case 9:
            path.cubicTo(
                axisAlignedPts[g].dx,
                axisAlignedPts[g].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy);
            break;
          case 10:
            path.cubicTo(
                axisAlignedPts[g].dx,
                axisAlignedPts[g].dy,
                axisAlignedPts[f].dx,
                axisAlignedPts[f].dy,
                axisAlignedPts[g].dx,
                axisAlignedPts[g].dy);
            break;
        }
        if (curveSelect != 7 && curveSelect != 10) {
          int result = path.convexityType;
          expect(result, SPathConvexityType.kConvex);
        } else {
          // we make a copy so that we don't cache the result on the passed
          // in path.
          SurfacePath path2 = SurfacePath.from(path);
          int c = path2.convexityType;
          assert(SPathConvexityType.kUnknown == c ||
              SPathConvexityType.kConcave == c);
        }
      }
    });

    test('Concave lines path', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(-0.284071773, -0.0622361786);
      path.lineTo(-0.284072, -0.0622351);
      path.lineTo(-0.28407, -0.0622307);
      path.lineTo(-0.284067, -0.0622182);
      path.lineTo(-0.284084, -0.0622269);
      path.lineTo(-0.284072, -0.0622362);
      path.close();
      expect(path.convexityType, SPathConvexityType.kConcave);
    });

    test('Single moveTo origin', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(0, 0);
      expect(path.convexityType, SPathConvexityType.kConvex);
    });

    test('Single diagonal line', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(12, 20);
      path.lineTo(-12, -20);
      expect(path.convexityType, SPathConvexityType.kConvex);
    });

    test('TriLeft', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(0, 0);
      path.lineTo(1, 0);
      path.lineTo(1, 1);
      path.close();
      expect(path.convexityType, SPathConvexityType.kConvex);
    });

    test('TriRight', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(0, 0);
      path.lineTo(-1, 0);
      path.lineTo(1, 1);
      path.close();
      expect(path.convexityType, SPathConvexityType.kConvex);
    });

    test('square', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(0, 0);
      path.lineTo(1, 0);
      path.lineTo(1, 1);
      path.lineTo(0, 1);
      path.close();
      expect(path.convexityType, SPathConvexityType.kConvex);
    });

    test('redundant square', () {
      final SurfacePath redundantSquare = SurfacePath();
      redundantSquare.moveTo(0, 0);
      redundantSquare.lineTo(0, 0);
      redundantSquare.lineTo(0, 0);
      redundantSquare.lineTo(1, 0);
      redundantSquare.lineTo(1, 0);
      redundantSquare.lineTo(1, 0);
      redundantSquare.lineTo(1, 1);
      redundantSquare.lineTo(1, 1);
      redundantSquare.lineTo(1, 1);
      redundantSquare.lineTo(0, 1);
      redundantSquare.lineTo(0, 1);
      redundantSquare.lineTo(0, 1);
      redundantSquare.close();
      expect(redundantSquare.convexityType, SPathConvexityType.kConvex);
    });

    test('bowtie', () {
      final SurfacePath bowTie = SurfacePath();
      bowTie.moveTo(0, 0);
      bowTie.lineTo(0, 0);
      bowTie.lineTo(0, 0);
      bowTie.lineTo(1, 1);
      bowTie.lineTo(1, 1);
      bowTie.lineTo(1, 1);
      bowTie.lineTo(1, 0);
      bowTie.lineTo(1, 0);
      bowTie.lineTo(1, 0);
      bowTie.lineTo(0, 1);
      bowTie.lineTo(0, 1);
      bowTie.lineTo(0, 1);
      bowTie.close();
      expect(bowTie.convexityType, SPathConvexityType.kConcave);
    });

    test('sprial', () {
      final SurfacePath spiral = SurfacePath();
      spiral.moveTo(0, 0);
      spiral.lineTo(100, 0);
      spiral.lineTo(100, 100);
      spiral.lineTo(0, 100);
      spiral.lineTo(0, 50);
      spiral.lineTo(50, 50);
      spiral.lineTo(50, 75);
      spiral.close();
      expect(spiral.convexityType, SPathConvexityType.kConcave);
    });

    test('dent', () {
      final SurfacePath dent = SurfacePath();
      dent.moveTo(0, 0);
      dent.lineTo(100, 100);
      dent.lineTo(0, 100);
      dent.lineTo(-50, 200);
      dent.lineTo(-200, 100);
      dent.close();
      expect(dent.convexityType, SPathConvexityType.kConcave);
    });

    test('degenerate segments1', () {
      final SurfacePath strokedSin = SurfacePath();
      for (int i = 0; i < 2000; i++) {
        double x = i.toDouble() / 2.0;
        double y = 500 - (x + math.sin(x / 100) * 40) / 3;
        if (0 == i) {
          strokedSin.moveTo(x, y);
        } else {
          strokedSin.lineTo(x, y);
        }
      }
      expect(strokedSin.convexityType, SPathConvexityType.kConcave);
    });

    /// Regression test for https://github.com/flutter/flutter/issues/66560.
    test('Quadratic', () {
      final SurfacePath path = SurfacePath();
      path.moveTo(100.0, 0.0);
      path.quadraticBezierTo(200.0, 0.0, 200.0, 100.0);
      path.quadraticBezierTo(200.0, 200.0, 100.0, 200.0);
      path.quadraticBezierTo(0.0, 200.0, 0.0, 100.0);
      path.quadraticBezierTo(0.0, 0.0, 100.0, 0.0);
      path.close();
      expect(path.contains(Offset(100, 20)), true);
      expect(path.contains(Offset(100, 120)), true);
      expect(path.contains(Offset(100, -10)), false);
    });
  });
}

class LineTestCase {
  final String pathContent;
  final int convexity;
  final int? direction;
  LineTestCase(this.pathContent, this.convexity, this.direction);
}

/// Parses a string of the format "mx my lx1 ly1 lx2 ly2..." into a path
/// with moveTo/lineTo instructions for points.
void setFromString(SurfacePath path, String value) {
  bool first = true;
  List<String> points = value.split(' ');
  if (points.length < 2) {
    return;
  }
  for (int i = 0; i < points.length; i += 2) {
    if (first) {
      path.moveTo(double.parse(points[i]), double.parse(points[i + 1]));
      first = false;
    } else {
      path.lineTo(double.parse(points[i]), double.parse(points[i + 1]));
    }
  }
}

// Scalar max is based on 32 bit float since [PathRef] stores values in
// Float32List.
const double kScalarMax = 3.402823466e+38;
const double kScalarMin = -kScalarMax;
