// 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:ui/ui.dart' as ui;

import '../../engine.dart' show kProfilePrerollFrame, kProfileApplyFrame;
import '../profiler.dart';
import '../vector_math.dart';
import 'canvas.dart';
import 'embedded_views.dart';
import 'layer.dart';
import 'n_way_canvas.dart';
import 'picture_recorder.dart';
import 'raster_cache.dart';

/// A tree of [Layer]s that, together with a [Size] compose a frame.
class LayerTree {
  LayerTree(this.rootLayer);

  /// The root of the layer tree.
  final RootLayer rootLayer;

  /// The size (in physical pixels) of the frame to paint this layer tree into.
  final ui.Size frameSize = ui.window.physicalSize;

  /// The devicePixelRatio of the frame to paint this layer tree into.
  double? devicePixelRatio;

  /// Performs a preroll phase before painting the layer tree.
  ///
  /// In this phase, the paint boundary for each layer is computed and
  /// pictures are registered with the raster cache as potential candidates
  /// to raster. If [ignoreRasterCache] is `true`, then there will be no
  /// attempt to register pictures to cache.
  void preroll(Frame frame, {bool ignoreRasterCache = false}) {
    final PrerollContext context = PrerollContext(
      ignoreRasterCache ? null : frame.rasterCache,
      frame.viewEmbedder,
    );
    rootLayer.preroll(context, Matrix4.identity());
  }

  /// Paints the layer tree into the given [frame].
  ///
  /// If [ignoreRasterCache] is `true`, then the raster cache will
  /// not be used.
  void paint(Frame frame, {bool ignoreRasterCache = false}) {
    final CkNWayCanvas internalNodesCanvas = CkNWayCanvas();
    internalNodesCanvas.addCanvas(frame.canvas);
    final List<CkCanvas> overlayCanvases =
        frame.viewEmbedder!.getCurrentCanvases();
    for (int i = 0; i < overlayCanvases.length; i++) {
      internalNodesCanvas.addCanvas(overlayCanvases[i]);
    }
    // Clear the canvases before painting
    internalNodesCanvas.clear(const ui.Color(0x00000000));
    final PaintContext context = PaintContext(
      internalNodesCanvas,
      frame.canvas,
      ignoreRasterCache ? null : frame.rasterCache,
      frame.viewEmbedder,
    );
    if (rootLayer.needsPainting) {
      rootLayer.paint(context);
    }
  }

  /// Flattens the tree into a single [ui.Picture].
  ///
  /// This picture does not contain any platform views.
  ui.Picture flatten() {
    final CkPictureRecorder recorder = CkPictureRecorder();
    final CkCanvas canvas = recorder.beginRecording(ui.Rect.largest);
    final PrerollContext prerollContext = PrerollContext(null, null);
    rootLayer.preroll(prerollContext, Matrix4.identity());

    final CkNWayCanvas internalNodesCanvas = CkNWayCanvas();
    internalNodesCanvas.addCanvas(canvas);
    final PaintContext paintContext =
        PaintContext(internalNodesCanvas, canvas, null, null);
    if (rootLayer.needsPainting) {
      rootLayer.paint(paintContext);
    }
    return recorder.endRecording();
  }
}

/// A single frame to be rendered.
class Frame {
  /// The canvas to render this frame to.
  final CkCanvas canvas;

  /// A cache of pre-rastered pictures.
  final RasterCache? rasterCache;

  /// The platform view embedder.
  final HtmlViewEmbedder? viewEmbedder;

  Frame(this.canvas, this.rasterCache, this.viewEmbedder);

  /// Rasterize the given layer tree into this frame.
  bool raster(LayerTree layerTree, {bool ignoreRasterCache = false}) {
    timeAction<void>(kProfilePrerollFrame, () {
      layerTree.preroll(this, ignoreRasterCache: ignoreRasterCache);
    });
    timeAction<void>(kProfileApplyFrame, () {
      layerTree.paint(this, ignoreRasterCache: ignoreRasterCache);
    });
    return true;
  }
}

/// The state of the compositor, which is persisted between frames.
class CompositorContext {
  /// A cache of pictures, which is shared between successive frames.
  RasterCache? rasterCache;

  /// Acquire a frame using this compositor's settings.
  Frame acquireFrame(CkCanvas canvas, HtmlViewEmbedder? viewEmbedder) {
    return Frame(canvas, rasterCache, viewEmbedder);
  }
}
