// 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.
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();
}
