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

// @dart = 2.12

import 'package:test/bootstrap/browser.dart';
import 'package:test/test.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart' as ui;

import 'layout_service_helper.dart';

const ui.Color white = ui.Color(0xFFFFFFFF);
const ui.Color black = ui.Color(0xFF000000);
const ui.Color red = ui.Color(0xFFFF0000);
const ui.Color green = ui.Color(0xFF00FF00);
const ui.Color blue = ui.Color(0xFF0000FF);

final EngineParagraphStyle ahemStyle = EngineParagraphStyle(
  fontFamily: 'ahem',
  fontSize: 10,
);

ui.ParagraphConstraints constrain(double width) {
  return ui.ParagraphConstraints(width: width);
}

CanvasParagraph rich(
  EngineParagraphStyle style,
  void Function(CanvasParagraphBuilder) callback,
) {
  final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);
  callback(builder);
  return builder.build();
}

void main() {
  internalBootstrapBrowserTest(() => testMain);
}

void testMain() async {
  await ui.webOnlyInitializeTestDomRenderer();

  test('does not crash on empty spans', () {
    final CanvasParagraph paragraph = rich(ahemStyle, (builder) {
      builder.pushStyle(EngineTextStyle.only(color: blue));
      builder.addText('');

      builder.pushStyle(EngineTextStyle.only(color: red));
      builder.addText('Lorem ipsum');

      builder.pushStyle(EngineTextStyle.only(color: green));
      builder.addText('');
    });

    expect(() => paragraph.layout(constrain(double.infinity)), returnsNormally);
  });

  test('measures spans in the same line correctly', () {
    final CanvasParagraph paragraph = rich(ahemStyle, (builder) {
      builder.pushStyle(EngineTextStyle.only(fontSize: 12.0));
      // 12.0 * 6 = 72.0 (with spaces)
      // 12.0 * 5 = 60.0 (without spaces)
      builder.addText('Lorem ');

      builder.pushStyle(EngineTextStyle.only(fontSize: 13.0));
      // 13.0 * 6 = 78.0 (with spaces)
      // 13.0 * 5 = 65.0 (without spaces)
      builder.addText('ipsum ');

      builder.pushStyle(EngineTextStyle.only(fontSize: 11.0));
      // 11.0 * 5 = 55.0
      builder.addText('dolor');
    })..layout(constrain(double.infinity));

    expect(paragraph.maxIntrinsicWidth, 205.0);
    expect(paragraph.minIntrinsicWidth, 65.0); // "ipsum"
    expect(paragraph.width, double.infinity);
    expectLines(paragraph, [
      l('Lorem ipsum dolor', 0, 17, hardBreak: true, width: 205.0, left: 0.0),
    ]);
  });

  test('breaks lines correctly at the end of spans', () {
    final CanvasParagraph paragraph = rich(ahemStyle, (builder) {
      builder.addText('Lorem ');
      builder.pushStyle(EngineTextStyle.only(fontSize: 15.0));
      builder.addText('sit ');
      builder.pop();
      builder.addText('.');
    })..layout(constrain(60.0));

    expect(paragraph.maxIntrinsicWidth, 130.0);
    expect(paragraph.minIntrinsicWidth, 50.0); // "Lorem"
    expect(paragraph.width, 60.0);
    expectLines(paragraph, [
      l('Lorem ', 0, 6, hardBreak: false, width: 50.0, left: 0.0),
      l('sit ', 6, 10, hardBreak: false, width: 45.0, left: 0.0),
      l('.', 10, 11, hardBreak: true, width: 10.0, left: 0.0),
    ]);
  });

  test('breaks lines correctly in the middle of spans', () {
    final CanvasParagraph paragraph = rich(ahemStyle, (builder) {
      builder.addText('Lorem ipsum ');
      builder.pushStyle(EngineTextStyle.only(fontSize: 11.0));
      builder.addText('sit dolor');
    })..layout(constrain(100.0));

    expect(paragraph.maxIntrinsicWidth, 219.0);
    expect(paragraph.minIntrinsicWidth, 55.0); // "dolor"
    expect(paragraph.width, 100.0);
    expectLines(paragraph, [
      l('Lorem ', 0, 6, hardBreak: false, width: 50.0, left: 0.0),
      l('ipsum sit ', 6, 16, hardBreak: false, width: 93.0, left: 0.0),
      l('dolor', 16, 21, hardBreak: true, width: 55.0, left: 0.0),
    ]);
  });

  test('handles space-only spans', () {
    final CanvasParagraph paragraph = rich(ahemStyle, (builder) {
      builder.pushStyle(EngineTextStyle.only(color: red));
      builder.addText('Lorem ');
      builder.pop();
      builder.pushStyle(EngineTextStyle.only(color: blue));
      builder.addText('   ');
      builder.pushStyle(EngineTextStyle.only(color: green));
      builder.addText('  ');
      builder.pushStyle(EngineTextStyle.only(color: black));
      builder.addText('ipsum');
    });
    paragraph.layout(constrain(80.0));

    expect(paragraph.maxIntrinsicWidth, 160.0);
    expect(paragraph.minIntrinsicWidth, 50.0); // "Lorem" or "ipsum"
    expect(paragraph.width, 80.0);
    expectLines(paragraph, [
      l('Lorem      ', 0, 11, hardBreak: false, width: 50.0, widthWithTrailingSpaces: 110.0, left: 0.0),
      l('ipsum', 11, 16, hardBreak: true, width: 50.0, left: 0.0),
    ]);
  });

  test('should not break at span end if it is not a line break', () {
    final CanvasParagraph paragraph = rich(ahemStyle, (builder) {
      builder.pushStyle(EngineTextStyle.only(color: red));
      builder.addText('Lorem');
      builder.pop();
      builder.pushStyle(EngineTextStyle.only(color: blue));
      builder.addText(' ');
      builder.pushStyle(EngineTextStyle.only(color: black));
      builder.addText('ip');
      builder.pushStyle(EngineTextStyle.only(color: green));
      builder.addText('su');
      builder.pushStyle(EngineTextStyle.only(color: white));
      builder.addText('m');
    })..layout(constrain(50.0));

    expect(paragraph.maxIntrinsicWidth, 110.0);
    expect(paragraph.minIntrinsicWidth, 50.0); // "Lorem" or "ipsum"
    expect(paragraph.width, 50.0);
    expectLines(paragraph, [
      l('Lorem ', 0, 6, hardBreak: false, width: 50.0, left: 0.0),
      l('ipsum', 6, 11, hardBreak: true, width: 50.0, left: 0.0),
    ]);
  });

  test('should handle placeholder-only paragraphs', () {
    final EngineParagraphStyle paragraphStyle = EngineParagraphStyle(
      fontFamily: 'ahem',
      fontSize: 10,
      textAlign: ui.TextAlign.center,
    );
    final CanvasParagraph paragraph = rich(paragraphStyle, (builder) {
      builder.addPlaceholder(300.0, 50.0, ui.PlaceholderAlignment.baseline, baseline: ui.TextBaseline.alphabetic);
    })..layout(constrain(500.0));

    expect(paragraph.maxIntrinsicWidth, 300.0);
    expect(paragraph.minIntrinsicWidth, 300.0);
    expect(paragraph.height, 50.0);
    expectLines(paragraph, [
      l('', 0, 0, hardBreak: true, width: 300.0, left: 100.0),
    ]);
  });

  test('correct maxIntrinsicWidth when paragraph ends with placeholder', () {
    final EngineParagraphStyle paragraphStyle = EngineParagraphStyle(
      fontFamily: 'ahem',
      fontSize: 10,
      textAlign: ui.TextAlign.center,
    );
    final CanvasParagraph paragraph = rich(paragraphStyle, (builder) {
      builder.addText('abcd');
      builder.addPlaceholder(300.0, 50.0, ui.PlaceholderAlignment.bottom);
    })..layout(constrain(400.0));

    expect(paragraph.maxIntrinsicWidth, 340.0);
    expect(paragraph.minIntrinsicWidth, 300.0);
    expect(paragraph.height, 50.0);
    expectLines(paragraph, [
      l('abcd', 0, 4, hardBreak: true, width: 340.0, left: 30.0),
    ]);
  });

  test('handles new line followed by a placeholder', () {
    final EngineParagraphStyle paragraphStyle = EngineParagraphStyle(
      fontFamily: 'ahem',
      fontSize: 10,
      textAlign: ui.TextAlign.center,
    );
    final CanvasParagraph paragraph = rich(paragraphStyle, (builder) {
      builder.addText('Lorem\n');
      builder.addPlaceholder(300.0, 40.0, ui.PlaceholderAlignment.bottom);
      builder.addText('ipsum');
    })..layout(constrain(300.0));

    // The placeholder's width + "ipsum"
    expect(paragraph.maxIntrinsicWidth, 300.0 + 50.0);
    expect(paragraph.minIntrinsicWidth, 300.0);
    expect(paragraph.height, 10.0 + 40.0 + 10.0);
    expectLines(paragraph, [
      l('Lorem', 0, 6, hardBreak: true, width: 50.0, height: 10.0, left: 125.0),
      l('', 6, 6, hardBreak: false, width: 300.0, height: 40.0, left: 0.0),
      l('ipsum', 6, 11, hardBreak: true, width: 50.0, height: 10.0, left: 125.0),
    ]);
  });
}
