/// Flutter widget that renders Wolf3D frames as native pixel images.
library;

import 'dart:ui' as ui;

import 'package:flutter/material.dart';
import 'package:wolf_3d_dart/wolf_3d_data_types.dart';
import 'package:wolf_3d_dart/wolf_3d_renderer.dart';
import 'package:wolf_3d_renderer/base_renderer.dart';
import 'package:wolf_3d_renderer/wolf_3d_asset_painter.dart';

/// Presents the software renderer output by decoding the shared framebuffer.
class WolfFlutterRenderer extends BaseWolfRenderer {
  /// Creates a pixel renderer bound to [engine].
  const WolfFlutterRenderer({
    required super.engine,
    super.onKeyEvent,
    super.key,
  });

  @override
  State<WolfFlutterRenderer> createState() => _WolfFlutterRendererState();
}

class _WolfFlutterRendererState
    extends BaseWolfRendererState<WolfFlutterRenderer> {
  static const int _renderWidth = 640;
  static const int _renderHeight = 400;
  final SoftwareRenderer _renderer = SoftwareRenderer();

  ui.Image? _renderedFrame;
  bool _isRendering = false;

  @override
  void initState() {
    super.initState();
    // Render at 2x canonical resolution so menu/UI edges stay crisp and avoid
    // bleed when the output is scaled to the host viewport.
    if (widget.engine.frameBuffer.width != _renderWidth ||
        widget.engine.frameBuffer.height != _renderHeight) {
      widget.engine.setFrameBuffer(_renderWidth, _renderHeight);
    }
  }

  @override
  Color get scaffoldColor => Colors.black;

  @override
  void performRender() {
    if (_isRendering) return;
    _isRendering = true;

    final FrameBuffer frameBuffer = widget.engine.frameBuffer;
    _renderer.render(widget.engine);

    // Convert the engine-owned framebuffer into a GPU-friendly ui.Image on
    // the Flutter side while preserving nearest-neighbor pixel fidelity.
    ui.decodeImageFromPixels(
      frameBuffer.pixels.buffer.asUint8List(),
      frameBuffer.width,
      frameBuffer.height,
      ui.PixelFormat.rgba8888,
      (ui.Image image) {
        if (mounted) {
          setState(() {
            _renderedFrame?.dispose();
            _renderedFrame = image;
          });
        }
        _isRendering = false;
      },
    );
  }

  @override
  Widget buildViewport(BuildContext context) {
    // Delay painting until at least one decoded frame is available.
    if (_renderedFrame == null) {
      return const CircularProgressIndicator(color: Colors.white24);
    }

    return Padding(
      padding: const EdgeInsets.all(16.0),
      child: AspectRatio(
        aspectRatio: 4 / 3,
        child: WolfAssetPainter.frame(_renderedFrame),
      ),
    );
  }
}
