// 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([this.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.
  final FillType fillType;

  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');
