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

// @dart = 2.8

import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
import '../flutter_test_alternative.dart';

void main() {
  group('$AnnotatedRegion find', () {
    test('finds the first value in a OffsetLayer when sized', () {
      final ContainerLayer containerLayer = ContainerLayer();
      final List<OffsetLayer> layers = <OffsetLayer>[
        OffsetLayer(offset: Offset.zero),
        OffsetLayer(offset: const Offset(0.0, 100.0)),
        OffsetLayer(offset: const Offset(0.0, 200.0)),
      ];
      int i = 0;
      for (final OffsetLayer layer in layers) {
        layer.append(AnnotatedRegionLayer<int>(i, size: const Size(200.0, 100.0)));
        containerLayer.append(layer);
        i += 1;
      }

      expect(containerLayer.find<int>(const Offset(0.0, 1.0)), 0);
      expect(containerLayer.find<int>(const Offset(0.0, 101.0)), 1);
      expect(containerLayer.find<int>(const Offset(0.0, 201.0)), 2);
    });

    test('finds a value within the clip in a ClipRectLayer', () {
      final ContainerLayer containerLayer = ContainerLayer();
      final List<ClipRectLayer> layers = <ClipRectLayer>[
        ClipRectLayer(clipRect: const Rect.fromLTRB(0.0, 0.0, 100.0, 100.0)),
        ClipRectLayer(clipRect: const Rect.fromLTRB(0.0, 100.0, 100.0, 200.0)),
        ClipRectLayer(clipRect: const Rect.fromLTRB(0.0, 200.0, 100.0, 300.0)),
      ];
      int i = 0;
      for (final ClipRectLayer layer in layers) {
        layer.append(AnnotatedRegionLayer<int>(i));
        containerLayer.append(layer);
        i += 1;
      }

      expect(containerLayer.find<int>(const Offset(0.0, 1.0)), 0);
      expect(containerLayer.find<int>(const Offset(0.0, 101.0)), 1);
      expect(containerLayer.find<int>(const Offset(0.0, 201.0)), 2);
    });


    test('finds a value within the clip in a ClipRRectLayer', () {
      final ContainerLayer containerLayer = ContainerLayer();
      final List<ClipRRectLayer> layers = <ClipRRectLayer>[
        ClipRRectLayer(clipRRect: RRect.fromLTRBR(0.0, 0.0, 100.0, 100.0, const Radius.circular(4.0))),
        ClipRRectLayer(clipRRect: RRect.fromLTRBR(0.0, 100.0, 100.0, 200.0, const Radius.circular(4.0))),
        ClipRRectLayer(clipRRect: RRect.fromLTRBR(0.0, 200.0, 100.0, 300.0, const Radius.circular(4.0))),
      ];
      int i = 0;
      for (final ClipRRectLayer layer in layers) {
        layer.append(AnnotatedRegionLayer<int>(i));
        containerLayer.append(layer);
        i += 1;
      }

      expect(containerLayer.find<int>(const Offset(5.0, 5.0)), 0);
      expect(containerLayer.find<int>(const Offset(5.0, 105.0)), 1);
      expect(containerLayer.find<int>(const Offset(5.0, 205.0)), 2);
    });

    test('finds a value under a TransformLayer', () {
      final Matrix4 transform = Matrix4(
        2.625, 0.0, 0.0, 0.0,
        0.0, 2.625, 0.0, 0.0,
        0.0, 0.0, 1.0, 0.0,
        0.0, 0.0, 0.0, 1.0,
      );
      final TransformLayer transformLayer = TransformLayer(transform: transform);
      final List<OffsetLayer> layers = <OffsetLayer>[
        OffsetLayer(),
        OffsetLayer(offset: const Offset(0.0, 100.0)),
        OffsetLayer(offset: const Offset(0.0, 200.0)),
      ];
      int i = 0;
      for (final OffsetLayer layer in layers) {
        final AnnotatedRegionLayer<int> annotatedRegionLayer = AnnotatedRegionLayer<int>(i, size: const Size(100.0, 100.0));
        layer.append(annotatedRegionLayer);
        transformLayer.append(layer);
        i += 1;
      }

      expect(transformLayer.find<int>(const Offset(0.0, 100.0)), 0);
      expect(transformLayer.find<int>(const Offset(0.0, 200.0)), 0);
      expect(transformLayer.find<int>(const Offset(0.0, 270.0)), 1);
      expect(transformLayer.find<int>(const Offset(0.0, 400.0)), 1);
      expect(transformLayer.find<int>(const Offset(0.0, 530.0)), 2);
    });

    test('looks for child AnnotatedRegions before parents', () {
      final AnnotatedRegionLayer<int> parent = AnnotatedRegionLayer<int>(1);
      final AnnotatedRegionLayer<int> child = AnnotatedRegionLayer<int>(2);
      final ContainerLayer layer = ContainerLayer();
      parent.append(child);
      layer.append(parent);

      expect(parent.find<int>(Offset.zero), 2);
    });

    test('looks for correct type', () {
      final AnnotatedRegionLayer<int> child1 = AnnotatedRegionLayer<int>(1);
      final AnnotatedRegionLayer<String> child2 = AnnotatedRegionLayer<String>('hello');
      final ContainerLayer layer = ContainerLayer();
      layer.append(child2);
      layer.append(child1);

      expect(layer.find<String>(Offset.zero), 'hello');
    });

    test('does not clip Layer.find on an AnnotatedRegion with an unrelated type', () {
      final AnnotatedRegionLayer<int> child = AnnotatedRegionLayer<int>(1);
      final AnnotatedRegionLayer<String> parent = AnnotatedRegionLayer<String>('hello', size: const Size(10.0, 10.0));
      final ContainerLayer layer = ContainerLayer();
      parent.append(child);
      layer.append(parent);

      expect(layer.find<int>(const Offset(100.0, 100.0)), 1);
    });

    test('handles non-invertible transforms', () {
      final AnnotatedRegionLayer<int> child = AnnotatedRegionLayer<int>(1);
      final TransformLayer parent = TransformLayer(transform: Matrix4.diagonal3Values(0.0, 1.0, 1.0));
      parent.append(child);

      expect(parent.find<int>(const Offset(0.0, 0.0)), null);

      parent.transform = Matrix4.diagonal3Values(1.0, 1.0, 1.0);

      expect(parent.find<int>(const Offset(0.0, 0.0)), 1);
    });
  });
  group('$AnnotatedRegion findAllAnnotations', () {
    test('finds the first value in a OffsetLayer when sized', () {
      final ContainerLayer containerLayer = ContainerLayer();
      final List<OffsetLayer> layers = <OffsetLayer>[
        OffsetLayer(offset: Offset.zero),
        OffsetLayer(offset: const Offset(0.0, 100.0)),
        OffsetLayer(offset: const Offset(0.0, 200.0)),
      ];
      int i = 0;
      for (final OffsetLayer layer in layers) {
        layer.append(AnnotatedRegionLayer<int>(i, size: const Size(200.0, 100.0)));
        containerLayer.append(layer);
        i += 1;
      }

      expect(containerLayer.findAllAnnotations<int>(const Offset(0.0, 1.0)).annotations.toList(), equals(<int>[0]));
      expect(containerLayer.findAllAnnotations<int>(const Offset(0.0, 101.0)).annotations.toList(), equals(<int>[1]));
      expect(containerLayer.findAllAnnotations<int>(const Offset(0.0, 201.0)).annotations.toList(), equals(<int>[2]));
    });

    test('finds a value within the clip in a ClipRectLayer', () {
      final ContainerLayer containerLayer = ContainerLayer();
      final List<ClipRectLayer> layers = <ClipRectLayer>[
        ClipRectLayer(clipRect: const Rect.fromLTRB(0.0, 0.0, 100.0, 100.0)),
        ClipRectLayer(clipRect: const Rect.fromLTRB(0.0, 100.0, 100.0, 200.0)),
        ClipRectLayer(clipRect: const Rect.fromLTRB(0.0, 200.0, 100.0, 300.0)),
      ];
      int i = 0;
      for (final ClipRectLayer layer in layers) {
        layer.append(AnnotatedRegionLayer<int>(i));
        containerLayer.append(layer);
        i += 1;
      }

      expect(containerLayer.findAllAnnotations<int>(const Offset(0.0, 1.0)).annotations.toList(), equals(<int>[0]));
      expect(containerLayer.findAllAnnotations<int>(const Offset(0.0, 101.0)).annotations.toList(), equals(<int>[1]));
      expect(containerLayer.findAllAnnotations<int>(const Offset(0.0, 201.0)).annotations.toList(), equals(<int>[2]));
    });


    test('finds a value within the clip in a ClipRRectLayer', () {
      final ContainerLayer containerLayer = ContainerLayer();
      final List<ClipRRectLayer> layers = <ClipRRectLayer>[
        ClipRRectLayer(clipRRect: RRect.fromLTRBR(0.0, 0.0, 100.0, 100.0, const Radius.circular(4.0))),
        ClipRRectLayer(clipRRect: RRect.fromLTRBR(0.0, 100.0, 100.0, 200.0, const Radius.circular(4.0))),
        ClipRRectLayer(clipRRect: RRect.fromLTRBR(0.0, 200.0, 100.0, 300.0, const Radius.circular(4.0))),
      ];
      int i = 0;
      for (final ClipRRectLayer layer in layers) {
        layer.append(AnnotatedRegionLayer<int>(i));
        containerLayer.append(layer);
        i += 1;
      }

      expect(containerLayer.findAllAnnotations<int>(const Offset(5.0, 5.0)).annotations.toList(), equals(<int>[0]));
      expect(containerLayer.findAllAnnotations<int>(const Offset(5.0, 105.0)).annotations.toList(), equals(<int>[1]));
      expect(containerLayer.findAllAnnotations<int>(const Offset(5.0, 205.0)).annotations.toList(), equals(<int>[2]));
    });

    test('finds a value under a TransformLayer', () {
      final Matrix4 transform = Matrix4(
        2.625, 0.0, 0.0, 0.0,
        0.0, 2.625, 0.0, 0.0,
        0.0, 0.0, 1.0, 0.0,
        0.0, 0.0, 0.0, 1.0,
      );
      final TransformLayer transformLayer = TransformLayer(transform: transform);
      final List<OffsetLayer> layers = <OffsetLayer>[
        OffsetLayer(),
        OffsetLayer(offset: const Offset(0.0, 100.0)),
        OffsetLayer(offset: const Offset(0.0, 200.0)),
      ];
      int i = 0;
      for (final OffsetLayer layer in layers) {
        final AnnotatedRegionLayer<int> annotatedRegionLayer = AnnotatedRegionLayer<int>(i, size: const Size(100.0, 100.0));
        layer.append(annotatedRegionLayer);
        transformLayer.append(layer);
        i += 1;
      }

      expect(transformLayer.findAllAnnotations<int>(const Offset(0.0, 100.0)).annotations.toList(), equals(<int>[0]));
      expect(transformLayer.findAllAnnotations<int>(const Offset(0.0, 200.0)).annotations.toList(), equals(<int>[0]));
      expect(transformLayer.findAllAnnotations<int>(const Offset(0.0, 270.0)).annotations.toList(), equals(<int>[1]));
      expect(transformLayer.findAllAnnotations<int>(const Offset(0.0, 400.0)).annotations.toList(), equals(<int>[1]));
      expect(transformLayer.findAllAnnotations<int>(const Offset(0.0, 530.0)).annotations.toList(), equals(<int>[2]));
    });

    test('finds multiple nested, overlapping regions', () {
      final ContainerLayer parent = ContainerLayer();

      int index = 0;
      final List<AnnotatedRegionLayer<int>> layers = <AnnotatedRegionLayer<int>>[
        AnnotatedRegionLayer<int>(index++, size: const Size(100.0, 100.0)),
        AnnotatedRegionLayer<int>(index++, size: const Size(100.0, 100.0)),
      ];
      for (final ContainerLayer layer in layers) {
        final AnnotatedRegionLayer<int> annotatedRegionLayer = AnnotatedRegionLayer<int>(index++, size: const Size(100.0, 100.0));
        layer.append(annotatedRegionLayer);
        parent.append(layer);
      }

      expect(parent.findAllAnnotations<int>(const Offset(0.0, 0.0)).annotations.toList(), equals(<int>[3, 1, 2, 0,]));
    });

    test('looks for child AnnotatedRegions before parents', () {
      final AnnotatedRegionLayer<int> parent = AnnotatedRegionLayer<int>(1);
      final AnnotatedRegionLayer<int> child1 = AnnotatedRegionLayer<int>(2);
      final AnnotatedRegionLayer<int> child2 = AnnotatedRegionLayer<int>(3);
      final AnnotatedRegionLayer<int> child3 = AnnotatedRegionLayer<int>(4);
      final ContainerLayer layer = ContainerLayer();
      parent.append(child1);
      parent.append(child2);
      parent.append(child3);
      layer.append(parent);

      expect(parent.findAllAnnotations<int>(Offset.zero).annotations.toList(), equals(<int>[4, 3, 2, 1]));
    });

    test('looks for correct type', () {
      final AnnotatedRegionLayer<int> child1 = AnnotatedRegionLayer<int>(1);
      final AnnotatedRegionLayer<String> child2 = AnnotatedRegionLayer<String>('hello');
      final ContainerLayer layer = ContainerLayer();
      layer.append(child2);
      layer.append(child1);

      expect(layer.findAllAnnotations<String>(Offset.zero).annotations.toList(), equals(<String>['hello']));
    });

    test('does not clip Layer.find on an AnnotatedRegion with an unrelated type', () {
      final AnnotatedRegionLayer<int> child = AnnotatedRegionLayer<int>(1);
      final AnnotatedRegionLayer<String> parent = AnnotatedRegionLayer<String>('hello', size: const Size(10.0, 10.0));
      final ContainerLayer layer = ContainerLayer();
      parent.append(child);
      layer.append(parent);

      expect(layer.findAllAnnotations<int>(const Offset(100.0, 100.0)).annotations.toList(), equals(<int>[1]));
    });

    test('handles non-invertible transforms', () {
      final AnnotatedRegionLayer<int> child = AnnotatedRegionLayer<int>(1);
      final TransformLayer parent = TransformLayer(transform: Matrix4.diagonal3Values(0.0, 1.0, 1.0));
      parent.append(child);

      expect(parent.findAllAnnotations<int>(const Offset(0.0, 0.0)).annotations.toList(), equals(<int>[]));

      parent.transform = Matrix4.diagonal3Values(1.0, 1.0, 1.0);

      expect(parent.findAllAnnotations<int>(const Offset(0.0, 0.0)).annotations.toList(), equals(<int>[1]));
    });
  });
}
