//! 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::*;

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/appkit/nssoundpboardtype?language=objc)
    #[cfg(feature = "NSPasteboard")]
    pub static NSSoundPboardType: &'static NSPasteboardType;
}

/// [Apple's documentation](https://developer.apple.com/documentation/appkit/nssoundname?language=objc)
pub type NSSoundName = NSString;

/// [Apple's documentation](https://developer.apple.com/documentation/appkit/nssoundplaybackdeviceidentifier?language=objc)
pub type NSSoundPlaybackDeviceIdentifier = NSString;

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/appkit/nssound?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSSound;
);

extern_conformance!(
    unsafe impl NSCoding for NSSound {}
);

extern_conformance!(
    unsafe impl NSCopying for NSSound {}
);

unsafe impl CopyingHelper for NSSound {
    type Result = Self;
}

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

#[cfg(feature = "NSPasteboard")]
extern_conformance!(
    unsafe impl NSPasteboardReading for NSSound {}
);

#[cfg(feature = "NSPasteboard")]
extern_conformance!(
    unsafe impl NSPasteboardWriting for NSSound {}
);

extern_conformance!(
    unsafe impl NSSecureCoding for NSSound {}
);

impl NSSound {
    extern_methods!(
        #[unsafe(method(soundNamed:))]
        #[unsafe(method_family = none)]
        pub fn soundNamed(name: &NSSoundName) -> Option<Retained<NSSound>>;

        #[unsafe(method(initWithContentsOfURL:byReference:))]
        #[unsafe(method_family = init)]
        pub fn initWithContentsOfURL_byReference(
            this: Allocated<Self>,
            url: &NSURL,
            by_ref: bool,
        ) -> Option<Retained<Self>>;

        #[unsafe(method(initWithContentsOfFile:byReference:))]
        #[unsafe(method_family = init)]
        pub fn initWithContentsOfFile_byReference(
            this: Allocated<Self>,
            path: &NSString,
            by_ref: bool,
        ) -> Option<Retained<Self>>;

        #[unsafe(method(initWithData:))]
        #[unsafe(method_family = init)]
        pub fn initWithData(this: Allocated<Self>, data: &NSData) -> Option<Retained<Self>>;

        #[unsafe(method(setName:))]
        #[unsafe(method_family = none)]
        pub fn setName(&self, string: Option<&NSSoundName>) -> bool;

        #[unsafe(method(name))]
        #[unsafe(method_family = none)]
        pub fn name(&self) -> Option<Retained<NSSoundName>>;

        #[cfg(feature = "NSPasteboard")]
        #[unsafe(method(canInitWithPasteboard:))]
        #[unsafe(method_family = none)]
        pub fn canInitWithPasteboard(pasteboard: &NSPasteboard) -> bool;

        #[unsafe(method(soundUnfilteredTypes))]
        #[unsafe(method_family = none)]
        pub fn soundUnfilteredTypes() -> Retained<NSArray<NSString>>;

        #[cfg(feature = "NSPasteboard")]
        #[unsafe(method(initWithPasteboard:))]
        #[unsafe(method_family = init)]
        pub fn initWithPasteboard(
            this: Allocated<Self>,
            pasteboard: &NSPasteboard,
        ) -> Option<Retained<Self>>;

        #[cfg(feature = "NSPasteboard")]
        #[unsafe(method(writeToPasteboard:))]
        #[unsafe(method_family = none)]
        pub fn writeToPasteboard(&self, pasteboard: &NSPasteboard);

        #[unsafe(method(play))]
        #[unsafe(method_family = none)]
        pub fn play(&self) -> bool;

        #[unsafe(method(pause))]
        #[unsafe(method_family = none)]
        pub fn pause(&self) -> bool;

        #[unsafe(method(resume))]
        #[unsafe(method_family = none)]
        pub fn resume(&self) -> bool;

        #[unsafe(method(stop))]
        #[unsafe(method_family = none)]
        pub fn stop(&self) -> bool;

        #[unsafe(method(isPlaying))]
        #[unsafe(method_family = none)]
        pub fn isPlaying(&self) -> bool;

        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub fn delegate(
            &self,
            mtm: MainThreadMarker,
        ) -> Option<Retained<ProtocolObject<dyn NSSoundDelegate>>>;

        /// Setter for [`delegate`][Self::delegate].
        ///
        /// This is a [weak property][objc2::topics::weak_property].
        #[unsafe(method(setDelegate:))]
        #[unsafe(method_family = none)]
        pub fn setDelegate(&self, delegate: Option<&ProtocolObject<dyn NSSoundDelegate>>);

        #[unsafe(method(duration))]
        #[unsafe(method_family = none)]
        pub fn duration(&self) -> NSTimeInterval;

        #[unsafe(method(volume))]
        #[unsafe(method_family = none)]
        pub fn volume(&self) -> c_float;

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

        #[unsafe(method(currentTime))]
        #[unsafe(method_family = none)]
        pub fn currentTime(&self) -> NSTimeInterval;

        /// Setter for [`currentTime`][Self::currentTime].
        #[unsafe(method(setCurrentTime:))]
        #[unsafe(method_family = none)]
        pub fn setCurrentTime(&self, current_time: NSTimeInterval);

        #[unsafe(method(loops))]
        #[unsafe(method_family = none)]
        pub fn loops(&self) -> bool;

        /// Setter for [`loops`][Self::loops].
        #[unsafe(method(setLoops:))]
        #[unsafe(method_family = none)]
        pub fn setLoops(&self, loops: bool);

        #[unsafe(method(playbackDeviceIdentifier))]
        #[unsafe(method_family = none)]
        pub fn playbackDeviceIdentifier(&self)
            -> Option<Retained<NSSoundPlaybackDeviceIdentifier>>;

        /// Setter for [`playbackDeviceIdentifier`][Self::playbackDeviceIdentifier].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setPlaybackDeviceIdentifier:))]
        #[unsafe(method_family = none)]
        pub fn setPlaybackDeviceIdentifier(
            &self,
            playback_device_identifier: Option<&NSSoundPlaybackDeviceIdentifier>,
        );

        /// # Safety
        ///
        /// - `channel_mapping` generic should be of the correct type.
        /// - `channel_mapping` might not allow `None`.
        #[deprecated]
        #[unsafe(method(setChannelMapping:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setChannelMapping(&self, channel_mapping: Option<&NSArray>);

        #[deprecated]
        #[unsafe(method(channelMapping))]
        #[unsafe(method_family = none)]
        pub fn channelMapping(&self) -> Option<Retained<NSArray>>;
    );
}

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

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

impl DefaultRetained for NSSound {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

/// NSDeprecated.
impl NSSound {
    extern_methods!(
        #[deprecated]
        #[unsafe(method(soundUnfilteredFileTypes))]
        #[unsafe(method_family = none)]
        pub fn soundUnfilteredFileTypes() -> Option<Retained<NSArray>>;

        #[deprecated]
        #[unsafe(method(soundUnfilteredPasteboardTypes))]
        #[unsafe(method_family = none)]
        pub fn soundUnfilteredPasteboardTypes() -> Option<Retained<NSArray>>;
    );
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/appkit/nssounddelegate?language=objc)
    pub unsafe trait NSSoundDelegate: NSObjectProtocol + MainThreadOnly {
        #[optional]
        #[unsafe(method(sound:didFinishPlaying:))]
        #[unsafe(method_family = none)]
        fn sound_didFinishPlaying(&self, sound: &NSSound, flag: bool);
    }
);

mod private_NSBundleSoundExtensions {
    pub trait Sealed {}
}

/// Category on [`NSBundle`].
pub unsafe trait NSBundleSoundExtensions:
    ClassType + Sized + private_NSBundleSoundExtensions::Sealed
{
    extern_methods!(
        #[unsafe(method(pathForSoundResource:))]
        #[unsafe(method_family = none)]
        fn pathForSoundResource(&self, name: &NSSoundName) -> Option<Retained<NSString>>;
    );
}

impl private_NSBundleSoundExtensions::Sealed for NSBundle {}
unsafe impl NSBundleSoundExtensions for NSBundle {}
