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

// This file is run as part of a reduced test set in CI on Mac and Windows
// machines.
@Tags(<String>['reduced-test-set'])

import 'dart:math' as math;

import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  test('LinearGradient scale test', () {
    const LinearGradient testGradient = LinearGradient(
      begin: Alignment.bottomRight,
      end: Alignment(0.7, 1.0),
      colors: <Color>[
        Color(0x00FFFFFF),
        Color(0x11777777),
        Color(0x44444444),
      ],
    );
    final LinearGradient? actual = LinearGradient.lerp(null, testGradient, 0.25);

    expect(actual, const LinearGradient(
      begin: Alignment.bottomRight,
      end: Alignment(0.7, 1.0),
      colors: <Color>[
        Color(0x00FFFFFF),
        Color(0x04777777),
        Color(0x11444444),
      ],
    ));
  });

  test('LinearGradient lerp test', () {
    const LinearGradient testGradient1 = LinearGradient(
      begin: Alignment.topLeft,
      end: Alignment.bottomLeft,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
    );
    const LinearGradient testGradient2 = LinearGradient(
      begin: Alignment.topRight,
      end: Alignment.topLeft,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
    );

    final LinearGradient? actual = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const LinearGradient(
      begin: Alignment.topCenter,
      end: Alignment.centerLeft,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x77777777),
      ],
      stops: <double>[0, 1],
    ));
  });

  test('LinearGradient lerp test with stops', () {
    const LinearGradient testGradient1 = LinearGradient(
      begin: Alignment.topLeft,
      end: Alignment.bottomLeft,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
      stops: <double>[
        0.0,
        0.5,
      ],
    );
    const LinearGradient testGradient2 = LinearGradient(
      begin: Alignment.topRight,
      end: Alignment.topLeft,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
      stops: <double>[
        0.5,
        1.0,
      ],
    );

    final LinearGradient? actual = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const LinearGradient(
      begin: Alignment.topCenter,
      end: Alignment.centerLeft,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x55555555),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        1.0,
      ],
    ));
  });

  test('LinearGradient lerp test with unequal number of colors', () {
    const LinearGradient testGradient1 = LinearGradient(
      colors: <Color>[
        Color(0x22222222),
        Color(0x66666666),
      ],
    );
    const LinearGradient testGradient2 = LinearGradient(
      colors: <Color>[
        Color(0x44444444),
        Color(0x66666666),
        Color(0x88888888),
      ],
    );

    final LinearGradient? actual = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const LinearGradient(
      colors: <Color>[
        Color(0x33333333),
        Color(0x55555555),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        1.0,
      ],
    ));
  });

  test('LinearGradient lerp test with stops and unequal number of colors', () {
    const LinearGradient testGradient1 = LinearGradient(
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
      stops: <double>[
        0.0,
        0.5,
      ],
    );
    const LinearGradient testGradient2 = LinearGradient(
      colors: <Color>[
        Color(0x44444444),
        Color(0x48484848),
        Color(0x88888888),
      ],
      stops: <double>[
        0.5,
        0.7,
        1.0,
      ],
    );

    final LinearGradient? actual = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const LinearGradient(
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x55555555),
        Color(0x57575757),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        0.7,
        1.0,
      ],
    ));
  });

  test('LinearGradient toString', () {
    expect(
      const LinearGradient(
        begin: Alignment.topLeft,
        end: Alignment.bottomLeft,
        transform: GradientRotation(1.6),
        colors: <Color>[
          Color(0x33333333),
          Color(0x66666666),
        ],
      ).toString(),
      equals(
        'LinearGradient(begin: Alignment.topLeft, end: Alignment.bottomLeft, colors: [Color(0x33333333), Color(0x66666666)], tileMode: TileMode.clamp, transform: GradientRotation(radians: 1.6))',
      ),
    );
  });

  test('LinearGradient with different transforms', () {
    const LinearGradient testGradient1 = LinearGradient(
      transform: GradientRotation(math.pi/4),
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
    );
    const LinearGradient testGradient1Copy = LinearGradient(
      transform: GradientRotation(math.pi/4),
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
    );
    const LinearGradient testGradient2 = LinearGradient(
      transform: GradientRotation(math.pi/2),
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
    );

    expect(
      testGradient1,
      equals(testGradient1Copy),
    );
    expect(
      testGradient1,
      isNot(equals(testGradient2)),
    );
  });

  test('LinearGradient with AlignmentDirectional', () {
    expect(
      () {
        return const LinearGradient(
          begin: AlignmentDirectional.topStart,
          colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
        ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
      },
      throwsAssertionError,
    );
    expect(
      () {
        return const LinearGradient(
          begin: AlignmentDirectional.topStart,
          colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
        ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.rtl);
      },
      returnsNormally,
    );
    expect(
      () {
        return const LinearGradient(
          begin: AlignmentDirectional.topStart,
          colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
        ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.ltr);
      },
      returnsNormally,
    );
    expect(
      () {
        return const LinearGradient(
          begin: Alignment.topLeft,
          colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
        ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
      },
      returnsNormally,
    );
  });

  test('RadialGradient with AlignmentDirectional', () {
    expect(
      () {
        return const RadialGradient(
          center: AlignmentDirectional.topStart,
          colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
        ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
      },
      throwsAssertionError,
    );

    expect(
      () {
        return const RadialGradient(
          center: AlignmentDirectional.topStart,
          colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
        ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.rtl);
      },
      returnsNormally,
    );
    expect(
      () {
        return const RadialGradient(
          center: AlignmentDirectional.topStart,
          colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
        ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0), textDirection: TextDirection.ltr);
      },
      returnsNormally,
    );
    expect(
      () {
        return const RadialGradient(
          center: Alignment.topLeft,
          colors: <Color>[ Color(0xFFFFFFFF), Color(0xFFFFFFFF) ],
        ).createShader(const Rect.fromLTWH(0.0, 0.0, 100.0, 100.0));
      },
      returnsNormally,
    );
  });

  test('RadialGradient lerp test', () {
    const RadialGradient testGradient1 = RadialGradient(
      center: Alignment.topLeft,
      radius: 20.0,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
    );
    const RadialGradient testGradient2 = RadialGradient(
      center: Alignment.topRight,
      radius: 10.0,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
    );

    final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const RadialGradient(
      center: Alignment.topCenter,
      radius: 15.0,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        1.0,
      ],
    ));
  });

  test('RadialGradient lerp test with stops', () {
    const RadialGradient testGradient1 = RadialGradient(
      center: Alignment.topLeft,
      radius: 20.0,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
      stops: <double>[
        0.0,
        0.5,
      ],
    );
    const RadialGradient testGradient2 = RadialGradient(
      center: Alignment.topRight,
      radius: 10.0,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
      stops: <double>[
        0.5,
        1.0,
      ],
    );

    final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);

    expect(actual, const RadialGradient(
      center: Alignment.topCenter,
      radius: 15.0,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x55555555),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        1.0,
      ],
    ));

    expect(actual!.focal, isNull);
  });

  test('RadialGradient lerp test with unequal number of colors', () {
    const RadialGradient testGradient1 = RadialGradient(
      colors: <Color>[
        Color(0x22222222),
        Color(0x66666666),
      ],
    );
    const RadialGradient testGradient2 = RadialGradient(
      colors: <Color>[
        Color(0x44444444),
        Color(0x66666666),
        Color(0x88888888),
      ],
    );

    final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const RadialGradient(
      colors: <Color>[
        Color(0x33333333),
        Color(0x55555555),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        1.0,
      ],
    ));
  });

  test('RadialGradient lerp test with stops and unequal number of colors', () {
    const RadialGradient testGradient1 = RadialGradient(
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
      stops: <double>[
        0.0,
        0.5,
      ],
    );
    const RadialGradient testGradient2 = RadialGradient(
      colors: <Color>[
        Color(0x44444444),
        Color(0x48484848),
        Color(0x88888888),
      ],
      stops: <double>[
        0.5,
        0.7,
        1.0,
      ],
    );

    final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const RadialGradient(
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x55555555),
        Color(0x57575757),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        0.7,
        1.0,
      ],
    ));
  });

  test('RadialGradient lerp test with focal', () {
    const RadialGradient testGradient1 = RadialGradient(
      center: Alignment.topLeft,
      focal: Alignment.centerLeft,
      radius: 20.0,
      focalRadius: 10.0,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
    );
    const RadialGradient testGradient2 = RadialGradient(
      center: Alignment.topRight,
      focal: Alignment.centerRight,
      radius: 10.0,
      focalRadius: 5.0,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
    );
    const RadialGradient testGradient3 = RadialGradient(
      center: Alignment.topRight,
      radius: 10.0,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
    );

    final RadialGradient? actual = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const RadialGradient(
      center: Alignment.topCenter,
      focal: Alignment.center,
      radius: 15.0,
      focalRadius: 7.5,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        1.0,
      ],
    ));

    final RadialGradient? actual2 = RadialGradient.lerp(testGradient1, testGradient3, 0.5);
    expect(actual2, const RadialGradient(
      center: Alignment.topCenter,
      focal: Alignment(-0.5, 0.0),
      radius: 15.0,
      focalRadius: 5.0,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        1.0,
      ],
    ));
  });

  test('SweepGradient lerp test', () {
    const SweepGradient testGradient1 = SweepGradient(
      center: Alignment.topLeft,
      endAngle: math.pi / 2,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
    );
    const SweepGradient testGradient2 = SweepGradient(
      center: Alignment.topRight,
      startAngle: math.pi / 2,
      endAngle: math.pi,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
    );

    final SweepGradient? actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const SweepGradient(
      center: Alignment.topCenter,
      startAngle: math.pi / 4,
      endAngle: math.pi * 3/4,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        1.0,
      ],
    ));
  });

  test('SweepGradient lerp test with stops', () {
    const SweepGradient testGradient1 = SweepGradient(
      center: Alignment.topLeft,
      endAngle: math.pi / 2,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
      stops: <double>[
        0.0,
        0.5,
      ],
    );
    const SweepGradient testGradient2 = SweepGradient(
      center: Alignment.topRight,
      startAngle: math.pi / 2,
      endAngle:  math.pi,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
      stops: <double>[
        0.5,
        1.0,
      ],
    );

    final SweepGradient? actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const SweepGradient(
      center: Alignment.topCenter,
      startAngle: math.pi / 4,
      endAngle: math.pi * 3/4,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x55555555),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        1.0,
      ],
    ));
  });

  test('SweepGradient lerp test with unequal number of colors', () {
    const SweepGradient testGradient1 = SweepGradient(
      colors: <Color>[
        Color(0x22222222),
        Color(0x66666666),
      ],
    );
    const SweepGradient testGradient2 = SweepGradient(
      colors: <Color>[
        Color(0x44444444),
        Color(0x66666666),
        Color(0x88888888),
      ],
    );

    final SweepGradient? actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const SweepGradient(
      colors: <Color>[
        Color(0x33333333),
        Color(0x55555555),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        1.0,
      ],
    ));
  });

  test('SweepGradient lerp test with stops and unequal number of colors', () {
    const SweepGradient testGradient1 = SweepGradient(
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
      stops: <double>[
        0.0,
        0.5,
      ],
    );
    const SweepGradient testGradient2 = SweepGradient(
      colors: <Color>[
        Color(0x44444444),
        Color(0x48484848),
        Color(0x88888888),
      ],
      stops: <double>[
        0.5,
        0.7,
        1.0,
      ],
    );

    final SweepGradient? actual = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
    expect(actual, const SweepGradient(
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x55555555),
        Color(0x57575757),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        0.5,
        0.7,
        1.0,
      ],
    ));
  });

  test('SweepGradient scale test)', () {
    const SweepGradient testGradient = SweepGradient(
      center: Alignment.topLeft,
      endAngle: math.pi / 2,
      colors: <Color>[
        Color(0xff333333),
        Color(0xff666666),
      ],
    );

    final SweepGradient actual = testGradient.scale(0.5);

    expect(actual, const SweepGradient(
      center: Alignment.topLeft,
      endAngle: math.pi / 2,
      colors: <Color>[
        Color(0x80333333),
        Color(0x80666666),
      ],
    ));
  });

  test('Gradient lerp test (with RadialGradient)', () {
    const RadialGradient testGradient1 = RadialGradient(
      center: Alignment.topLeft,
      radius: 20.0,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
      stops: <double>[
        0.0,
        1.0,
      ],
    );
    const RadialGradient testGradient2 = RadialGradient(
      center: Alignment.topCenter,
      radius: 15.0,
      colors: <Color>[
        Color(0x3B3B3B3B),
        Color(0x77777777),
      ],
      stops: <double>[
        0.0,
        1.0,
      ],
    );
    const RadialGradient testGradient3 = RadialGradient(
      center: Alignment.topRight,
      radius: 10.0,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
      stops: <double>[
        0.0,
        1.0,
      ],
    );

    expect(Gradient.lerp(testGradient1, testGradient3, 0.0), testGradient1);
    expect(Gradient.lerp(testGradient1, testGradient3, 0.5), testGradient2);
    expect(Gradient.lerp(testGradient1, testGradient3, 1.0), testGradient3);
    expect(Gradient.lerp(testGradient3, testGradient1, 0.0), testGradient3);
    expect(Gradient.lerp(testGradient3, testGradient1, 0.5), testGradient2);
    expect(Gradient.lerp(testGradient3, testGradient1, 1.0), testGradient1);
  });

  test('Gradient lerp test (LinearGradient to RadialGradient)', () {
    const LinearGradient testGradient1 = LinearGradient(
      begin: Alignment.topLeft,
      end: Alignment.bottomRight,
      colors: <Color>[
        Color(0x33333333),
        Color(0x66666666),
      ],
    );
    const RadialGradient testGradient2 = RadialGradient(
      radius: 20.0,
      colors: <Color>[
        Color(0x44444444),
        Color(0x88888888),
      ],
    );

    expect(Gradient.lerp(testGradient1, testGradient2, 0.0), testGradient1);
    expect(Gradient.lerp(testGradient1, testGradient2, 1.0), testGradient2);
    expect(Gradient.lerp(testGradient1, testGradient2, 0.5), testGradient2.scale(0.0));
  });

  test('Gradients can handle missing stops and report mismatched stops', () {
    const LinearGradient test1a = LinearGradient(
      colors: <Color>[
        Color(0x11111111),
        Color(0x22222222),
        Color(0x33333333),
      ],
    );
    const RadialGradient test1b = RadialGradient(
      colors: <Color>[
        Color(0x11111111),
        Color(0x22222222),
        Color(0x33333333),
      ],
    );
    const LinearGradient test2a = LinearGradient(
      colors: <Color>[
        Color(0x11111111),
        Color(0x22222222),
        Color(0x33333333),
      ],
      stops: <double>[0.0, 1.0],
    );
    const RadialGradient test2b = RadialGradient(
      colors: <Color>[
        Color(0x11111111),
        Color(0x22222222),
        Color(0x33333333),
      ],
      stops: <double>[0.0, 1.0],
    );
    const Rect rect = Rect.fromLTWH(1.0, 2.0, 3.0, 4.0);
    expect(test1a.createShader(rect), isNotNull);
    expect(test1b.createShader(rect), isNotNull);
    expect(() { test2a.createShader(rect); }, throwsArgumentError);
    expect(() { test2b.createShader(rect); }, throwsArgumentError);
  });

  group('Transforms', () {
    const List<Color> colors = <Color>[Color(0xFFFFFFFF), Color(0xFF000088)];
    const Rect rect = Rect.fromLTWH(0.0, 0.0, 300.0, 400.0);
    const List<Gradient> gradients45 = <Gradient>[
      LinearGradient(colors: colors, transform: GradientRotation(math.pi/4)),
      // A radial gradient won't be interesting to rotate unless the center is changed.
      RadialGradient(colors: colors, center: Alignment.topCenter, transform: GradientRotation(math.pi/4)),
      SweepGradient(colors: colors, transform: GradientRotation(math.pi/4)),
    ];
    const List<Gradient> gradients90 = <Gradient>[
      LinearGradient(colors: colors, transform: GradientRotation(math.pi/2)),
      // A radial gradient won't be interesting to rotate unless the center is changed.
      RadialGradient(colors: colors, center: Alignment.topCenter, transform: GradientRotation(math.pi/2)),
      SweepGradient(colors: colors, transform: GradientRotation(math.pi/2)),
    ];

    const Map<Type, String> gradientSnakeCase = <Type, String> {
      LinearGradient: 'linear_gradient',
      RadialGradient: 'radial_gradient',
      SweepGradient: 'sweep_gradient',
    };

    Future<void> runTest(WidgetTester tester, Gradient gradient, double degrees) async {
      final String goldenName = '${gradientSnakeCase[gradient.runtimeType]}_$degrees.png';
      final Shader shader = gradient.createShader(
        rect,
      );
      final Key painterKey = UniqueKey();
      await tester.pumpWidget(Center(
        child: SizedBox.fromSize(
          size: rect.size,
          child: RepaintBoundary(
            key: painterKey,
            child: CustomPaint(
              painter: GradientPainter(shader, rect),
            ),
          ),
        ),
      ));
      await expectLater(
        find.byKey(painterKey),
        matchesGoldenFile(goldenName),
      );
    }

    group('Gradients - 45 degrees', () {
      for (final Gradient gradient in gradients45) {
        testWidgets('$gradient', (WidgetTester tester) async {
          await runTest(tester, gradient, 45);
        });
      }
    });

    group('Gradients - 90 degrees', () {
      for (final Gradient gradient in gradients90) {
        testWidgets('$gradient', (WidgetTester tester) async {
          await runTest(tester, gradient, 90);
        });
      }
    });
  });
}

class GradientPainter extends CustomPainter {
  const GradientPainter(this.shader, this.rect);

  final Shader shader;
  final Rect rect;

  @override
  void paint(Canvas canvas, Size size) {
    canvas.drawRect(rect, Paint()..shader = shader);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;

}
