// Copyright 2013 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:test/test.dart';
import 'package:ui/src/engine.dart';

TestLine l(
  String? displayText,
  int? startIndex,
  int? endIndex, {
  int?  endIndexWithoutNewlines,
  bool? hardBreak,
  double? height,
  double? width,
  double? widthWithTrailingSpaces,
  double? left,
  double? baseline,
}) {
  return TestLine(
    displayText: displayText,
    startIndex: startIndex,
    endIndex: endIndex,
    endIndexWithoutNewlines: endIndexWithoutNewlines,
    hardBreak: hardBreak,
    height: height,
    width: width,
    widthWithTrailingSpaces: widthWithTrailingSpaces,
    left: left,
    baseline: baseline,
  );
}

void expectLines(CanvasParagraph paragraph, List<TestLine> expectedLines) {
  final String text = paragraph.toPlainText();
  final List<ParagraphLine> lines = paragraph.lines;
  expect(lines, hasLength(expectedLines.length));
  for (int i = 0; i < lines.length; i++) {
    final ParagraphLine line = lines[i];
    final TestLine expectedLine = expectedLines[i];

    expect(
      line.lineNumber,
      i,
      reason: 'line #$i had the wrong `lineNumber`. Expected: $i. Actual: ${line.lineNumber}',
    );
    if (expectedLine.displayText != null) {
      String displayText =
          text.substring(line.startIndex, line.endIndexWithoutNewlines);
      if (line.ellipsis != null) {
        displayText += line.ellipsis!;
      }
      expect(
        displayText,
        expectedLine.displayText,
        reason:
            'line #$i had a different `displayText` value: "$displayText" vs. "${expectedLine.displayText}"',
      );
    }
    if (expectedLine.startIndex != null) {
      expect(
        line.startIndex,
        expectedLine.startIndex,
        reason:
            'line #$i had a different `startIndex` value: "${line.startIndex}" vs. "${expectedLine.startIndex}"',
      );
    }
    if (expectedLine.endIndex != null) {
      expect(
        line.endIndex,
        expectedLine.endIndex,
        reason:
            'line #$i had a different `endIndex` value: "${line.endIndex}" vs. "${expectedLine.endIndex}"',
      );
    }
    if (expectedLine.endIndexWithoutNewlines != null) {
      expect(
        line.endIndexWithoutNewlines,
        expectedLine.endIndexWithoutNewlines,
        reason:
            'line #$i had a different `endIndexWithoutNewlines` value: "${line.endIndexWithoutNewlines}" vs. "${expectedLine.endIndexWithoutNewlines}"',
      );
    }
    if (expectedLine.hardBreak != null) {
      expect(
        line.hardBreak,
        expectedLine.hardBreak,
        reason:
            'line #$i had a different `hardBreak` value: "${line.hardBreak}" vs. "${expectedLine.hardBreak}"',
      );
    }
    if (expectedLine.height != null) {
      expect(
        line.height,
        expectedLine.height,
        reason:
            'line #$i had a different `height` value: "${line.height}" vs. "${expectedLine.height}"',
      );
    }
    if (expectedLine.width != null) {
      expect(
        line.width,
        expectedLine.width,
        reason:
            'line #$i had a different `width` value: "${line.width}" vs. "${expectedLine.width}"',
      );
    }
    if (expectedLine.widthWithTrailingSpaces != null) {
      expect(
        line.widthWithTrailingSpaces,
        expectedLine.widthWithTrailingSpaces,
        reason:
            'line #$i had a different `widthWithTrailingSpaces` value: "${line.widthWithTrailingSpaces}" vs. "${expectedLine.widthWithTrailingSpaces}"',
      );
    }
    if (expectedLine.left != null) {
      expect(
        line.left,
        expectedLine.left,
        reason:
            'line #$i had a different `left` value: "${line.left}" vs. "${expectedLine.left}"',
      );
    }
  }
}

class TestLine {
  TestLine({
    this.displayText,
    this.startIndex,
    this.endIndex,
    this.endIndexWithoutNewlines,
    this.hardBreak,
    this.height,
    this.width,
    this.widthWithTrailingSpaces,
    this.left,
    this.baseline,
  });

  final String? displayText;
  final int? startIndex;
  final int? endIndex;
  final int? endIndexWithoutNewlines;
  final bool? hardBreak;
  final double? height;
  final double? width;
  final double? widthWithTrailingSpaces;
  final double? left;
  final double? baseline;
}
