// 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/bootstrap/browser.dart';
import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';

import 'text_scuba.dart';

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

Future<void> testMain() async {
  final EngineScubaTester scuba = await EngineScubaTester.initialize(
    viewportSize: const Size(800, 800),
  );

  setUpStableTestFonts();

  void drawLetterAndWordSpacing(EngineCanvas canvas) {
    Offset offset = Offset.zero;

    for (double spacing = 0; spacing < 15; spacing += 5) {
      canvas.drawParagraph(
        paragraph('HelloWorld',
            textStyle: TextStyle(
                color: const Color(0xFF000000),
                decoration: TextDecoration.none,
                fontFamily: 'Roboto',
                fontSize: 30,
                letterSpacing: spacing)),
        offset,
      );
      offset = offset.translate(0, 40);
    }
    for (double spacing = 0; spacing < 30; spacing += 10) {
      final TextStyle textStyle = TextStyle(
          color: const Color(0xFF00FF00),
          decoration: TextDecoration.none,
          fontFamily: 'Roboto',
          fontSize: 30,
          wordSpacing: spacing);
      canvas.drawParagraph(
        paragraph('Hello World', textStyle: textStyle, maxWidth: 600),
        offset,
      );
      offset = offset.translate(0, 40);
    }
  }

  testEachCanvas('draws text with letter/word spacing', (EngineCanvas canvas) {
    drawLetterAndWordSpacing(canvas);
    return scuba.diffCanvasScreenshot(
        canvas, 'paint_bounds_for_text_style_letter_spacing');
  });

  void drawTextDecorationStyle(EngineCanvas canvas) {
    final List<TextDecorationStyle> decorationStyles = <TextDecorationStyle>[
      TextDecorationStyle.solid,
      TextDecorationStyle.double,
      TextDecorationStyle.dotted,
      TextDecorationStyle.dashed,
      TextDecorationStyle.wavy,
    ];

    Offset offset = Offset.zero;

    for (final TextDecorationStyle decorationStyle in decorationStyles) {
      final TextStyle textStyle = TextStyle(
        color: const Color.fromRGBO(50, 50, 255, 1.0),
        decoration: TextDecoration.underline,
        decorationStyle: decorationStyle,
        decorationColor: const Color.fromRGBO(50, 50, 50, 1.0),
        fontFamily: 'Roboto',
        fontSize: 30,
      );
      canvas.drawParagraph(
        paragraph('Hello World', textStyle: textStyle, maxWidth: 600),
        offset,
      );
      offset = offset.translate(0, 40);
    }
  }

  testEachCanvas('draws text decoration style', (EngineCanvas canvas) {
    drawTextDecorationStyle(canvas);
    return scuba.diffCanvasScreenshot(
        canvas, 'paint_bounds_for_text_decorationStyle');
  });

  void drawTextDecoration(EngineCanvas canvas) {
    final List<TextDecoration> decorations = <TextDecoration>[
      TextDecoration.overline,
      TextDecoration.underline,
      TextDecoration.combine(<TextDecoration>[
        TextDecoration.underline,
        TextDecoration.lineThrough
      ]),
      TextDecoration.combine(
          <TextDecoration>[TextDecoration.underline, TextDecoration.overline]),
      TextDecoration.combine(
          <TextDecoration>[TextDecoration.overline, TextDecoration.lineThrough])
    ];

    Offset offset = Offset.zero;

    for (final TextDecoration decoration in decorations) {
      final TextStyle textStyle = TextStyle(
        color: const Color.fromRGBO(50, 50, 255, 1.0),
        decoration: decoration,
        decorationStyle: TextDecorationStyle.solid,
        decorationColor: const Color.fromRGBO(255, 160, 0, 1.0),
        fontFamily: 'Roboto',
        fontSize: 20,
      );
      canvas.drawParagraph(
        paragraph(
          'Hello World $decoration',
          textStyle: textStyle,
          maxWidth: 600,
        ),
        offset,
      );
      offset = offset.translate(0, 40);
    }
  }

  testEachCanvas('draws text decoration', (EngineCanvas canvas) {
    drawTextDecoration(canvas);
    return scuba.diffCanvasScreenshot(
        canvas, 'paint_bounds_for_text_decoration');
  });

  void drawTextWithBackground(EngineCanvas canvas) {
    // Single-line text.
    canvas.drawParagraph(
      paragraph(
        'Hello World',
        maxWidth: 600,
        textStyle: TextStyle(
          color: const Color.fromRGBO(0, 0, 0, 1.0),
          background: Paint()..color = const Color.fromRGBO(255, 50, 50, 1.0),
          fontFamily: 'Roboto',
          fontSize: 30,
        ),
      ),
      Offset.zero,
    );

    // Multi-line text.
    canvas.drawParagraph(
      paragraph(
        'Multi line Hello World paragraph',
        maxWidth: 200,
        textStyle: TextStyle(
          color: const Color.fromRGBO(0, 0, 0, 1.0),
          background: Paint()..color = const Color.fromRGBO(50, 50, 255, 1.0),
          fontFamily: 'Roboto',
          fontSize: 30,
        ),
      ),
      const Offset(0, 40),
    );
  }

  void drawTextWithShadow(EngineCanvas canvas) {
    // Single-line text.
    canvas.drawParagraph(
      paragraph(
        'Hello World',
        maxWidth: 600,
        textStyle: TextStyle(
          color: const Color.fromRGBO(0, 0, 0, 1.0),
          background: Paint()..color = const Color.fromRGBO(255, 50, 50, 1.0),
          fontFamily: 'Roboto',
          fontSize: 30,
          shadows: <Shadow>[
            const Shadow(
              blurRadius: 0,
              color: Color.fromRGBO(255, 0, 255, 1.0),
              offset: Offset(10, 5),
            ),
          ],
        ),
      ),
      Offset.zero,
    );

    // Multi-line text.
    canvas.drawParagraph(
      paragraph(
        'Multi line Hello World paragraph',
        maxWidth: 200,
        textStyle: TextStyle(
          color: const Color.fromRGBO(0, 0, 0, 1.0),
          background: Paint()..color = const Color.fromRGBO(50, 50, 255, 1.0),
          fontFamily: 'Roboto',
          fontSize: 30,
          shadows: <Shadow>[
            const Shadow(
              blurRadius: 0,
              color: Color.fromRGBO(255, 0, 255, 1.0),
              offset: Offset(10, 5),
            ),
            const Shadow(
              blurRadius: 0,
              color: Color.fromRGBO(0, 255, 255, 1.0),
              offset: Offset(-10, -5),
            ),
          ],
        ),
      ),
      const Offset(0, 40),
    );
  }

  testEachCanvas('draws text with a background', (EngineCanvas canvas) {
    drawTextWithBackground(canvas);
    return scuba.diffCanvasScreenshot(canvas, 'text_background');
  });

  testEachCanvas('draws text with a shadow', (EngineCanvas canvas) {
    drawTextWithShadow(canvas);
    return scuba.diffCanvasScreenshot(canvas, 'text_shadow', maxDiffRatePercent: 0.2);
  });

  testEachCanvas('Handles disabled strut style', (EngineCanvas canvas) {
    // Flutter uses [StrutStyle.disabled] for the [SelectableText] widget. This
    // translates into a strut style with a [height] of 0, which wasn't being
    // handled correctly by the web engine.
    final StrutStyle disabled = StrutStyle(height: 0, leading: 0);
    canvas.drawParagraph(
      paragraph(
        'Hello\nWorld',
        paragraphStyle: ParagraphStyle(strutStyle: disabled),
      ),
      Offset.zero,
    );
    return scuba.diffCanvasScreenshot(
      canvas,
      'text_strut_style_disabled',
      region: const Rect.fromLTRB(0, 0, 100, 100),
      maxDiffRatePercent: 0.0,
    );
  });
}
