// 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, const Alignment(0.0, 0.0));
    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(const AlignmentDirectional(0.0, 0.0).resolve(TextDirection.ltr), const Alignment(0.0, 0.0));
    expect(const AlignmentDirectional(0.0, 0.0).resolve(TextDirection.rtl), const Alignment(0.0, 0.0));
    expect(const AlignmentDirectional(1.0, 1.0).resolve(TextDirection.ltr), const Alignment(1.0, 1.0));
    expect(const AlignmentDirectional(1.0, 1.0).resolve(TextDirection.rtl), const Alignment(-1.0, 1.0));
    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(const AlignmentDirectional(-1.0, 0.0).resolve(TextDirection.ltr),
           const AlignmentDirectional(1.0, 0.0).resolve(TextDirection.rtl));
    expect(const AlignmentDirectional(-1.0, 0.0).resolve(TextDirection.ltr),
     isNot(const AlignmentDirectional(1.0, 0.0).resolve(TextDirection.ltr)));
    expect(const AlignmentDirectional(1.0, 0.0).resolve(TextDirection.ltr),
     isNot(const AlignmentDirectional(1.0, 0.0).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, const AlignmentDirectional(1.0, 0.0));
    expect(const AlignmentDirectional(1.0, 2.0) ~/ 2.0, const AlignmentDirectional(0.0, 1.0));
    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), const AlignmentDirectional(1.0, 0.0).resolve(direction));
      expect(Alignment.center.add(const AlignmentDirectional(1.0, 2.0) ~/ 2.0).resolve(direction), const AlignmentDirectional(0.0, 1.0).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, const Alignment(1.0, 0.0));
    expect(const Alignment(1.0, 2.0) ~/ 2.0, const Alignment(0.0, 1.0));
  });

  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(const Alignment(0.0, 0.0).toString(), 'Alignment.center');
    expect(const Alignment(-1.0, 1.0).add(const AlignmentDirectional(1.0, 0.0)).toString(), 'Alignment.bottomLeft + AlignmentDirectional.centerEnd');
    expect(const Alignment(0.0001, 0.0001).toString(), 'Alignment(0.0, 0.0)');
    expect(const Alignment(0.0, 0.0).toString(), 'Alignment.center');
    expect(const AlignmentDirectional(0.0, 0.0).toString(), 'AlignmentDirectional.center');
    expect(const Alignment(1.0, 1.0).add(const AlignmentDirectional(1.0, 1.0)).toString(), 'Alignment(1.0, 2.0) + AlignmentDirectional.centerEnd');
  });
}
