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

// ignore_for_file: camel_case_types, non_constant_identifier_names

import 'dart:ffi' as ffi;
import 'dart:io';
import 'dart:typed_data';

/// Determines the winding rule that decides how the interior of a Path is
/// calculated.
///
/// This enum is used by the [Path] constructor
// must match ordering in //third_party/skia/include/core/SkPathTypes.h
enum FillType {
  /// The interior is defined by a non-zero sum of signed edge crossings.
  nonZero,

  /// The interior is defined by an odd number of edge crossings.
  evenOdd,
}

/// A set of operations applied to two paths.
// Sync with //third_party/skia/include/pathops/SkPathOps.h
enum PathOp {
  /// Subtracts the second path from the first.
  difference,

  /// Creates a new path representing the intersection of the first and second.
  intersect,

  /// Creates a new path representing the union of the first and second
  /// (includive-or).
  union,

  /// Creates a new path representing the exclusive-or of two paths.
  xor,

  /// Creates a new path that subtracts the first path from the second.s
  reversedDifference,
}

/// The commands used in a [Path] object.
///
/// This enumeration is a subset of the commands that SkPath supports.
// Sync with //third_party/skia/include/core/SkPathTypes.h
enum PathVerb {
  /// Picks up the pen and moves it without drawing. Uses two point values.
  moveTo,

  /// A straight line from the current point to the specified point.
  lineTo,

  _quadTo,
  _conicTo,

  /// A cubic bezier curve from the current point.
  ///
  /// The next two points are used as the first control point. The next two
  /// points form the second control point. The next two points form the
  /// target point.
  cubicTo,

  /// A straight line from the current point to the last [moveTo] point.
  close,
}

/// A proxy class for [Path.replay].
///
/// Allows implementations to easily inspect the contents of a [Path].
abstract class PathProxy {
  /// Picks up the pen and moves to absolute coordinates x,y.
  void moveTo(double x, double y);

  /// Draws a straight line from the current point to absolute coordinates x,y.
  void lineTo(double x, double y);

  /// Creates a cubic Bezier curve from the current point to point x3,y3 using
  /// x1,y1 as the first control point and x2,y2 as the second.
  void cubicTo(
      double x1, double y1, double x2, double y2, double x3, double y3);

  /// Draws a straight line from the current point to the last [moveTo] point.
  void close();

  /// Called by [Path.replay] to indicate that a new path is being played.
  void reset() {}
}

/// A path proxy that can print the SVG path-data representation of this path.
class SvgPathProxy implements PathProxy {
  final StringBuffer _buffer = StringBuffer();

  @override
  void reset() {
    _buffer.clear();
  }

  @override
  void close() {
    _buffer.write('Z');
  }

  @override
  void cubicTo(
      double x1, double y1, double x2, double y2, double x3, double y3) {
    _buffer.write('C$x1,$y1 $x2,$y2 $x3,$y3');
  }

  @override
  void lineTo(double x, double y) {
    _buffer.write('L$x,$y');
  }

  @override
  void moveTo(double x, double y) {
    _buffer.write('M$x,$y');
  }

  @override
  String toString() => _buffer.toString();
}

/// Creates a path object to operate on.
///
/// First, build up the path contours with the [moveTo], [lineTo], [cubicTo],
/// and [close] methods. All methods expect absolute coordinates.
///
/// Finally, use the [dispose] method to clean up native resources. After
/// [dispose] has been called, this class must not be used again.
class Path implements PathProxy {
  /// Creates an empty path object with the specified fill type.
  Path([FillType fillType = FillType.nonZero])
      : _path = _createPathFn(fillType.index);

  /// Creates a copy of this path.
  factory Path.from(Path other) {
    final Path result = Path(other.fillType);
    other.replay(result);
    return result;
  }

  /// The [FillType] of this path.
  FillType get fillType {
    assert(_path != null);
    return FillType.values[_getFillTypeFn(_path!)];
  }

  ffi.Pointer<_SkPath>? _path;
  ffi.Pointer<_PathData>? _pathData;

  /// The number of points used by each [PathVerb].
  static const Map<PathVerb, int> pointsPerVerb = <PathVerb, int>{
    PathVerb.moveTo: 2,
    PathVerb.lineTo: 2,
    PathVerb.cubicTo: 6,
    PathVerb.close: 0,
  };

  /// Makes the appropriate calls using [verbs] and [points] to replay this path
  /// on [proxy].
  ///
  /// Calls [PathProxy.reset] first if [reset] is true.
  void replay(PathProxy proxy, {bool reset = true}) {
    if (reset) {
      proxy.reset();
    }
    int index = 0;
    for (final PathVerb verb in verbs.toList()) {
      switch (verb) {
        case PathVerb.moveTo:
          proxy.moveTo(points[index++], points[index++]);
          break;
        case PathVerb.lineTo:
          proxy.lineTo(points[index++], points[index++]);
          break;
        case PathVerb._quadTo:
          assert(false);
          break;
        case PathVerb._conicTo:
          assert(false);
          break;
        case PathVerb.cubicTo:
          proxy.cubicTo(
            points[index++],
            points[index++],
            points[index++],
            points[index++],
            points[index++],
            points[index++],
          );
          break;
        case PathVerb.close:
          proxy.close();
          break;
      }
    }
    assert(index == points.length);
  }

  /// The list of path verbs in this path.
  ///
  /// This may not match the verbs supplied by calls to [moveTo], [lineTo],
  /// [cubicTo], and [close] after [applyOp] is invoked.
  ///
  /// This list determines the meaning of the [points] array.
  Iterable<PathVerb> get verbs {
    _updatePathData();
    final int count = _pathData!.ref.verb_count;
    return List<PathVerb>.generate(count, (int index) {
      return PathVerb.values[_pathData!.ref.verbs.elementAt(index).value];
    }, growable: false);
  }

  /// The list of points to use with [verbs].
  ///
  /// Each verb uses a specific number of points, specified by the
  /// [pointsPerVerb] map.
  Float32List get points {
    _updatePathData();
    return _pathData!.ref.points.asTypedList(_pathData!.ref.point_count);
  }

  void _updatePathData() {
    assert(_path != null);
    _pathData ??= _dataFn(_path!);
  }

  void _resetPathData() {
    if (_pathData != null) {
      _destroyDataFn(_pathData!);
    }
    _pathData = null;
  }

  @override
  void moveTo(double x, double y) {
    assert(_path != null);
    _resetPathData();
    _moveToFn(_path!, x, y);
  }

  @override
  void lineTo(double x, double y) {
    assert(_path != null);
    _resetPathData();
    _lineToFn(_path!, x, y);
  }

  @override
  void cubicTo(
    double x1,
    double y1,
    double x2,
    double y2,
    double x3,
    double y3,
  ) {
    assert(_path != null);
    _resetPathData();
    _cubicToFn(_path!, x1, y1, x2, y2, x3, y3);
  }

  @override
  void close() {
    assert(_path != null);
    _resetPathData();
    _closeFn(_path!, true);
  }

  @override
  void reset() {
    assert(_path != null);
    _resetPathData();
    _resetFn(_path!);
  }

  /// Releases native resources.
  ///
  /// After calling dispose, this class must not be used again.
  void dispose() {
    assert(_path != null);
    _resetPathData();
    _destroyFn(_path!);
    _path = null;
  }

  /// Applies the operation described by [op] to this path using [other].
  Path applyOp(Path other, PathOp op) {
    assert(_path != null);
    assert(other._path != null);
    final Path result = Path.from(this);
    _opFn(result._path!, other._path!, op.index);
    return result;
  }
}

// TODO(dnfield): Figure out where to put this.
// https://github.com/flutter/flutter/issues/99563
final ffi.DynamicLibrary _dylib = () {
  if (Platform.isWindows) {
    return ffi.DynamicLibrary.open('path_ops.dll');
  } else if (Platform.isIOS || Platform.isMacOS) {
    return ffi.DynamicLibrary.open('libpath_ops.dylib');
  } else if (Platform.isAndroid || Platform.isLinux) {
    return ffi.DynamicLibrary.open('libpath_ops.so');
  }
  throw UnsupportedError('Unknown platform: ${Platform.operatingSystem}');
}();

class _SkPath extends ffi.Opaque {}

class _PathData extends ffi.Struct {
  external ffi.Pointer<ffi.Uint8> verbs;

  @ffi.Size()
  external int verb_count;

  external ffi.Pointer<ffi.Float> points;

  @ffi.Size()
  external int point_count;
}

typedef _CreatePathType = ffi.Pointer<_SkPath> Function(int);
typedef _create_path_type = ffi.Pointer<_SkPath> Function(ffi.Int);

final _CreatePathType _createPathFn =
    _dylib.lookupFunction<_create_path_type, _CreatePathType>(
  'CreatePath',
);

typedef _MoveToType = void Function(ffi.Pointer<_SkPath>, double, double);
typedef _move_to_type = ffi.Void Function(
    ffi.Pointer<_SkPath>, ffi.Float, ffi.Float);

final _MoveToType _moveToFn = _dylib.lookupFunction<_move_to_type, _MoveToType>(
  'MoveTo',
);

typedef _LineToType = void Function(ffi.Pointer<_SkPath>, double, double);
typedef _line_to_type = ffi.Void Function(
    ffi.Pointer<_SkPath>, ffi.Float, ffi.Float);

final _LineToType _lineToFn = _dylib.lookupFunction<_line_to_type, _LineToType>(
  'LineTo',
);

typedef _CubicToType = void Function(
    ffi.Pointer<_SkPath>, double, double, double, double, double, double);
typedef _cubic_to_type = ffi.Void Function(ffi.Pointer<_SkPath>, ffi.Float,
    ffi.Float, ffi.Float, ffi.Float, ffi.Float, ffi.Float);

final _CubicToType _cubicToFn =
    _dylib.lookupFunction<_cubic_to_type, _CubicToType>('CubicTo');

typedef _CloseType = void Function(ffi.Pointer<_SkPath>, bool);
typedef _close_type = ffi.Void Function(ffi.Pointer<_SkPath>, ffi.Bool);

final _CloseType _closeFn =
    _dylib.lookupFunction<_close_type, _CloseType>('Close');

typedef _ResetType = void Function(ffi.Pointer<_SkPath>);
typedef _reset_type = ffi.Void Function(ffi.Pointer<_SkPath>);

final _ResetType _resetFn =
    _dylib.lookupFunction<_reset_type, _ResetType>('Reset');

typedef _DestroyType = void Function(ffi.Pointer<_SkPath>);
typedef _destroy_type = ffi.Void Function(ffi.Pointer<_SkPath>);

final _DestroyType _destroyFn =
    _dylib.lookupFunction<_destroy_type, _DestroyType>('DestroyPath');

typedef _OpType = void Function(
    ffi.Pointer<_SkPath>, ffi.Pointer<_SkPath>, int);
typedef _op_type = ffi.Void Function(
    ffi.Pointer<_SkPath>, ffi.Pointer<_SkPath>, ffi.Int);

final _OpType _opFn = _dylib.lookupFunction<_op_type, _OpType>('Op');

typedef _PathDataType = ffi.Pointer<_PathData> Function(ffi.Pointer<_SkPath>);
typedef _path_data_type = ffi.Pointer<_PathData> Function(ffi.Pointer<_SkPath>);

final _PathDataType _dataFn =
    _dylib.lookupFunction<_path_data_type, _PathDataType>('Data');

typedef _DestroyDataType = void Function(ffi.Pointer<_PathData>);
typedef _destroy_data_type = ffi.Void Function(ffi.Pointer<_PathData>);

final _DestroyDataType _destroyDataFn =
    _dylib.lookupFunction<_destroy_data_type, _DestroyDataType>('DestroyData');

typedef _GetFillTypeType = int Function(ffi.Pointer<_SkPath>);
typedef _get_fill_type_type = ffi.Int32 Function(ffi.Pointer<_SkPath>);

final _GetFillTypeType _getFillTypeFn =
    _dylib.lookupFunction<_get_fill_type_type, _GetFillTypeType>('GetFillType');
