// 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 'dart:async';

import 'package:ui/src/engine.dart';
import 'package:ui/ui.dart';
import 'package:web_engine_tester/golden_tester.dart';

typedef CanvasTest = FutureOr<void> Function(EngineCanvas canvas);

const LineBreakType prohibited = LineBreakType.prohibited;
const LineBreakType opportunity = LineBreakType.opportunity;
const LineBreakType mandatory = LineBreakType.mandatory;
const LineBreakType endOfText = LineBreakType.endOfText;

const TextDirection ltr = TextDirection.ltr;
const TextDirection rtl = TextDirection.rtl;

const FragmentFlow ffLtr = FragmentFlow.ltr;
const FragmentFlow ffRtl = FragmentFlow.rtl;
const FragmentFlow ffPrevious = FragmentFlow.previous;
const FragmentFlow ffSandwich = FragmentFlow.sandwich;

const String rtlWord1 = 'واحدة';
const String rtlWord2 = 'ثنتان';

const Color white = Color(0xFFFFFFFF);
const Color black = Color(0xFF000000);
const Color red = Color(0xFFFF0000);
const Color lightGreen = Color(0xFFDCEDC8);
const Color green = Color(0xFF00FF00);
const Color lightBlue = Color(0xFFB3E5FC);
const Color blue = Color(0xFF0000FF);
const Color yellow = Color(0xFFFFEB3B);
const Color lightPurple = Color(0xFFE1BEE7);

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

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

CanvasParagraph plain(
  EngineParagraphStyle style,
  String text, {
  EngineTextStyle? textStyle,
}) {
  final CanvasParagraphBuilder builder = CanvasParagraphBuilder(style);
  if (textStyle != null) {
    builder.pushStyle(textStyle);
  }
  builder.addText(text);
  return builder.build();
}

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

Future<void> takeScreenshot(
  EngineCanvas canvas,
  Rect region,
  String fileName,
) async {
  final DomElement sceneElement = createDomElement('flt-scene');
  if (isIosSafari) {
    // Shrink to fit on the iPhone screen.
    sceneElement.style.position = 'absolute';
    sceneElement.style.transformOrigin = '0 0 0';
    sceneElement.style.transform = 'scale(0.3)';
  }
  try {
    sceneElement.append(canvas.rootElement);
    domDocument.body!.append(sceneElement);
    await matchGoldenFile('$fileName.png', region: region);
  } finally {
    // The page is reused across tests, so remove the element after taking the
    // Scuba screenshot.
    sceneElement.remove();
  }
}

/// Fills the single placeholder in the given [paragraph] with a red rectangle.
///
/// The placeholder is filled relative to [offset].
///
/// Throws if the paragraph contains more than one placeholder.
void fillPlaceholder(
  EngineCanvas canvas,
  Offset offset,
  CanvasParagraph paragraph,
) {
  final TextBox placeholderBox = paragraph.getBoxesForPlaceholders().single;
  final SurfacePaint paint = SurfacePaint()..color = red;
  canvas.drawRect(placeholderBox.toRect().shift(offset), paint.paintData);
}


/// Fill the given [boxes] with rectangles of the given [color].
///
/// All rectangles are filled relative to [offset].
void fillBoxes(EngineCanvas canvas, Offset offset, List<TextBox> boxes, Color color) {
  for (final TextBox box in boxes) {
    final Rect rect = box.toRect().shift(offset);
    canvas.drawRect(rect, SurfacePaintData()..color = color.value);
  }
}

String getSpanText(CanvasParagraph paragraph, ParagraphSpan span) {
  return paragraph.plainText.substring(span.start, span.end);
}
