// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// Autogenerated by jnigen. DO NOT EDIT!

// ignore_for_file: annotate_overrides
// ignore_for_file: camel_case_extensions
// ignore_for_file: camel_case_types
// ignore_for_file: constant_identifier_names
// ignore_for_file: file_names
// ignore_for_file: no_leading_underscores_for_local_identifiers
// ignore_for_file: non_constant_identifier_names
// ignore_for_file: overridden_fields
// ignore_for_file: unnecessary_cast
// ignore_for_file: unused_element
// ignore_for_file: unused_field
// ignore_for_file: unused_import
// ignore_for_file: unused_local_variable
// ignore_for_file: unused_shown_name

import "dart:isolate" show ReceivePort;
import "dart:ffi" as ffi;
import "package:jni/internal_helpers_for_jnigen.dart";
import "package:jni/jni.dart" as jni;

// Auto-generated initialization code.

final ffi.Pointer<T> Function<T extends ffi.NativeType>(String sym) jniLookup =
    ProtectedJniExtensions.initGeneratedLibrary("notification_plugin");

/// from: com.example.notification_plugin.Notifications
class Notifications extends jni.JObject {
  @override
  late final jni.JObjType<Notifications> $type = type;

  Notifications.fromRef(
    jni.JObjectPtr ref,
  ) : super.fromRef(ref);

  /// The type which includes information such as the signature of this class.
  static const type = $NotificationsType();
  static final _new0 = jniLookup<ffi.NativeFunction<jni.JniResult Function()>>(
          "Notifications__new0")
      .asFunction<jni.JniResult Function()>();

  /// from: public void <init>()
  /// The returned object must be released after use, by calling the [release] method.
  factory Notifications() {
    return Notifications.fromRef(_new0().object);
  }

  static final _showNotification = jniLookup<
          ffi.NativeFunction<
              jni.JniResult Function(
                  ffi.Pointer<ffi.Void>,
                  ffi.Int32,
                  ffi.Pointer<ffi.Void>,
                  ffi.Pointer<ffi.Void>)>>("Notifications__showNotification")
      .asFunction<
          jni.JniResult Function(ffi.Pointer<ffi.Void>, int,
              ffi.Pointer<ffi.Void>, ffi.Pointer<ffi.Void>)>();

  /// from: static public void showNotification(android.content.Context context, int notificationID, java.lang.String title, java.lang.String text)
  static void showNotification(
    jni.JObject context,
    int notificationID,
    jni.JString title,
    jni.JString text,
  ) {
    return _showNotification(
            context.reference, notificationID, title.reference, text.reference)
        .check();
  }
}

class $NotificationsType extends jni.JObjType<Notifications> {
  const $NotificationsType();

  @override
  String get signature => r"Lcom/example/notification_plugin/Notifications;";

  @override
  Notifications fromRef(jni.JObjectPtr ref) => Notifications.fromRef(ref);

  @override
  jni.JObjType get superType => const jni.JObjectType();

  @override
  final superCount = 1;

  @override
  int get hashCode => ($NotificationsType).hashCode;

  @override
  bool operator ==(Object other) {
    return other.runtimeType == ($NotificationsType) &&
        other is $NotificationsType;
  }
}
