//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
use objc2_foundation::*;

use crate::*;

/// Generic callback block.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avmidiplayercompletionhandler?language=objc)
#[cfg(feature = "block2")]
pub type AVMIDIPlayerCompletionHandler = *mut block2::DynBlock<dyn Fn()>;

extern_class!(
    /// A player for music file formats (MIDI, iMelody).
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/avfaudio/avmidiplayer?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct AVMIDIPlayer;
);

extern_conformance!(
    unsafe impl NSObjectProtocol for AVMIDIPlayer {}
);

impl AVMIDIPlayer {
    extern_methods!(
        /// Create a player with the contents of the file specified by the URL.
        ///
        /// 'bankURL' should contain the path to a SoundFont2 or DLS bank to be used
        /// by the MIDI synthesizer.  For OSX it can be set to nil for the default,
        /// but for iOS it must always refer to a valid bank file.
        #[unsafe(method(initWithContentsOfURL:soundBankURL:error:_))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithContentsOfURL_soundBankURL_error(
            this: Allocated<Self>,
            in_url: &NSURL,
            bank_url: Option<&NSURL>,
        ) -> Result<Retained<Self>, Retained<NSError>>;

        /// Create a player with the contents of the data object
        ///
        /// 'bankURL' should contain the path to a SoundFont2 or DLS bank to be used
        /// by the MIDI synthesizer.  For OSX it can be set to nil for the default,
        /// but for iOS it must always refer to a valid bank file.
        #[unsafe(method(initWithData:soundBankURL:error:_))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithData_soundBankURL_error(
            this: Allocated<Self>,
            data: &NSData,
            bank_url: Option<&NSURL>,
        ) -> Result<Retained<Self>, Retained<NSError>>;

        /// Get ready to play the sequence by prerolling all events
        ///
        /// Happens automatically on play if it has not already been called, but may produce a delay in startup.
        #[unsafe(method(prepareToPlay))]
        #[unsafe(method_family = none)]
        pub unsafe fn prepareToPlay(&self);

        #[cfg(feature = "block2")]
        /// Play the sequence.
        ///
        /// # Safety
        ///
        /// `completion_handler` must be a valid pointer or null.
        #[unsafe(method(play:))]
        #[unsafe(method_family = none)]
        pub unsafe fn play(&self, completion_handler: AVMIDIPlayerCompletionHandler);

        /// Stop playing the sequence.
        #[unsafe(method(stop))]
        #[unsafe(method_family = none)]
        pub unsafe fn stop(&self);

        /// The length of the currently loaded file in seconds.
        #[unsafe(method(duration))]
        #[unsafe(method_family = none)]
        pub unsafe fn duration(&self) -> NSTimeInterval;

        /// Indicates whether or not the player is playing
        #[unsafe(method(isPlaying))]
        #[unsafe(method_family = none)]
        pub unsafe fn isPlaying(&self) -> bool;

        /// The playback rate of the player
        ///
        /// 1.0 is normal playback rate.  Rate must be > 0.0.
        #[unsafe(method(rate))]
        #[unsafe(method_family = none)]
        pub unsafe fn rate(&self) -> c_float;

        /// Setter for [`rate`][Self::rate].
        #[unsafe(method(setRate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setRate(&self, rate: c_float);

        /// The current playback position in seconds
        ///
        /// Setting this positions the player to the specified time.  No range checking on the time value is done.
        /// This can be set while the player is playing, in which case playback will resume at the new time.
        #[unsafe(method(currentPosition))]
        #[unsafe(method_family = none)]
        pub unsafe fn currentPosition(&self) -> NSTimeInterval;

        /// Setter for [`currentPosition`][Self::currentPosition].
        #[unsafe(method(setCurrentPosition:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setCurrentPosition(&self, current_position: NSTimeInterval);
    );
}

/// Methods declared on superclass `NSObject`.
impl AVMIDIPlayer {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}
