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

// This example shows how to draw some bi-directional text using the raw
// interface to the engine.

import 'dart:typed_data';
import 'dart:ui' as ui;

// A paragraph represents a rectangular region that contains some text.
late ui.Paragraph paragraph;

ui.Picture paint(ui.Rect paintBounds) {
  final ui.PictureRecorder recorder = ui.PictureRecorder();
  final ui.Canvas canvas = ui.Canvas(recorder, paintBounds);

  final double devicePixelRatio = ui.window.devicePixelRatio;
  final ui.Size logicalSize = ui.window.physicalSize / devicePixelRatio;

  canvas.translate(logicalSize.width / 2.0, logicalSize.height / 2.0);
  canvas.drawRect(const ui.Rect.fromLTRB(-100.0, -100.0, 100.0, 100.0),
                  ui.Paint()..color = const ui.Color.fromARGB(255, 0, 255, 0));

  // The paint method of Paragraph draws the contents of the paragraph onto the
  // given canvas.
  canvas.drawParagraph(paragraph, ui.Offset(-paragraph.width / 2.0, (paragraph.width / 2.0) - 125.0));

  return recorder.endRecording();
}

ui.Scene composite(ui.Picture picture, ui.Rect paintBounds) {
  final double devicePixelRatio = ui.window.devicePixelRatio;
  final Float64List deviceTransform = Float64List(16)
    ..[0] = devicePixelRatio
    ..[5] = devicePixelRatio
    ..[10] = 1.0
    ..[15] = 1.0;
  final ui.SceneBuilder sceneBuilder = ui.SceneBuilder()
    ..pushTransform(deviceTransform)
    ..addPicture(ui.Offset.zero, picture)
    ..pop();
  return sceneBuilder.build();
}

void beginFrame(Duration timeStamp) {
  final ui.Rect paintBounds = ui.Offset.zero & (ui.window.physicalSize / ui.window.devicePixelRatio);
  final ui.Picture picture = paint(paintBounds);
  final ui.Scene scene = composite(picture, paintBounds);
  ui.window.render(scene);
}

void main() {
  // To create a paragraph of text, we use ParagraphBuilder.
  final ui.ParagraphBuilder builder = ui.ParagraphBuilder(
    // The text below has a primary direction of left-to-right.
    // The embedded text has other directions.
    // If this was TextDirection.rtl, the "Hello, world" text would end up on
    // the other side of the right-to-left text.
    ui.ParagraphStyle(textDirection: ui.TextDirection.ltr),
  )
    // We first push a style that turns the text blue.
    ..pushStyle(ui.TextStyle(color: const ui.Color(0xFF0000FF)))
    ..addText('Hello, ')
    // The next run of text will be bold.
    ..pushStyle(ui.TextStyle(fontWeight: ui.FontWeight.bold))
    ..addText('world. ')
    // The pop() command signals the end of the bold styling.
    ..pop()
    // We add text to the paragraph in logical order. The paragraph object
    // understands bi-directional text and will compute the visual ordering
    // during layout.
    ..addText('هذا هو قليلا طويلة من النص الذي يجب التفاف .')
    // The second pop() removes the blue color.
    ..pop()
    // We can add more text with the default styling.
    ..addText(' و أكثر قليلا لجعله أطول. ')
    ..addText('สวัสดี');
  // When we're done adding styles and text, we build the Paragraph object, at
  // which time we can apply styling that affects the entire paragraph, such as
  // left, right, or center alignment. Once built, the contents of the paragraph
  // cannot be altered, but sizing and positioning information can be updated.
  paragraph = builder.build()
    // Next, we supply a width that the text is permitted to occupy and we ask
    // the paragraph to the visual position of each its glyphs as well as its
    // overall size, subject to its sizing constraints.
    ..layout(const ui.ParagraphConstraints(width: 180.0));

  // Finally, we register our beginFrame callback and kick off the first frame.
  ui.window.onBeginFrame = beginFrame;
  ui.window.scheduleFrame();
}
