// 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 'dart:ffi';
import 'dart:typed_data';

import 'package:ui/src/engine/skwasm/skwasm_impl.dart';
import 'package:ui/ui.dart' as ui;

class SkwasmVertices extends SkwasmObjectWrapper<RawVertices> implements ui.Vertices {
  factory SkwasmVertices(
    ui.VertexMode mode,
    List<ui.Offset> positions, {
    List<ui.Offset>? textureCoordinates,
    List<ui.Color>? colors,
    List<int>? indices,
  }) => withStackScope((StackScope scope) {
    final RawPointArray rawPositions = scope.convertPointArrayToNative(positions);
    final RawPointArray rawTextureCoordinates = textureCoordinates != null
        ? scope.convertPointArrayToNative(textureCoordinates)
        : nullptr;
    final RawColorArray rawColors = colors != null
        ? scope.convertColorArrayToNative(colors)
        : nullptr;
    final Pointer<Uint16> rawIndices = indices != null
        ? scope.convertIntsToUint16Native(indices)
        : nullptr;
    final int indexCount = indices != null ? indices.length : 0;
    return SkwasmVertices._(
      verticesCreate(
        mode.index,
        positions.length,
        rawPositions,
        rawTextureCoordinates,
        rawColors,
        indexCount,
        rawIndices,
      ),
    );
  });

  factory SkwasmVertices.raw(
    ui.VertexMode mode,
    Float32List positions, {
    Float32List? textureCoordinates,
    Int32List? colors,
    Uint16List? indices,
  }) => withStackScope((StackScope scope) {
    final RawPointArray rawPositions = scope.convertDoublesToNative(positions);
    final RawPointArray rawTextureCoordinates = textureCoordinates != null
        ? scope.convertDoublesToNative(textureCoordinates)
        : nullptr;
    final RawColorArray rawColors = colors != null
        ? scope.convertIntsToUint32Native(colors)
        : nullptr;
    final Pointer<Uint16> rawIndices = indices != null
        ? scope.convertIntsToUint16Native(indices)
        : nullptr;
    final int indexCount = indices != null ? indices.length : 0;
    return SkwasmVertices._(
      verticesCreate(
        mode.index,
        positions.length ~/ 2,
        rawPositions,
        rawTextureCoordinates,
        rawColors,
        indexCount,
        rawIndices,
      ),
    );
  });

  SkwasmVertices._(VerticesHandle handle) : super(handle, _registry);

  static final SkwasmFinalizationRegistry<RawVertices> _registry =
      SkwasmFinalizationRegistry<RawVertices>((VerticesHandle handle) => verticesDispose(handle));
}
