// This file was generated by gir (https://github.com/gtk-rs/gir)
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

use crate::{
    Analysis, AttrIterator, AttrList, Context, Direction, GlyphString, Item, Stretch, Style,
    Variant, Weight,
};
use glib::translate::*;
use std::{mem, ptr};

//#[cfg_attr(feature = "v1_44", deprecated = "Since 1.44")]
//#[allow(deprecated)]
//#[doc(alias = "pango_break")]
//#[doc(alias = "break")]
//pub fn break_(text: &str, analysis: &mut Analysis, attrs: /*Ignored*/&[LogAttr]) {
//    unsafe { TODO: call ffi:pango_break() }
//}

//#[doc(alias = "pango_default_break")]
//pub fn default_break(text: &str, analysis: Option<&mut Analysis>, attrs: /*Ignored*/&mut LogAttr, attrs_len: i32) {
//    unsafe { TODO: call ffi:pango_default_break() }
//}

#[doc(alias = "pango_find_base_dir")]
pub fn find_base_dir(text: &str) -> Direction {
    let length = text.len() as _;
    unsafe { from_glib(ffi::pango_find_base_dir(text.to_glib_none().0, length)) }
}

#[doc(alias = "pango_find_paragraph_boundary")]
pub fn find_paragraph_boundary(text: &str) -> (i32, i32) {
    let length = text.len() as _;
    unsafe {
        let mut paragraph_delimiter_index = mem::MaybeUninit::uninit();
        let mut next_paragraph_start = mem::MaybeUninit::uninit();
        ffi::pango_find_paragraph_boundary(
            text.to_glib_none().0,
            length,
            paragraph_delimiter_index.as_mut_ptr(),
            next_paragraph_start.as_mut_ptr(),
        );
        (
            paragraph_delimiter_index.assume_init(),
            next_paragraph_start.assume_init(),
        )
    }
}

//#[doc(alias = "pango_get_log_attrs")]
//#[doc(alias = "get_log_attrs")]
//pub fn log_attrs(text: &str, level: i32, language: &mut Language, attrs: /*Ignored*/&[LogAttr]) {
//    unsafe { TODO: call ffi:pango_get_log_attrs() }
//}

#[doc(alias = "pango_is_zero_width")]
pub fn is_zero_width(ch: char) -> bool {
    unsafe { from_glib(ffi::pango_is_zero_width(ch.into_glib())) }
}

#[doc(alias = "pango_itemize")]
pub fn itemize(
    context: &Context,
    text: &str,
    start_index: i32,
    length: i32,
    attrs: &AttrList,
    cached_iter: Option<&AttrIterator>,
) -> Vec<Item> {
    unsafe {
        FromGlibPtrContainer::from_glib_full(ffi::pango_itemize(
            context.to_glib_none().0,
            text.to_glib_none().0,
            start_index,
            length,
            attrs.to_glib_none().0,
            mut_override(cached_iter.to_glib_none().0),
        ))
    }
}

#[doc(alias = "pango_itemize_with_base_dir")]
pub fn itemize_with_base_dir(
    context: &Context,
    base_dir: Direction,
    text: &str,
    start_index: i32,
    length: i32,
    attrs: &AttrList,
    cached_iter: Option<&AttrIterator>,
) -> Vec<Item> {
    unsafe {
        FromGlibPtrContainer::from_glib_full(ffi::pango_itemize_with_base_dir(
            context.to_glib_none().0,
            base_dir.into_glib(),
            text.to_glib_none().0,
            start_index,
            length,
            attrs.to_glib_none().0,
            mut_override(cached_iter.to_glib_none().0),
        ))
    }
}

#[doc(alias = "pango_markup_parser_finish")]
pub fn markup_parser_finish(
    context: &glib::MarkupParseContext,
) -> Result<(AttrList, glib::GString, char), glib::Error> {
    unsafe {
        let mut attr_list = ptr::null_mut();
        let mut text = ptr::null_mut();
        let mut accel_char = mem::MaybeUninit::uninit();
        let mut error = ptr::null_mut();
        let is_ok = ffi::pango_markup_parser_finish(
            context.to_glib_none().0,
            &mut attr_list,
            &mut text,
            accel_char.as_mut_ptr(),
            &mut error,
        );
        debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
        if error.is_null() {
            Ok((
                from_glib_full(attr_list),
                from_glib_full(text),
                std::convert::TryFrom::try_from(accel_char.assume_init())
                    .expect("conversion from an invalid Unicode value attempted"),
            ))
        } else {
            Err(from_glib_full(error))
        }
    }
}

#[doc(alias = "pango_markup_parser_new")]
pub fn markup_parser_new(accel_marker: char) -> glib::MarkupParseContext {
    unsafe { from_glib_none(ffi::pango_markup_parser_new(accel_marker.into_glib())) }
}

#[doc(alias = "pango_parse_markup")]
pub fn parse_markup(
    markup_text: &str,
    accel_marker: char,
) -> Result<(AttrList, glib::GString, char), glib::Error> {
    let length = markup_text.len() as _;
    unsafe {
        let mut attr_list = ptr::null_mut();
        let mut text = ptr::null_mut();
        let mut accel_char = mem::MaybeUninit::uninit();
        let mut error = ptr::null_mut();
        let is_ok = ffi::pango_parse_markup(
            markup_text.to_glib_none().0,
            length,
            accel_marker.into_glib(),
            &mut attr_list,
            &mut text,
            accel_char.as_mut_ptr(),
            &mut error,
        );
        debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
        if error.is_null() {
            Ok((
                from_glib_full(attr_list),
                from_glib_full(text),
                std::convert::TryFrom::try_from(accel_char.assume_init())
                    .expect("conversion from an invalid Unicode value attempted"),
            ))
        } else {
            Err(from_glib_full(error))
        }
    }
}

#[doc(alias = "pango_parse_stretch")]
pub fn parse_stretch(str: &str, warn: bool) -> Option<Stretch> {
    unsafe {
        let mut stretch = mem::MaybeUninit::uninit();
        let ret = from_glib(ffi::pango_parse_stretch(
            str.to_glib_none().0,
            stretch.as_mut_ptr(),
            warn.into_glib(),
        ));
        if ret {
            Some(from_glib(stretch.assume_init()))
        } else {
            None
        }
    }
}

#[doc(alias = "pango_parse_style")]
pub fn parse_style(str: &str, warn: bool) -> Option<Style> {
    unsafe {
        let mut style = mem::MaybeUninit::uninit();
        let ret = from_glib(ffi::pango_parse_style(
            str.to_glib_none().0,
            style.as_mut_ptr(),
            warn.into_glib(),
        ));
        if ret {
            Some(from_glib(style.assume_init()))
        } else {
            None
        }
    }
}

#[doc(alias = "pango_parse_variant")]
pub fn parse_variant(str: &str, warn: bool) -> Option<Variant> {
    unsafe {
        let mut variant = mem::MaybeUninit::uninit();
        let ret = from_glib(ffi::pango_parse_variant(
            str.to_glib_none().0,
            variant.as_mut_ptr(),
            warn.into_glib(),
        ));
        if ret {
            Some(from_glib(variant.assume_init()))
        } else {
            None
        }
    }
}

#[doc(alias = "pango_parse_weight")]
pub fn parse_weight(str: &str, warn: bool) -> Option<Weight> {
    unsafe {
        let mut weight = mem::MaybeUninit::uninit();
        let ret = from_glib(ffi::pango_parse_weight(
            str.to_glib_none().0,
            weight.as_mut_ptr(),
            warn.into_glib(),
        ));
        if ret {
            Some(from_glib(weight.assume_init()))
        } else {
            None
        }
    }
}

#[doc(alias = "pango_quantize_line_geometry")]
pub fn quantize_line_geometry(thickness: &mut i32, position: &mut i32) {
    unsafe {
        ffi::pango_quantize_line_geometry(thickness, position);
    }
}

#[doc(alias = "pango_shape")]
pub fn shape(text: &str, analysis: &Analysis, glyphs: &mut GlyphString) {
    let length = text.len() as _;
    unsafe {
        ffi::pango_shape(
            text.to_glib_none().0,
            length,
            analysis.to_glib_none().0,
            glyphs.to_glib_none_mut().0,
        );
    }
}

//#[cfg(feature = "v1_50")]
//#[cfg_attr(docsrs, doc(cfg(feature = "v1_50")))]
//#[doc(alias = "pango_shape_item")]
//pub fn shape_item(item: &mut Item, paragraph_text: Option<&str>, log_attrs: /*Ignored*/Option<&mut LogAttr>, glyphs: &mut GlyphString, flags: ShapeFlags) {
//    unsafe { TODO: call ffi:pango_shape_item() }
//}

//#[cfg(feature = "v1_44")]
//#[cfg_attr(docsrs, doc(cfg(feature = "v1_44")))]
//#[doc(alias = "pango_tailor_break")]
//pub fn tailor_break(text: &str, analysis: &mut Analysis, offset: i32, attrs: /*Ignored*/&[LogAttr]) {
//    unsafe { TODO: call ffi:pango_tailor_break() }
//}

#[doc(alias = "pango_unichar_direction")]
pub fn unichar_direction(ch: char) -> Direction {
    unsafe { from_glib(ffi::pango_unichar_direction(ch.into_glib())) }
}

#[doc(alias = "pango_units_from_double")]
pub fn units_from_double(d: f64) -> i32 {
    unsafe { ffi::pango_units_from_double(d) }
}

#[doc(alias = "pango_units_to_double")]
pub fn units_to_double(i: i32) -> f64 {
    unsafe { ffi::pango_units_to_double(i) }
}

#[doc(alias = "pango_version")]
pub fn version() -> i32 {
    unsafe { ffi::pango_version() }
}

#[doc(alias = "pango_version_check")]
pub fn version_check(
    required_major: i32,
    required_minor: i32,
    required_micro: i32,
) -> Option<glib::GString> {
    unsafe {
        from_glib_none(ffi::pango_version_check(
            required_major,
            required_minor,
            required_micro,
        ))
    }
}

#[doc(alias = "pango_version_string")]
pub fn version_string() -> glib::GString {
    unsafe { from_glib_none(ffi::pango_version_string()) }
}
