// 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 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';

import 'rendering_tester.dart';

void main() {
  TestRenderingFlutterBinding.ensureInitialized();

  test('RenderBaseline', () {
    RenderBaseline parent;
    RenderSizedBox child;
    final RenderBox root = RenderPositionedBox(
      alignment: Alignment.topLeft,
      child: parent = RenderBaseline(
        baseline: 0.0,
        baselineType: TextBaseline.alphabetic,
        child: child = RenderSizedBox(const Size(100.0, 100.0)),
      ),
    );
    final BoxParentData childParentData = child.parentData! as BoxParentData;

    layout(root);
    expect(childParentData.offset.dx, equals(0.0));
    expect(childParentData.offset.dy, equals(-100.0));
    expect(parent.size, equals(const Size(100.0, 0.0)));

    parent.baseline = 25.0;
    pumpFrame();
    expect(childParentData.offset.dx, equals(0.0));
    expect(childParentData.offset.dy, equals(-75.0));
    expect(parent.size, equals(const Size(100.0, 25.0)));

    parent.baseline = 90.0;
    pumpFrame();
    expect(childParentData.offset.dx, equals(0.0));
    expect(childParentData.offset.dy, equals(-10.0));
    expect(parent.size, equals(const Size(100.0, 90.0)));

    parent.baseline = 100.0;
    pumpFrame();
    expect(childParentData.offset.dx, equals(0.0));
    expect(childParentData.offset.dy, equals(0.0));
    expect(parent.size, equals(const Size(100.0, 100.0)));

    parent.baseline = 110.0;
    pumpFrame();
    expect(childParentData.offset.dx, equals(0.0));
    expect(childParentData.offset.dy, equals(10.0));
    expect(parent.size, equals(const Size(100.0, 110.0)));
  });

  test('RenderBaseline different baseline types', () {
    final _RenderBaselineTester child = _RenderBaselineTester()
     ..boxSize = const Size.square(100)
     ..alphabeticBaselineOffset = 50
     ..ideographicBaselineOffset = 60;
    final RenderBaseline renderBaseline = RenderBaseline(
      baseline: 1.0,
      baselineType: TextBaseline.alphabetic,
      child: child,
    );

    layout(renderBaseline, phase: EnginePhase.paint);
    expect(renderBaseline.getDryBaseline(const BoxConstraints(), TextBaseline.alphabetic), 1.0);
    expect(renderBaseline.getDryBaseline(const BoxConstraints(), TextBaseline.ideographic), 11.0);

    child
     ..alphabeticBaselineOffset = null
     ..ideographicBaselineOffset = null
     ..markNeedsLayout(); // Clears baseline cache.

    renderBaseline.markNeedsLayout();

    pumpFrame(phase: EnginePhase.paint);
    expect(renderBaseline.getDryBaseline(const BoxConstraints(), TextBaseline.alphabetic), isNull);
    expect(renderBaseline.getDryBaseline(const BoxConstraints(), TextBaseline.ideographic), isNull);
  });

  test('RenderFlex and RenderIgnoreBaseline (control test -- with baseline)', () {
    final RenderBox a, b;
    final RenderBox root = RenderFlex(
      crossAxisAlignment: CrossAxisAlignment.baseline,
      textBaseline: TextBaseline.alphabetic,
      textDirection: TextDirection.ltr,
      children: <RenderBox>[
        a = RenderParagraph(
          const TextSpan(text: 'a', style: TextStyle(fontSize: 128.0, fontFamily: 'FlutterTest')), // places baseline at y=96
          textDirection: TextDirection.ltr,
        ),
        b = RenderParagraph(
          const TextSpan(text: 'b', style: TextStyle(fontSize: 32.0, fontFamily: 'FlutterTest')), // 24 above baseline, 8 below baseline
          textDirection: TextDirection.ltr,
        ),
      ],
    );
    layout(root);

    final Offset aPos = a.localToGlobal(Offset.zero);
    final Offset bPos = b.localToGlobal(Offset.zero);
    expect(aPos.dy, 0.0);
    expect(bPos.dy, 96.0 - 24.0);
  });

  test('RenderFlex and RenderIgnoreBaseline (with ignored baseline)', () {
    final RenderBox a, b;
    final RenderBox root = RenderFlex(
      crossAxisAlignment: CrossAxisAlignment.baseline,
      textBaseline: TextBaseline.alphabetic,
      textDirection: TextDirection.ltr,
      children: <RenderBox>[
        RenderIgnoreBaseline(
          child: a = RenderParagraph(
            const TextSpan(text: 'a', style: TextStyle(fontSize: 128.0, fontFamily: 'FlutterTest')),
            textDirection: TextDirection.ltr,
          ),
        ),
        b = RenderParagraph(
          const TextSpan(text: 'b', style: TextStyle(fontSize: 32.0, fontFamily: 'FlutterTest')),
          textDirection: TextDirection.ltr,
        ),
      ],
    );
    layout(root);

    final Offset aPos = a.localToGlobal(Offset.zero);
    final Offset bPos = b.localToGlobal(Offset.zero);
    expect(aPos.dy, 0.0);
    expect(bPos.dy, 0.0);
  });
}

class _RenderBaselineTester extends RenderBox {
  Size boxSize = Size.zero;
  double? alphabeticBaselineOffset;
  double? ideographicBaselineOffset;

  @override
  double? computeDistanceToActualBaseline(TextBaseline baseline) {
    return switch (baseline) {
      TextBaseline.alphabetic => alphabeticBaselineOffset,
      TextBaseline.ideographic => ideographicBaselineOffset,
    };
  }

  @override
  double? computeDryBaseline(covariant BoxConstraints constraints, TextBaseline baseline) {
    return switch (baseline) {
      TextBaseline.alphabetic => alphabeticBaselineOffset,
      TextBaseline.ideographic => ideographicBaselineOffset,
    };
  }

  @override
  Size computeDryLayout(covariant BoxConstraints constraints) => constraints.constrain(boxSize);

  @override
  void performLayout() {
    size = computeDryLayout(constraints);
  }
}
