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

import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

import '../rendering/src/solid_color_box.dart';

// Solid color, RenderObject version
void addFlexChildSolidColor(RenderFlex parent, Color backgroundColor, { int flex = 0 }) {
  final RenderSolidColorBox child = RenderSolidColorBox(backgroundColor);
  parent.add(child);
  final FlexParentData childParentData = child.parentData! as FlexParentData;
  childParentData.flex = flex;
}

// Solid color, Widget version
class Rectangle extends StatelessWidget {
  const Rectangle(this.color, { super.key });

  final Color color;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      child: Container(
        color: color,
      ),
    );
  }
}

double? value;
RenderObjectToWidgetElement<RenderBox>? element;
void attachWidgetTreeToRenderTree(RenderProxyBox container) {
  element = RenderObjectToWidgetAdapter<RenderBox>(
    container: container,
    child: Directionality(
      textDirection: TextDirection.ltr,
      child: SizedBox(
        height: 300.0,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: <Widget>[
            const Rectangle(Color(0xFF00FFFF)),
            Material(
              child: Container(
                padding: const EdgeInsets.all(10.0),
                margin: const EdgeInsets.all(10.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.spaceAround,
                  children: <Widget>[
                    ElevatedButton(
                      child: const Row(
                        children: <Widget>[
                          FlutterLogo(),
                          Text('PRESS ME'),
                        ],
                      ),
                      onPressed: () {
                        value = value == null ? 0.1 : (value! + 0.1) % 1.0;
                        attachWidgetTreeToRenderTree(container);
                      },
                    ),
                    CircularProgressIndicator(value: value),
                  ],
                ),
              ),
            ),
            const Rectangle(Color(0xFFFFFF00)),
          ],
        ),
      ),
    ),
  ).attachToRenderTree(WidgetsBinding.instance.buildOwner!, element);
}

Duration? timeBase;
late RenderTransform transformBox;

void rotate(Duration timeStamp) {
  timeBase ??= timeStamp;
  final double delta = (timeStamp - timeBase!).inMicroseconds.toDouble() / Duration.microsecondsPerSecond; // radians

  transformBox.setIdentity();
  transformBox.rotateZ(delta);

  WidgetsBinding.instance.buildOwner!.buildScope(element!);
}

void main() {
  final WidgetsBinding binding = WidgetsFlutterBinding.ensureInitialized();
  final RenderProxyBox proxy = RenderProxyBox();
  attachWidgetTreeToRenderTree(proxy);

  final RenderFlex flexRoot = RenderFlex(direction: Axis.vertical);
  addFlexChildSolidColor(flexRoot, const Color(0xFFFF00FF), flex: 1);
  flexRoot.add(proxy);
  addFlexChildSolidColor(flexRoot, const Color(0xFF0000FF), flex: 1);

  transformBox = RenderTransform(child: flexRoot, transform: Matrix4.identity(), alignment: Alignment.center);
  final RenderPadding root = RenderPadding(padding: const EdgeInsets.all(80.0), child: transformBox);

  // TODO(goderbauer): Create a window if embedder doesn't provide an implicit view to draw into.
  assert(binding.platformDispatcher.implicitView != null);
  final RenderView view = RenderView(
    view: binding.platformDispatcher.implicitView!,
    child: root,
  );
  final PipelineOwner pipelineOwner = PipelineOwner()..rootNode = view;
  binding.rootPipelineOwner.adoptChild(pipelineOwner);
  binding.addRenderView(view);
  view.prepareInitialFrame();

  binding.addPersistentFrameCallback(rotate);
}