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

/// Describes the type of a render event.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/aurendereventtype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct AURenderEventType(pub u8);
impl AURenderEventType {
    #[doc(alias = "AURenderEventParameter")]
    pub const Parameter: Self = Self(1);
    #[doc(alias = "AURenderEventParameterRamp")]
    pub const ParameterRamp: Self = Self(2);
    #[doc(alias = "AURenderEventMIDI")]
    pub const MIDI: Self = Self(8);
    #[doc(alias = "AURenderEventMIDISysEx")]
    pub const MIDISysEx: Self = Self(9);
    #[doc(alias = "AURenderEventMIDIEventList")]
    pub const MIDIEventList: Self = Self(10);
}

unsafe impl Encode for AURenderEventType {
    const ENCODING: Encoding = u8::ENCODING;
}

unsafe impl RefEncode for AURenderEventType {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// AUAudioUnitImplementation.
/// Aspects of AUAudioUnit of interest only to subclassers.
#[cfg(feature = "AUAudioUnit")]
impl AUAudioUnit {
    extern_methods!(
        #[cfg(feature = "AudioComponent")]
        /// Register an audio unit component implemented as an AUAudioUnit subclass.
        ///
        /// This method dynamically registers the supplied AUAudioUnit subclass with the Audio Component
        /// system, in the context of the current process (only). After registering the subclass, it can
        /// be instantiated via AudioComponentInstanceNew,
        /// -[AUAudioUnit initWithComponentDescription:options:error:], and via any other API's which
        /// instantiate audio units via their component descriptions (e.g.
        /// <AudioToolbox
        /// /AUGraph.h>, or
        /// <AVFoundation
        /// /AVAudioUnitEffect.h>).
        #[unsafe(method(registerSubclass:asComponentDescription:name:version:))]
        #[unsafe(method_family = none)]
        pub unsafe fn registerSubclass_asComponentDescription_name_version(
            cls: &AnyClass,
            component_description: AudioComponentDescription,
            name: &NSString,
            version: u32,
        );

        /// Hint to control the size of the allocated buffer for outgoing MIDI events.
        ///
        /// This property allows the plug-in to provide a hint to the framework regarding the size of
        /// its outgoing MIDI data buffer.
        ///
        /// If the plug-in produces more MIDI output data than the default size of the allocated buffer,
        /// then the plug-in can provide this property to increase the size of this buffer.
        ///
        /// The value represents the number of 3-byte Legacy MIDI messages that fit into the buffer or
        /// a single MIDIEventList containing 1 MIDIEventPacket of 2 words when using MIDI 2.0 (MIDIEventList based API's).
        ///
        /// This property is set to the default value by the framework.
        ///
        /// In case of kAudioUnitErr_MIDIOutputBufferFull errors caused by producing too much MIDI
        /// output in one render call, set this property to increase the buffer.
        ///
        /// This only provides a recommendation to the framework.
        ///
        /// Bridged to kAudioUnitProperty_MIDIOutputBufferSizeHint.
        #[unsafe(method(MIDIOutputBufferSizeHint))]
        #[unsafe(method_family = none)]
        pub unsafe fn MIDIOutputBufferSizeHint(&self) -> NSInteger;

        /// Setter for [`MIDIOutputBufferSizeHint`][Self::MIDIOutputBufferSizeHint].
        #[unsafe(method(setMIDIOutputBufferSizeHint:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMIDIOutputBufferSizeHint(&self, midi_output_buffer_size_hint: NSInteger);

        /// Parameter `flag`: In the base class implementation of allocateRenderResourcesAndReturnError:, the property renderResourcesAllocated is set to YES.
        /// If allocateRenderResourcesAndReturnError: should fail in a subclass, subclassers must use this method to set renderResourcesAllocated to NO.
        #[unsafe(method(setRenderResourcesAllocated:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setRenderResourcesAllocated(&self, flag: bool);
    );
}

/// AUAudioUnitImplementation.
/// Aspects of AUAudioUnitBus of interest only to the implementation of v3 AUs.
#[cfg(feature = "AUAudioUnit")]
impl AUAudioUnitBus {
    extern_methods!(
        /// An array of numbers giving the supported numbers of channels for this bus.
        ///
        /// If supportedChannelCounts is nil, then any number less than or equal to maximumChannelCount
        /// is supported. If setting supportedChannelCounts makes the current format unsupported, then
        /// format will be set to nil. The default value is nil.
        #[unsafe(method(supportedChannelCounts))]
        #[unsafe(method_family = none)]
        pub unsafe fn supportedChannelCounts(&self) -> Option<Retained<NSArray<NSNumber>>>;

        /// Setter for [`supportedChannelCounts`][Self::supportedChannelCounts].
        #[unsafe(method(setSupportedChannelCounts:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setSupportedChannelCounts(
            &self,
            supported_channel_counts: Option<&NSArray<NSNumber>>,
        );

        /// The maximum numbers of channels supported for this bus.
        ///
        /// If supportedChannelCounts is set, then this value is derived from supportedChannelCounts. If
        /// setting maximumChannelCount makes the current format unsupported, then format will be set to
        /// nil. The default value is UINT_MAX.
        #[unsafe(method(maximumChannelCount))]
        #[unsafe(method_family = none)]
        pub unsafe fn maximumChannelCount(&self) -> AUAudioChannelCount;

        /// Setter for [`maximumChannelCount`][Self::maximumChannelCount].
        #[unsafe(method(setMaximumChannelCount:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMaximumChannelCount(&self, maximum_channel_count: AUAudioChannelCount);
    );
}

/// AUAudioUnitBusImplementation.
/// Aspects of AUAudioUnitBusArray of interest only to subclassers.
#[cfg(feature = "AUAudioUnit")]
impl AUAudioUnitBusArray {
    extern_methods!(
        /// Sets the bus array to be a copy of the supplied array. The base class issues KVO notifications.
        #[unsafe(method(replaceBusses:))]
        #[unsafe(method_family = none)]
        pub unsafe fn replaceBusses(&self, bus_array: &NSArray<AUAudioUnitBus>);
    );
}

/// Factory.
/// Factory methods for building parameters, parameter groups, and parameter trees.
///
///
/// Note: In non-ARC code, "create" methods return unretained objects (unlike "create"
/// C functions); the caller should generally retain them.
#[cfg(feature = "AUParameters")]
impl AUParameterTree {
    extern_methods!(
        #[cfg(feature = "AudioUnitProperties")]
        /// Create an AUParameter.
        /// See AUParameter's properties for descriptions of the arguments.
        #[unsafe(method(createParameterWithIdentifier:name:address:min:max:unit:unitName:flags:valueStrings:dependentParameters:))]
        #[unsafe(method_family = none)]
        pub unsafe fn createParameterWithIdentifier_name_address_min_max_unit_unitName_flags_valueStrings_dependentParameters(
            identifier: &NSString,
            name: &NSString,
            address: AUParameterAddress,
            min: AUValue,
            max: AUValue,
            unit: AudioUnitParameterUnit,
            unit_name: Option<&NSString>,
            flags: AudioUnitParameterOptions,
            value_strings: Option<&NSArray<NSString>>,
            dependent_parameters: Option<&NSArray<NSNumber>>,
        ) -> Retained<AUParameter>;

        /// Create an AUParameterGroup.
        ///
        /// Parameter `identifier`: An identifier for the group (non-localized, persistent).
        ///
        /// Parameter `name`: The group's human-readable name (localized).
        ///
        /// Parameter `children`: The group's child nodes.
        #[unsafe(method(createGroupWithIdentifier:name:children:))]
        #[unsafe(method_family = none)]
        pub unsafe fn createGroupWithIdentifier_name_children(
            identifier: &NSString,
            name: &NSString,
            children: &NSArray<AUParameterNode>,
        ) -> Retained<AUParameterGroup>;

        /// Create a template group which may be used as a prototype for further group instances.
        ///
        ///
        /// Template groups provide a way to construct multiple instances of identical parameter
        /// groups, sharing certain immutable state between the instances.
        ///
        /// Template groups may not appear in trees except at the root.
        #[unsafe(method(createGroupTemplate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn createGroupTemplate(
            children: &NSArray<AUParameterNode>,
        ) -> Retained<AUParameterGroup>;

        /// Initialize a group as a copied instance of a template group.
        ///
        /// Parameter `templateGroup`: A group to be used as a template and largely copied.
        ///
        /// Parameter `identifier`: An identifier for the new group (non-localized, persistent).
        ///
        /// Parameter `name`: The new group's human-readable name (localized).
        ///
        /// Parameter `addressOffset`: The new group's parameters' addresses will be offset from those in
        /// the template by this value.
        #[unsafe(method(createGroupFromTemplate:identifier:name:addressOffset:))]
        #[unsafe(method_family = none)]
        pub unsafe fn createGroupFromTemplate_identifier_name_addressOffset(
            template_group: &AUParameterGroup,
            identifier: &NSString,
            name: &NSString,
            address_offset: AUParameterAddress,
        ) -> Retained<AUParameterGroup>;

        /// Create an AUParameterTree.
        ///
        /// Parameter `children`: The tree's top-level child nodes.
        #[unsafe(method(createTreeWithChildren:))]
        #[unsafe(method_family = none)]
        pub unsafe fn createTreeWithChildren(
            children: &NSArray<AUParameterNode>,
        ) -> Retained<AUParameterTree>;
    );
}

/// A block called to notify the AUAudioUnit implementation of changes to AUParameter values.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auimplementorvalueobserver?language=objc)
#[cfg(all(feature = "AUParameters", feature = "block2"))]
pub type AUImplementorValueObserver = *mut block2::DynBlock<dyn Fn(NonNull<AUParameter>, AUValue)>;

/// A block called to fetch an AUParameter's current value from the AUAudioUnit implementation.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auimplementorvalueprovider?language=objc)
#[cfg(all(feature = "AUParameters", feature = "block2"))]
pub type AUImplementorValueProvider =
    *mut block2::DynBlock<dyn Fn(NonNull<AUParameter>) -> AUValue>;

/// A block called to convert an AUParameter's value to a string.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auimplementorstringfromvaluecallback?language=objc)
#[cfg(all(feature = "AUParameters", feature = "block2"))]
pub type AUImplementorStringFromValueCallback =
    *mut block2::DynBlock<dyn Fn(NonNull<AUParameter>, *const AUValue) -> NonNull<NSString>>;

/// A block called to convert a string to an AUParameter's value.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auimplementorvaluefromstringcallback?language=objc)
#[cfg(all(feature = "AUParameters", feature = "block2"))]
pub type AUImplementorValueFromStringCallback =
    *mut block2::DynBlock<dyn Fn(NonNull<AUParameter>, NonNull<NSString>) -> AUValue>;

/// A block called to return a group or parameter's localized display name, abbreviated to the requested length.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auimplementordisplaynamewithlengthcallback?language=objc)
#[cfg(all(feature = "AUParameters", feature = "block2"))]
pub type AUImplementorDisplayNameWithLengthCallback =
    *mut block2::DynBlock<dyn Fn(NonNull<AUParameterNode>, NSInteger) -> NonNull<NSString>>;

/// AUParameterNodeImplementation.
/// Aspects of AUParameterNode of interest only to AUAudioUnit subclassers.
#[cfg(feature = "AUParameters")]
impl AUParameterNode {
    extern_methods!(
        #[cfg(feature = "block2")]
        /// Called when a parameter changes value.
        ///
        /// This block, used only in an audio unit implementation, receives all externally-generated
        /// changes to parameter values. It should store the new value in its audio signal processing
        /// state (assuming that that state is separate from the AUParameter object).
        #[unsafe(method(implementorValueObserver))]
        #[unsafe(method_family = none)]
        pub unsafe fn implementorValueObserver(&self) -> AUImplementorValueObserver;

        #[cfg(feature = "block2")]
        /// Setter for [`implementorValueObserver`][Self::implementorValueObserver].
        #[unsafe(method(setImplementorValueObserver:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setImplementorValueObserver(
            &self,
            implementor_value_observer: AUImplementorValueObserver,
        );

        #[cfg(feature = "block2")]
        /// Called when a value of a parameter in the tree is known to have a stale value
        /// needing to be refreshed.
        ///
        /// The audio unit should return the current value for this parameter; the AUParameterNode will
        /// store the value.
        #[unsafe(method(implementorValueProvider))]
        #[unsafe(method_family = none)]
        pub unsafe fn implementorValueProvider(&self) -> AUImplementorValueProvider;

        #[cfg(feature = "block2")]
        /// Setter for [`implementorValueProvider`][Self::implementorValueProvider].
        #[unsafe(method(setImplementorValueProvider:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setImplementorValueProvider(
            &self,
            implementor_value_provider: AUImplementorValueProvider,
        );

        #[cfg(feature = "block2")]
        /// Called to provide string representations of parameter values.
        /// If value is nil, the callback uses the current value of the parameter.
        #[unsafe(method(implementorStringFromValueCallback))]
        #[unsafe(method_family = none)]
        pub unsafe fn implementorStringFromValueCallback(
            &self,
        ) -> AUImplementorStringFromValueCallback;

        #[cfg(feature = "block2")]
        /// Setter for [`implementorStringFromValueCallback`][Self::implementorStringFromValueCallback].
        #[unsafe(method(setImplementorStringFromValueCallback:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setImplementorStringFromValueCallback(
            &self,
            implementor_string_from_value_callback: AUImplementorStringFromValueCallback,
        );

        #[cfg(feature = "block2")]
        /// Called to convert string to numeric representations of parameter values.
        #[unsafe(method(implementorValueFromStringCallback))]
        #[unsafe(method_family = none)]
        pub unsafe fn implementorValueFromStringCallback(
            &self,
        ) -> AUImplementorValueFromStringCallback;

        #[cfg(feature = "block2")]
        /// Setter for [`implementorValueFromStringCallback`][Self::implementorValueFromStringCallback].
        #[unsafe(method(setImplementorValueFromStringCallback:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setImplementorValueFromStringCallback(
            &self,
            implementor_value_from_string_callback: AUImplementorValueFromStringCallback,
        );

        #[cfg(feature = "block2")]
        /// Called to obtain an abbreviated version of a parameter or group name.
        #[unsafe(method(implementorDisplayNameWithLengthCallback))]
        #[unsafe(method_family = none)]
        pub unsafe fn implementorDisplayNameWithLengthCallback(
            &self,
        ) -> AUImplementorDisplayNameWithLengthCallback;

        #[cfg(feature = "block2")]
        /// Setter for [`implementorDisplayNameWithLengthCallback`][Self::implementorDisplayNameWithLengthCallback].
        #[unsafe(method(setImplementorDisplayNameWithLengthCallback:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setImplementorDisplayNameWithLengthCallback(
            &self,
            implementor_display_name_with_length_callback: AUImplementorDisplayNameWithLengthCallback,
        );
    );
}

extern_class!(
    /// Wraps a v2 audio unit in an AUAudioUnit subclass.
    ///
    /// Implementors of version 3 audio units may derive their implementations from
    /// AUAudioUnitV2Bridge. It expects the component description with which it is initialized to
    /// refer to a registered component with a v2 implementation using an
    /// AudioComponentFactoryFunction. The bridge will instantiate the v2 audio unit via the factory
    /// function and communicate it with it using the v2 AudioUnit API's (AudioUnitSetProperty,
    /// etc.)
    ///
    /// Hosts should not access this class; it will be instantiated when needed when creating an
    /// AUAudioUnit.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auaudiounitv2bridge?language=objc)
    #[unsafe(super(AUAudioUnit, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "AUAudioUnit")]
    pub struct AUAudioUnitV2Bridge;
);

#[cfg(feature = "AUAudioUnit")]
extern_conformance!(
    unsafe impl NSObjectProtocol for AUAudioUnitV2Bridge {}
);

#[cfg(feature = "AUAudioUnit")]
impl AUAudioUnitV2Bridge {
    extern_methods!(
        #[cfg(all(feature = "AUComponent", feature = "AudioComponent"))]
        /// The underlying v2 AudioUnit
        ///
        /// We generally discourage interacting with the underlying v2 AudioUnit directly and
        /// recommend using the v3 equivalent methods and properties from AUAudioUnitV2Bridge.
        ///
        /// In some rare cases it may be desirable to interact with the v2 AudioUnit.
        /// For example, a v2 plugin may define custom properties that are not bridged to v3.
        /// Implementors can sublcass AUAudioUnitV2Bridge and call the v2 API methods
        /// AudioUnitGetProperty / AudioUnitSetProperty with the v2 AudioUnit.
        #[unsafe(method(audioUnit))]
        #[unsafe(method_family = none)]
        pub unsafe fn audioUnit(&self) -> AudioUnit;
    );
}

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

        #[cfg(feature = "AudioComponent")]
        /// Designated initializer.
        ///
        /// Parameter `componentDescription`: A single AUAudioUnit subclass may implement multiple audio units, for example, an effect
        /// that can also function as a generator, or a cluster of related effects. The component
        /// description specifies the component which was instantiated.
        ///
        /// Parameter `options`: Options for loading the unit in-process or out-of-process.
        ///
        /// Parameter `outError`: Returned in the event of failure.
        #[unsafe(method(initWithComponentDescription:options:error:_))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithComponentDescription_options_error(
            this: Allocated<Self>,
            component_description: AudioComponentDescription,
            options: AudioComponentInstantiationOptions,
        ) -> Result<Retained<Self>, Retained<NSError>>;

        #[cfg(feature = "AudioComponent")]
        /// Convenience initializer (omits options).
        #[unsafe(method(initWithComponentDescription:error:_))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithComponentDescription_error(
            this: Allocated<Self>,
            component_description: AudioComponentDescription,
        ) -> Result<Retained<Self>, Retained<NSError>>;
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(feature = "AUAudioUnit")]
impl AUAudioUnitV2Bridge {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

extern_protocol!(
    /// Protocol to which principal classes of v3 audio units (extensions) must conform.
    ///
    /// The principal class of a non-UI v3 audio unit extension will generally derive from NSObject
    /// and implement this protocol.
    ///
    /// The principal class of a UI v3 audio unit extension must derive from AUViewController and
    /// implement this protocol.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/audiotoolbox/auaudiounitfactory?language=objc)
    pub unsafe trait AUAudioUnitFactory: NSExtensionRequestHandling {
        #[cfg(all(feature = "AUAudioUnit", feature = "AudioComponent"))]
        /// Create an instance of an extension's AUAudioUnit.
        ///
        /// This method should create and return an instance of its audio unit.
        ///
        /// This method will be called only once per instance of the factory.
        ///
        /// Note that in non-ARC code, "create" methods return unretained objects (unlike "create"
        /// C functions); the implementor should return an object with reference count 1 but
        /// autoreleased.
        #[unsafe(method(createAudioUnitWithComponentDescription:error:_))]
        #[unsafe(method_family = none)]
        unsafe fn createAudioUnitWithComponentDescription_error(
            &self,
            desc: AudioComponentDescription,
        ) -> Result<Retained<AUAudioUnit>, Retained<NSError>>;
    }
);
