//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::cell::UnsafeCell;
use core::ffi::*;
use core::marker::{PhantomData, PhantomPinned};
use core::ptr::NonNull;
#[cfg(feature = "objc2")]
use objc2::__framework_prelude::*;

use crate::*;

impl CFStringTokenizer {
    /// Guesses the language of a string and returns the BCP 47 string of the
    /// language.
    ///
    /// Parameter `string`: The string whose language is to be guessed.
    ///
    /// Parameter `range`: The range of characters in string whose language to be
    /// guessed. The specified range must not exceed the bounds of the string.
    ///
    /// Returns: A language represented in BCP 47 string. NULL is returned either if
    /// string is NULL, the location of range is negative, the length of range
    /// is 0, or the language of the string cannot be guessed.
    ///
    /// The result is not guaranteed to be accurate. Typically 200-400
    /// characters are required to reliably guess the language of a string.
    #[doc(alias = "CFStringTokenizerCopyBestStringLanguage")]
    #[inline]
    pub fn best_string_language(string: &CFString, range: CFRange) -> Option<CFRetained<CFString>> {
        extern "C-unwind" {
            fn CFStringTokenizerCopyBestStringLanguage(
                string: &CFString,
                range: CFRange,
            ) -> Option<NonNull<CFString>>;
        }
        let ret = unsafe { CFStringTokenizerCopyBestStringLanguage(string, range) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }
}

/// [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfstringtokenizer?language=objc)
#[doc(alias = "CFStringTokenizerRef")]
#[repr(C)]
pub struct CFStringTokenizer {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

cf_type!(
    unsafe impl CFStringTokenizer {}
);
#[cfg(feature = "objc2")]
cf_objc2_type!(
    unsafe impl RefEncode<"__CFStringTokenizer"> for CFStringTokenizer {}
);

/// Tokenization Unit
/// Use one of tokenization unit options with CFStringTokenizerCreate to
/// specify how the string should be tokenized.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfstringtokenizerunitword?language=objc)
pub const kCFStringTokenizerUnitWord: CFOptionFlags = 0;
/// Tokenization Unit
/// Use one of tokenization unit options with CFStringTokenizerCreate to
/// specify how the string should be tokenized.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfstringtokenizerunitsentence?language=objc)
pub const kCFStringTokenizerUnitSentence: CFOptionFlags = 1;
/// Tokenization Unit
/// Use one of tokenization unit options with CFStringTokenizerCreate to
/// specify how the string should be tokenized.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfstringtokenizerunitparagraph?language=objc)
pub const kCFStringTokenizerUnitParagraph: CFOptionFlags = 2;
/// Tokenization Unit
/// Use one of tokenization unit options with CFStringTokenizerCreate to
/// specify how the string should be tokenized.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfstringtokenizerunitlinebreak?language=objc)
pub const kCFStringTokenizerUnitLineBreak: CFOptionFlags = 3;
/// Tokenization Unit
/// Use one of tokenization unit options with CFStringTokenizerCreate to
/// specify how the string should be tokenized.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfstringtokenizerunitwordboundary?language=objc)
pub const kCFStringTokenizerUnitWordBoundary: CFOptionFlags = 4;
/// Attribute Specifier
/// Use attribute specifier to tell tokenizer to prepare the specified attribute
/// when it tokenizes the given string. The attribute value can be retrieved by
/// calling CFStringTokenizerCopyCurrentTokenAttribute with one of the attribute
/// option.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfstringtokenizerattributelatintranscription?language=objc)
pub const kCFStringTokenizerAttributeLatinTranscription: CFOptionFlags = 1 << 16;
/// Attribute Specifier
/// Use attribute specifier to tell tokenizer to prepare the specified attribute
/// when it tokenizes the given string. The attribute value can be retrieved by
/// calling CFStringTokenizerCopyCurrentTokenAttribute with one of the attribute
/// option.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corefoundation/kcfstringtokenizerattributelanguage?language=objc)
pub const kCFStringTokenizerAttributeLanguage: CFOptionFlags = 1 << 17;

/// Token type
/// CFStringTokenizerGoToTokenAtIndex / CFStringTokenizerAdvanceToNextToken returns
/// the type of current token.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corefoundation/cfstringtokenizertokentype?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CFStringTokenizerTokenType(pub CFOptionFlags);
bitflags::bitflags! {
    impl CFStringTokenizerTokenType: CFOptionFlags {
        #[doc(alias = "kCFStringTokenizerTokenNone")]
        const None = 0;
        #[doc(alias = "kCFStringTokenizerTokenNormal")]
        const Normal = 1<<0;
/// Compound token which may contain subtokens but with no derived subtokens.
/// Its subtokens can be obtained by calling CFStringTokenizerGetCurrentSubTokens.
        #[doc(alias = "kCFStringTokenizerTokenHasSubTokensMask")]
        const HasSubTokensMask = 1<<1;
/// Compound token which may contain derived subtokens.
/// Its subtokens and derived subtokens can be obtained by calling
/// CFStringTokenizerGetCurrentSubTokens.
        #[doc(alias = "kCFStringTokenizerTokenHasDerivedSubTokensMask")]
        const HasDerivedSubTokensMask = 1<<2;
/// Compound token which may contain derived subtokens.
/// Its subtokens and derived subtokens can be obtained by calling
/// CFStringTokenizerGetCurrentSubTokens.
        #[doc(alias = "kCFStringTokenizerTokenHasHasNumbersMask")]
        const HasHasNumbersMask = 1<<3;
/// Compound token which may contain derived subtokens.
/// Its subtokens and derived subtokens can be obtained by calling
/// CFStringTokenizerGetCurrentSubTokens.
        #[doc(alias = "kCFStringTokenizerTokenHasNonLettersMask")]
        const HasNonLettersMask = 1<<4;
/// Compound token which may contain derived subtokens.
/// Its subtokens and derived subtokens can be obtained by calling
/// CFStringTokenizerGetCurrentSubTokens.
        #[doc(alias = "kCFStringTokenizerTokenIsCJWordMask")]
        const IsCJWordMask = 1<<5;
    }
}

#[cfg(feature = "objc2")]
unsafe impl Encode for CFStringTokenizerTokenType {
    const ENCODING: Encoding = CFOptionFlags::ENCODING;
}

#[cfg(feature = "objc2")]
unsafe impl RefEncode for CFStringTokenizerTokenType {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

unsafe impl ConcreteType for CFStringTokenizer {
    /// Get the type identifier.
    ///
    /// Returns: the type identifier of all CFStringTokenizer instances.
    #[doc(alias = "CFStringTokenizerGetTypeID")]
    #[inline]
    fn type_id() -> CFTypeID {
        extern "C-unwind" {
            fn CFStringTokenizerGetTypeID() -> CFTypeID;
        }
        unsafe { CFStringTokenizerGetTypeID() }
    }
}

impl CFStringTokenizer {
    /// Creates a tokenizer instance.
    ///
    /// Parameter `alloc`: The CFAllocator which should be used to allocate memory for the
    /// tokenizer and its storage for values. This parameter may be NULL in which
    /// case the current default CFAllocator is used.
    ///
    /// Parameter `string`: The string to tokenize.
    ///
    /// Parameter `range`: The range of characters within the string to be tokenized. The
    /// specified range must not exceed the length of the string.
    ///
    /// Parameter `options`: Use one of the Tokenization Unit options to specify how the
    /// string should be tokenized. Optionally specify one or more attribute
    /// specifiers to tell the tokenizer to prepare specified attributes when it
    /// tokenizes the string.
    ///
    /// Parameter `locale`: The locale to specify language or region specific behavior. Pass
    /// NULL if you want tokenizer to identify the locale automatically.
    ///
    /// Returns: A reference to the new CFStringTokenizer.
    ///
    /// # Safety
    ///
    /// - `alloc` might not allow `None`.
    /// - `string` might not allow `None`.
    /// - `locale` might not allow `None`.
    #[doc(alias = "CFStringTokenizerCreate")]
    #[cfg(feature = "CFLocale")]
    #[inline]
    pub unsafe fn new(
        alloc: Option<&CFAllocator>,
        string: Option<&CFString>,
        range: CFRange,
        options: CFOptionFlags,
        locale: Option<&CFLocale>,
    ) -> Option<CFRetained<CFStringTokenizer>> {
        extern "C-unwind" {
            fn CFStringTokenizerCreate(
                alloc: Option<&CFAllocator>,
                string: Option<&CFString>,
                range: CFRange,
                options: CFOptionFlags,
                locale: Option<&CFLocale>,
            ) -> Option<NonNull<CFStringTokenizer>>;
        }
        let ret = unsafe { CFStringTokenizerCreate(alloc, string, range, options, locale) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }

    /// Set the string to tokenize.
    ///
    /// Parameter `tokenizer`: The reference to CFStringTokenizer returned by
    /// CFStringTokenizerCreate.
    ///
    /// Parameter `string`: The string to tokenize.
    ///
    /// Parameter `range`: The range of characters within the string to be tokenized. The
    /// specified range must not exceed the length of the string.
    ///
    /// # Safety
    ///
    /// `string` might not allow `None`.
    #[doc(alias = "CFStringTokenizerSetString")]
    #[inline]
    pub unsafe fn set_string(&self, string: Option<&CFString>, range: CFRange) {
        extern "C-unwind" {
            fn CFStringTokenizerSetString(
                tokenizer: &CFStringTokenizer,
                string: Option<&CFString>,
                range: CFRange,
            );
        }
        unsafe { CFStringTokenizerSetString(self, string, range) }
    }

    /// Random access to a token. Find a token that includes the character specified
    /// by character index, and set it as the current token.
    ///
    /// Parameter `tokenizer`: The reference to CFStringTokenizer returned by
    /// CFStringTokenizerCreate.
    ///
    /// Parameter `index`: The index of the Unicode character in the CFString.
    ///
    /// Returns: Type of the token if succeeded in finding a token and setting it as
    /// current token. kCFStringTokenizerTokenNone if failed in finding a token.
    ///
    /// The range and attribute of the token can be obtained by calling
    /// CFStringTokenizerGetCurrentTokenRange and CFStringTokenizerCopyCurrentTokenAttribute.
    /// If the token is a compound (with type kCFStringTokenizerTokenHasSubTokensMask or
    /// kCFStringTokenizerTokenHasDerivedSubTokensMask), its subtokens and
    /// (or) derived subtokens can be obtained by calling CFStringTokenizerGetCurrentSubTokens.
    #[doc(alias = "CFStringTokenizerGoToTokenAtIndex")]
    #[inline]
    pub fn go_to_token_at_index(&self, index: CFIndex) -> CFStringTokenizerTokenType {
        extern "C-unwind" {
            fn CFStringTokenizerGoToTokenAtIndex(
                tokenizer: &CFStringTokenizer,
                index: CFIndex,
            ) -> CFStringTokenizerTokenType;
        }
        unsafe { CFStringTokenizerGoToTokenAtIndex(self, index) }
    }

    /// Token enumerator.
    ///
    /// Parameter `tokenizer`: The reference to CFStringTokenizer returned by
    /// CFStringTokenizerCreate.
    ///
    /// Returns: Type of the token if succeeded in finding a token and setting it as
    /// current token. kCFStringTokenizerTokenNone if failed in finding a token.
    ///
    /// If there is no preceding call to CFStringTokenizerGoToTokenAtIndex
    /// or CFStringTokenizerAdvanceToNextToken, it finds the first token in the range
    /// specified to CFStringTokenizerCreate. If there is a current token after successful
    /// call to CFStringTokenizerGoToTokenAtIndex or CFStringTokenizerAdvanceToNextToken,
    /// it proceeds to the next token. If succeeded in finding a token, set it as current
    /// token and return its token type. Otherwise invalidate current token and return
    /// kCFStringTokenizerTokenNone.
    /// The range and attribute of the token can be obtained by calling
    /// CFStringTokenizerGetCurrentTokenRange and
    /// CFStringTokenizerCopyCurrentTokenAttribute. If the token is a compound
    /// (with type kCFStringTokenizerTokenHasSubTokensMask or
    /// kCFStringTokenizerTokenHasDerivedSubTokensMask), its subtokens and
    /// (or) derived subtokens can be obtained by calling CFStringTokenizerGetCurrentSubTokens.
    #[doc(alias = "CFStringTokenizerAdvanceToNextToken")]
    #[inline]
    pub fn advance_to_next_token(&self) -> CFStringTokenizerTokenType {
        extern "C-unwind" {
            fn CFStringTokenizerAdvanceToNextToken(
                tokenizer: &CFStringTokenizer,
            ) -> CFStringTokenizerTokenType;
        }
        unsafe { CFStringTokenizerAdvanceToNextToken(self) }
    }

    /// Returns the range of current token.
    ///
    /// Parameter `tokenizer`: The reference to CFStringTokenizer returned by
    /// CFStringTokenizerCreate.
    ///
    /// Returns: Range of current token, or {kCFNotFound,0} if there is no current token.
    #[doc(alias = "CFStringTokenizerGetCurrentTokenRange")]
    #[inline]
    pub fn current_token_range(&self) -> CFRange {
        extern "C-unwind" {
            fn CFStringTokenizerGetCurrentTokenRange(tokenizer: &CFStringTokenizer) -> CFRange;
        }
        unsafe { CFStringTokenizerGetCurrentTokenRange(self) }
    }

    /// Copies the specified attribute of current token.
    ///
    /// Parameter `tokenizer`: The reference to CFStringTokenizer returned by
    /// CFStringTokenizerCreate.
    ///
    /// Parameter `attribute`: Specify a token attribute you want to obtain. The value is
    /// one of kCFStringTokenizerAttributeLatinTranscription or
    /// kCFStringTokenizerAttributeLanguage.
    ///
    /// Returns: Token attribute, or NULL if current token does not have the specified
    /// attribute or if there is no current token.
    #[doc(alias = "CFStringTokenizerCopyCurrentTokenAttribute")]
    #[inline]
    pub fn current_token_attribute(&self, attribute: CFOptionFlags) -> Option<CFRetained<CFType>> {
        extern "C-unwind" {
            fn CFStringTokenizerCopyCurrentTokenAttribute(
                tokenizer: &CFStringTokenizer,
                attribute: CFOptionFlags,
            ) -> Option<NonNull<CFType>>;
        }
        let ret = unsafe { CFStringTokenizerCopyCurrentTokenAttribute(self, attribute) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }

    /// Retrieves the subtokens or derived subtokens contained in the compound token.
    ///
    /// Parameter `tokenizer`: The reference to CFStringTokenizer returned by CFStringTokenizerCreate.
    ///
    /// Parameter `ranges`: An array of CFRange to fill in with the ranges of subtokens. The filled in
    /// ranges are relative to the string specified to CFStringTokenizerCreate. This parameter
    /// can be NULL.
    ///
    /// Parameter `maxRangeLength`: The maximum number of ranges to return.
    ///
    /// Parameter `derivedSubTokens`: An array of CFMutableArray to which the derived subtokens are to
    /// be added. This parameter can be NULL.
    ///
    /// Returns: number of subtokens.
    ///
    /// If token type is kCFStringTokenizerTokenNone, the ranges array and
    /// derivedSubTokens array are untouched and the return value is 0.
    /// If token type is kCFStringTokenizerTokenNormal, the ranges array has one item
    /// filled in with the entire range of the token (if maxRangeLength >= 1) and a string
    /// taken from the entire token range is added to the derivedSubTokens array and the
    /// return value is 1.
    /// If token type is kCFStringTokenizerTokenHasSubTokensMask or
    /// kCFStringTokenizerTokenHasDerivedSubTokensMask, the ranges array is filled
    /// in with as many items as there are subtokens (up to a limit of maxRangeLength).
    /// The derivedSubTokens array will have sub tokens added even when the sub token is a
    /// substring of the token. If token type is kCFStringTokenizerTokenHasSubTokensMask,
    /// the ordinary non-derived subtokens are added to the derivedSubTokens array.
    ///
    /// # Safety
    ///
    /// - `ranges` must be a valid pointer.
    /// - `derived_sub_tokens` generic must be of the correct type.
    /// - `derived_sub_tokens` might not allow `None`.
    #[doc(alias = "CFStringTokenizerGetCurrentSubTokens")]
    #[cfg(feature = "CFArray")]
    #[inline]
    pub unsafe fn current_sub_tokens(
        &self,
        ranges: *mut CFRange,
        max_range_length: CFIndex,
        derived_sub_tokens: Option<&CFMutableArray>,
    ) -> CFIndex {
        extern "C-unwind" {
            fn CFStringTokenizerGetCurrentSubTokens(
                tokenizer: &CFStringTokenizer,
                ranges: *mut CFRange,
                max_range_length: CFIndex,
                derived_sub_tokens: Option<&CFMutableArray>,
            ) -> CFIndex;
        }
        unsafe {
            CFStringTokenizerGetCurrentSubTokens(self, ranges, max_range_length, derived_sub_tokens)
        }
    }
}

#[deprecated = "renamed to `CFStringTokenizer::best_string_language`"]
#[inline]
pub extern "C-unwind" fn CFStringTokenizerCopyBestStringLanguage(
    string: &CFString,
    range: CFRange,
) -> Option<CFRetained<CFString>> {
    extern "C-unwind" {
        fn CFStringTokenizerCopyBestStringLanguage(
            string: &CFString,
            range: CFRange,
        ) -> Option<NonNull<CFString>>;
    }
    let ret = unsafe { CFStringTokenizerCopyBestStringLanguage(string, range) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[cfg(feature = "CFLocale")]
#[deprecated = "renamed to `CFStringTokenizer::new`"]
#[inline]
pub unsafe extern "C-unwind" fn CFStringTokenizerCreate(
    alloc: Option<&CFAllocator>,
    string: Option<&CFString>,
    range: CFRange,
    options: CFOptionFlags,
    locale: Option<&CFLocale>,
) -> Option<CFRetained<CFStringTokenizer>> {
    extern "C-unwind" {
        fn CFStringTokenizerCreate(
            alloc: Option<&CFAllocator>,
            string: Option<&CFString>,
            range: CFRange,
            options: CFOptionFlags,
            locale: Option<&CFLocale>,
        ) -> Option<NonNull<CFStringTokenizer>>;
    }
    let ret = unsafe { CFStringTokenizerCreate(alloc, string, range, options, locale) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

extern "C-unwind" {
    #[deprecated = "renamed to `CFStringTokenizer::set_string`"]
    pub fn CFStringTokenizerSetString(
        tokenizer: &CFStringTokenizer,
        string: Option<&CFString>,
        range: CFRange,
    );
}

#[deprecated = "renamed to `CFStringTokenizer::go_to_token_at_index`"]
#[inline]
pub extern "C-unwind" fn CFStringTokenizerGoToTokenAtIndex(
    tokenizer: &CFStringTokenizer,
    index: CFIndex,
) -> CFStringTokenizerTokenType {
    extern "C-unwind" {
        fn CFStringTokenizerGoToTokenAtIndex(
            tokenizer: &CFStringTokenizer,
            index: CFIndex,
        ) -> CFStringTokenizerTokenType;
    }
    unsafe { CFStringTokenizerGoToTokenAtIndex(tokenizer, index) }
}

#[deprecated = "renamed to `CFStringTokenizer::advance_to_next_token`"]
#[inline]
pub extern "C-unwind" fn CFStringTokenizerAdvanceToNextToken(
    tokenizer: &CFStringTokenizer,
) -> CFStringTokenizerTokenType {
    extern "C-unwind" {
        fn CFStringTokenizerAdvanceToNextToken(
            tokenizer: &CFStringTokenizer,
        ) -> CFStringTokenizerTokenType;
    }
    unsafe { CFStringTokenizerAdvanceToNextToken(tokenizer) }
}

#[deprecated = "renamed to `CFStringTokenizer::current_token_range`"]
#[inline]
pub extern "C-unwind" fn CFStringTokenizerGetCurrentTokenRange(
    tokenizer: &CFStringTokenizer,
) -> CFRange {
    extern "C-unwind" {
        fn CFStringTokenizerGetCurrentTokenRange(tokenizer: &CFStringTokenizer) -> CFRange;
    }
    unsafe { CFStringTokenizerGetCurrentTokenRange(tokenizer) }
}

#[deprecated = "renamed to `CFStringTokenizer::current_token_attribute`"]
#[inline]
pub extern "C-unwind" fn CFStringTokenizerCopyCurrentTokenAttribute(
    tokenizer: &CFStringTokenizer,
    attribute: CFOptionFlags,
) -> Option<CFRetained<CFType>> {
    extern "C-unwind" {
        fn CFStringTokenizerCopyCurrentTokenAttribute(
            tokenizer: &CFStringTokenizer,
            attribute: CFOptionFlags,
        ) -> Option<NonNull<CFType>>;
    }
    let ret = unsafe { CFStringTokenizerCopyCurrentTokenAttribute(tokenizer, attribute) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

extern "C-unwind" {
    #[cfg(feature = "CFArray")]
    #[deprecated = "renamed to `CFStringTokenizer::current_sub_tokens`"]
    pub fn CFStringTokenizerGetCurrentSubTokens(
        tokenizer: &CFStringTokenizer,
        ranges: *mut CFRange,
        max_range_length: CFIndex,
        derived_sub_tokens: Option<&CFMutableArray>,
    ) -> CFIndex;
}
