// 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' as math;

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

void approxExpect(Alignment a, Alignment b) {
  expect(a.x, moreOrLessEquals(b.x));
  expect(a.y, moreOrLessEquals(b.y));
}

void main() {
  test('Alignment control test', () {
    const Alignment alignment = Alignment(0.5, 0.25);

    expect(alignment, hasOneLineDescription);
    expect(alignment.hashCode, equals(const Alignment(0.5, 0.25).hashCode));

    expect(alignment / 2.0, const Alignment(0.25, 0.125));
    expect(alignment ~/ 2.0, Alignment.center);
    expect(alignment % 5.0, const Alignment(0.5, 0.25));
  });

  test('Alignment.lerp()', () {
    const Alignment a = Alignment.topLeft;
    const Alignment b = Alignment.topCenter;
    expect(Alignment.lerp(a, b, 0.25), equals(const Alignment(-0.75, -1.0)));

    expect(Alignment.lerp(null, null, 0.25), isNull);
    expect(Alignment.lerp(null, b, 0.25), equals(const Alignment(0.0, -0.25)));
    expect(Alignment.lerp(a, null, 0.25), equals(const Alignment(-0.75, -0.75)));
  });

  test('AlignmentGeometry invariants', () {
    const AlignmentDirectional topStart = AlignmentDirectional.topStart;
    const AlignmentDirectional topEnd = AlignmentDirectional.topEnd;
    const Alignment center = Alignment.center;
    const Alignment topLeft = Alignment.topLeft;
    const Alignment topRight = Alignment.topRight;
    final List<double> numbers = <double>[0.0, 1.0, -1.0, 2.0, 0.25, 0.5, 100.0, -999.75];

    expect((topEnd * 0.0).add(topRight * 0.0), center);
    expect(topEnd.add(topRight) * 0.0, (topEnd * 0.0).add(topRight * 0.0));
    expect(topStart.add(topLeft), topLeft.add(topStart));
    expect(topStart.add(topLeft).resolve(TextDirection.ltr), (topStart.resolve(TextDirection.ltr)) + topLeft);
    expect(topStart.add(topLeft).resolve(TextDirection.rtl), (topStart.resolve(TextDirection.rtl)) + topLeft);
    expect(topStart.add(topLeft).resolve(TextDirection.ltr), topStart.resolve(TextDirection.ltr).add(topLeft));
    expect(topStart.add(topLeft).resolve(TextDirection.rtl), topStart.resolve(TextDirection.rtl).add(topLeft));
    expect(topStart.resolve(TextDirection.ltr), topLeft);
    expect(topStart.resolve(TextDirection.rtl), topRight);
    expect(topEnd * 0.0, center);
    expect(topLeft * 0.0, center);
    expect(topStart * 1.0, topStart);
    expect(topEnd * 1.0, topEnd);
    expect(topLeft * 1.0, topLeft);
    expect(topRight * 1.0, topRight);
    for (final double n in numbers) {
      expect((topStart * n).add(topStart), topStart * (n + 1.0));
      expect((topEnd * n).add(topEnd), topEnd * (n + 1.0));
      for (final double m in numbers) {
        expect((topStart * n).add(topStart * m), topStart * (n + m));
      }
    }
    expect(topStart + topStart + topStart, topStart * 3.0); // without using "add"
    for (final TextDirection x in TextDirection.values) {
      expect((topEnd * 0.0).add(topRight * 0.0).resolve(x), center.add(center).resolve(x));
      expect((topEnd * 0.0).add(topLeft).resolve(x), center.add(topLeft).resolve(x));
      expect((topEnd * 0.0).resolve(x).add(topLeft.resolve(x)), center.resolve(x).add(topLeft.resolve(x)));
      expect((topEnd * 0.0).resolve(x).add(topLeft), center.resolve(x).add(topLeft));
      expect((topEnd * 0.0).resolve(x), center.resolve(x));
    }
    expect(topStart, isNot(topLeft));
    expect(topEnd, isNot(topLeft));
    expect(topStart, isNot(topRight));
    expect(topEnd, isNot(topRight));
    expect(topStart.add(topLeft), isNot(topLeft));
    expect(topStart.add(topLeft), isNot(topStart));
  });

  test('AlignmentGeometry.resolve()', () {
    expect(const AlignmentDirectional(0.25, 0.3).resolve(TextDirection.ltr), const Alignment(0.25, 0.3));
    expect(const AlignmentDirectional(0.25, 0.3).resolve(TextDirection.rtl), const Alignment(-0.25, 0.3));
    expect(const AlignmentDirectional(-0.25, 0.3).resolve(TextDirection.ltr), const Alignment(-0.25, 0.3));
    expect(const AlignmentDirectional(-0.25, 0.3).resolve(TextDirection.rtl), const Alignment(0.25, 0.3));
    expect(const AlignmentDirectional(1.25, 0.3).resolve(TextDirection.ltr), const Alignment(1.25, 0.3));
    expect(const AlignmentDirectional(1.25, 0.3).resolve(TextDirection.rtl), const Alignment(-1.25, 0.3));
    expect(const AlignmentDirectional(0.5, -0.3).resolve(TextDirection.ltr), const Alignment(0.5, -0.3));
    expect(const AlignmentDirectional(0.5, -0.3).resolve(TextDirection.rtl), const Alignment(-0.5, -0.3));
    expect(AlignmentDirectional.center.resolve(TextDirection.ltr), Alignment.center);
    expect(AlignmentDirectional.center.resolve(TextDirection.rtl), Alignment.center);
    expect(AlignmentDirectional.bottomEnd.resolve(TextDirection.ltr), Alignment.bottomRight);
    expect(AlignmentDirectional.bottomEnd.resolve(TextDirection.rtl), Alignment.bottomLeft);
    expect(AlignmentDirectional(nonconst(1.0), 2.0), AlignmentDirectional(nonconst(1.0), 2.0));
    expect(const AlignmentDirectional(1.0, 2.0), isNot(const AlignmentDirectional(2.0, 1.0)));
    expect(
      AlignmentDirectional.centerStart.resolve(TextDirection.ltr),
      AlignmentDirectional.centerEnd.resolve(TextDirection.rtl),
    );
    expect(
      AlignmentDirectional.centerStart.resolve(TextDirection.ltr),
      isNot(AlignmentDirectional.centerEnd.resolve(TextDirection.ltr)),
    );
    expect(
      AlignmentDirectional.centerEnd.resolve(TextDirection.ltr),
      isNot(AlignmentDirectional.centerEnd.resolve(TextDirection.rtl)),
    );
  });

  test('AlignmentGeometry.lerp ad hoc tests', () {
    final AlignmentGeometry mixed1 = const Alignment(10.0, 20.0).add(const AlignmentDirectional(30.0, 50.0));
    final AlignmentGeometry mixed2 = const Alignment(70.0, 110.0).add(const AlignmentDirectional(130.0, 170.0));
    final AlignmentGeometry mixed3 = const Alignment(25.0, 42.5).add(const AlignmentDirectional(55.0, 80.0));

    for (final TextDirection direction in TextDirection.values) {
      expect(AlignmentGeometry.lerp(mixed1, mixed2, 0.0)!.resolve(direction), mixed1.resolve(direction));
      expect(AlignmentGeometry.lerp(mixed1, mixed2, 1.0)!.resolve(direction), mixed2.resolve(direction));
      expect(AlignmentGeometry.lerp(mixed1, mixed2, 0.25)!.resolve(direction), mixed3.resolve(direction));
    }
  });

  test('lerp commutes with resolve', () {
    final List<AlignmentGeometry?> offsets = <AlignmentGeometry?>[
      Alignment.topLeft,
      Alignment.topCenter,
      Alignment.topRight,
      AlignmentDirectional.topStart,
      AlignmentDirectional.topCenter,
      AlignmentDirectional.topEnd,
      Alignment.centerLeft,
      Alignment.center,
      Alignment.centerRight,
      AlignmentDirectional.centerStart,
      AlignmentDirectional.center,
      AlignmentDirectional.centerEnd,
      Alignment.bottomLeft,
      Alignment.bottomCenter,
      Alignment.bottomRight,
      AlignmentDirectional.bottomStart,
      AlignmentDirectional.bottomCenter,
      AlignmentDirectional.bottomEnd,
      const Alignment(-1.0, 0.65),
      const AlignmentDirectional(-1.0, 0.45),
      const AlignmentDirectional(0.125, 0.625),
      const Alignment(0.25, 0.875),
      const Alignment(0.0625, 0.5625).add(const AlignmentDirectional(0.1875, 0.6875)),
      const AlignmentDirectional(2.0, 3.0),
      const Alignment(2.0, 3.0),
      const Alignment(2.0, 3.0).add(const AlignmentDirectional(5.0, 3.0)),
      const Alignment(10.0, 20.0).add(const AlignmentDirectional(30.0, 50.0)),
      const Alignment(70.0, 110.0).add(const AlignmentDirectional(130.0, 170.0)),
      const Alignment(25.0, 42.5).add(const AlignmentDirectional(55.0, 80.0)),
      null,
    ];

    final List<double> times = <double>[ 0.25, 0.5, 0.75 ];

    for (final TextDirection direction in TextDirection.values) {
      final Alignment defaultValue = AlignmentDirectional.center.resolve(direction);
      for (final AlignmentGeometry? a in offsets) {
        final Alignment resolvedA = a?.resolve(direction) ?? defaultValue;
        for (final AlignmentGeometry? b in offsets) {
          final Alignment resolvedB = b?.resolve(direction) ?? defaultValue;
          approxExpect(Alignment.lerp(resolvedA, resolvedB, 0.0)!, resolvedA);
          approxExpect(Alignment.lerp(resolvedA, resolvedB, 1.0)!, resolvedB);
          approxExpect((AlignmentGeometry.lerp(a, b, 0.0) ?? defaultValue).resolve(direction), resolvedA);
          approxExpect((AlignmentGeometry.lerp(a, b, 1.0) ?? defaultValue).resolve(direction), resolvedB);
          for (final double t in times) {
            assert(t > 0.0);
            assert(t < 1.0);
            final Alignment value = (AlignmentGeometry.lerp(a, b, t) ?? defaultValue).resolve(direction);
            approxExpect(value, Alignment.lerp(resolvedA, resolvedB, t)!);
            final double minDX = math.min(resolvedA.x, resolvedB.x);
            final double maxDX = math.max(resolvedA.x, resolvedB.x);
            final double minDY = math.min(resolvedA.y, resolvedB.y);
            final double maxDY = math.max(resolvedA.y, resolvedB.y);
            expect(value.x, inInclusiveRange(minDX, maxDX));
            expect(value.y, inInclusiveRange(minDY, maxDY));
          }
        }
      }
    }
  });

  test('AlignmentGeometry add/subtract', () {
    const AlignmentGeometry directional = AlignmentDirectional(1.0, 2.0);
    const AlignmentGeometry normal = Alignment(3.0, 5.0);
    expect(directional.add(normal).resolve(TextDirection.ltr), const Alignment(4.0, 7.0));
    expect(directional.add(normal).resolve(TextDirection.rtl), const Alignment(2.0, 7.0));
    expect(normal.add(normal), normal * 2.0);
    expect(directional.add(directional), directional * 2.0);
  });

  test('AlignmentGeometry operators', () {
    expect(const AlignmentDirectional(1.0, 2.0) * 2.0, const AlignmentDirectional(2.0, 4.0));
    expect(const AlignmentDirectional(1.0, 2.0) / 2.0, const AlignmentDirectional(0.5, 1.0));
    expect(const AlignmentDirectional(1.0, 2.0) % 2.0, AlignmentDirectional.centerEnd);
    expect(const AlignmentDirectional(1.0, 2.0) ~/ 2.0, AlignmentDirectional.bottomCenter);
    for (final TextDirection direction in TextDirection.values) {
      expect(Alignment.center.add(const AlignmentDirectional(1.0, 2.0) * 2.0).resolve(direction), const AlignmentDirectional(2.0, 4.0).resolve(direction));
      expect(Alignment.center.add(const AlignmentDirectional(1.0, 2.0) / 2.0).resolve(direction), const AlignmentDirectional(0.5, 1.0).resolve(direction));
      expect(Alignment.center.add(const AlignmentDirectional(1.0, 2.0) % 2.0).resolve(direction), AlignmentDirectional.centerEnd.resolve(direction));
      expect(Alignment.center.add(const AlignmentDirectional(1.0, 2.0) ~/ 2.0).resolve(direction), AlignmentDirectional.bottomCenter.resolve(direction));
    }
    expect(const Alignment(1.0, 2.0) * 2.0, const Alignment(2.0, 4.0));
    expect(const Alignment(1.0, 2.0) / 2.0, const Alignment(0.5, 1.0));
    expect(const Alignment(1.0, 2.0) % 2.0, Alignment.centerRight);
    expect(const Alignment(1.0, 2.0) ~/ 2.0, Alignment.bottomCenter);
  });

  test('AlignmentGeometry operators', () {
    expect(const Alignment(1.0, 2.0) + const Alignment(3.0, 5.0), const Alignment(4.0, 7.0));
    expect(const Alignment(1.0, 2.0) - const Alignment(3.0, 5.0), const Alignment(-2.0, -3.0));
    expect(const AlignmentDirectional(1.0, 2.0) + const AlignmentDirectional(3.0, 5.0), const AlignmentDirectional(4.0, 7.0));
    expect(const AlignmentDirectional(1.0, 2.0) - const AlignmentDirectional(3.0, 5.0), const AlignmentDirectional(-2.0, -3.0));
  });

  test('AlignmentGeometry toString', () {
    expect(const Alignment(1.0001, 2.0001).toString(), 'Alignment(1.0, 2.0)');
    expect(Alignment.center.toString(), 'Alignment.center');
    expect(Alignment.bottomLeft.add(AlignmentDirectional.centerEnd).toString(), 'Alignment.bottomLeft + AlignmentDirectional.centerEnd');
    expect(const Alignment(0.0001, 0.0001).toString(), 'Alignment(0.0, 0.0)');
    expect(Alignment.center.toString(), 'Alignment.center');
    expect(AlignmentDirectional.center.toString(), 'AlignmentDirectional.center');
    expect(Alignment.bottomRight.add(AlignmentDirectional.bottomEnd).toString(), 'Alignment(1.0, 2.0) + AlignmentDirectional.centerEnd');
  });
}
