// Code generated by girgen. DO NOT EDIT.

package adw

import (
	"runtime"
	"unsafe"

	"github.com/diamondburned/gotk4/pkg/core/gextras"
	coreglib "github.com/diamondburned/gotk4/pkg/core/glib"
	"github.com/diamondburned/gotk4/pkg/gdk/v4"
	"github.com/diamondburned/gotk4/pkg/gtk/v4"
)

// #include <stdlib.h>
// #include <adwaita.h>
// #include <glib-object.h>
// extern gboolean _gotk4_adw1_TabBar_ConnectExtraDragDrop(gpointer, AdwTabPage*, GValue*, guintptr);
// extern GdkDragAction _gotk4_adw1_TabBar_ConnectExtraDragValue(gpointer, AdwTabPage*, GValue*, guintptr);
import "C"

// GType values.
var (
	GTypeTabBar = coreglib.Type(C.adw_tab_bar_get_type())
)

func init() {
	coreglib.RegisterGValueMarshalers([]coreglib.TypeMarshaler{
		coreglib.TypeMarshaler{T: GTypeTabBar, F: marshalTabBar},
	})
}

// TabBarOverrides contains methods that are overridable.
type TabBarOverrides struct {
}

func defaultTabBarOverrides(v *TabBar) TabBarOverrides {
	return TabBarOverrides{}
}

// TabBar: tab bar for tabview.
//
// <picture> <source srcset="tab-bar-dark.png" media="(prefers-color-scheme:
// dark)"> <img src="tab-bar.png" alt="tab-bar"> </picture>
//
// The AdwTabBar widget is a tab bar that can be used with conjunction with
// AdwTabView. It is typically used as a top bar within toolbarview.
//
// AdwTabBar can autohide and can optionally contain action widgets on both
// sides of the tabs.
//
// When there's not enough space to show all the tabs, AdwTabBar will scroll
// them. Pinned tabs always stay visible and aren't a part of the scrollable
// area.
//
// # CSS nodes
//
// AdwTabBar has a single CSS node with name tabbar.
type TabBar struct {
	_ [0]func() // equal guard
	gtk.Widget
}

var (
	_ gtk.Widgetter = (*TabBar)(nil)
)

func init() {
	coreglib.RegisterClassInfo[*TabBar, *TabBarClass, TabBarOverrides](
		GTypeTabBar,
		initTabBarClass,
		wrapTabBar,
		defaultTabBarOverrides,
	)
}

func initTabBarClass(gclass unsafe.Pointer, overrides TabBarOverrides, classInitFunc func(*TabBarClass)) {
	if classInitFunc != nil {
		class := (*TabBarClass)(gextras.NewStructNative(gclass))
		classInitFunc(class)
	}
}

func wrapTabBar(obj *coreglib.Object) *TabBar {
	return &TabBar{
		Widget: gtk.Widget{
			InitiallyUnowned: coreglib.InitiallyUnowned{
				Object: obj,
			},
			Object: obj,
			Accessible: gtk.Accessible{
				Object: obj,
			},
			Buildable: gtk.Buildable{
				Object: obj,
			},
			ConstraintTarget: gtk.ConstraintTarget{
				Object: obj,
			},
		},
	}
}

func marshalTabBar(p uintptr) (interface{}, error) {
	return wrapTabBar(coreglib.ValueFromNative(unsafe.Pointer(p)).Object()), nil
}

// ConnectExtraDragDrop: this signal is emitted when content is dropped onto a
// tab.
//
// The content must be of one of the types set up via
// tabbar.SetupExtraDropTarget.
//
// See gtk.DropTarget::drop.
func (self *TabBar) ConnectExtraDragDrop(f func(page *TabPage, value *coreglib.Value) (ok bool)) coreglib.SignalHandle {
	return coreglib.ConnectGeneratedClosure(self, "extra-drag-drop", false, unsafe.Pointer(C._gotk4_adw1_TabBar_ConnectExtraDragDrop), f)
}

// ConnectExtraDragValue: this signal is emitted when the dropped content is
// preloaded.
//
// In order for data to be preloaded, tabbar:extra-drag-preload must be set to
// TRUE.
//
// The content must be of one of the types set up via
// tabbar.SetupExtraDropTarget.
//
// See gtk.DropTarget:value.
func (self *TabBar) ConnectExtraDragValue(f func(page *TabPage, value *coreglib.Value) (dragAction gdk.DragAction)) coreglib.SignalHandle {
	return coreglib.ConnectGeneratedClosure(self, "extra-drag-value", false, unsafe.Pointer(C._gotk4_adw1_TabBar_ConnectExtraDragValue), f)
}

// NewTabBar creates a new AdwTabBar.
//
// The function returns the following values:
//
//   - tabBar: newly created AdwTabBar.
func NewTabBar() *TabBar {
	var _cret *C.AdwTabBar // in

	_cret = C.adw_tab_bar_new()

	var _tabBar *TabBar // out

	_tabBar = wrapTabBar(coreglib.Take(unsafe.Pointer(_cret)))

	return _tabBar
}

// Autohide gets whether the tabs automatically hide.
//
// The function returns the following values:
//
//   - ok: whether the tabs automatically hide.
func (self *TabBar) Autohide() bool {
	var _arg0 *C.AdwTabBar // out
	var _cret C.gboolean   // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_autohide(_arg0)
	runtime.KeepAlive(self)

	var _ok bool // out

	if _cret != 0 {
		_ok = true
	}

	return _ok
}

// EndActionWidget gets the widget shown after the tabs.
//
// The function returns the following values:
//
//   - widget (optional) shown after the tabs.
func (self *TabBar) EndActionWidget() gtk.Widgetter {
	var _arg0 *C.AdwTabBar // out
	var _cret *C.GtkWidget // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_end_action_widget(_arg0)
	runtime.KeepAlive(self)

	var _widget gtk.Widgetter // out

	if _cret != nil {
		{
			objptr := unsafe.Pointer(_cret)

			object := coreglib.Take(objptr)
			casted := object.WalkCast(func(obj coreglib.Objector) bool {
				_, ok := obj.(gtk.Widgetter)
				return ok
			})
			rv, ok := casted.(gtk.Widgetter)
			if !ok {
				panic("no marshaler for " + object.TypeFromInstance().String() + " matching gtk.Widgetter")
			}
			_widget = rv
		}
	}

	return _widget
}

// ExpandTabs gets whether tabs expand to full width.
//
// The function returns the following values:
//
//   - ok: whether tabs expand to full width.
func (self *TabBar) ExpandTabs() bool {
	var _arg0 *C.AdwTabBar // out
	var _cret C.gboolean   // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_expand_tabs(_arg0)
	runtime.KeepAlive(self)

	var _ok bool // out

	if _cret != 0 {
		_ok = true
	}

	return _ok
}

// ExtraDragPreferredAction gets the current action during a drop on the
// extra_drop_target.
//
// The function returns the following values:
//
//   - dragAction: drag action of the current drop.
func (self *TabBar) ExtraDragPreferredAction() gdk.DragAction {
	var _arg0 *C.AdwTabBar    // out
	var _cret C.GdkDragAction // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_extra_drag_preferred_action(_arg0)
	runtime.KeepAlive(self)

	var _dragAction gdk.DragAction // out

	_dragAction = gdk.DragAction(_cret)

	return _dragAction
}

// ExtraDragPreload gets whether drop data should be preloaded on hover.
//
// The function returns the following values:
//
//   - ok: whether drop data should be preloaded on hover.
func (self *TabBar) ExtraDragPreload() bool {
	var _arg0 *C.AdwTabBar // out
	var _cret C.gboolean   // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_extra_drag_preload(_arg0)
	runtime.KeepAlive(self)

	var _ok bool // out

	if _cret != 0 {
		_ok = true
	}

	return _ok
}

// Inverted gets whether tabs use inverted layout.
//
// The function returns the following values:
//
//   - ok: whether tabs use inverted layout.
func (self *TabBar) Inverted() bool {
	var _arg0 *C.AdwTabBar // out
	var _cret C.gboolean   // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_inverted(_arg0)
	runtime.KeepAlive(self)

	var _ok bool // out

	if _cret != 0 {
		_ok = true
	}

	return _ok
}

// IsOverflowing gets whether self is overflowing.
//
// If TRUE, all tabs cannot be displayed at once and require scrolling.
//
// The function returns the following values:
//
//   - ok: whether self is overflowing.
func (self *TabBar) IsOverflowing() bool {
	var _arg0 *C.AdwTabBar // out
	var _cret C.gboolean   // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_is_overflowing(_arg0)
	runtime.KeepAlive(self)

	var _ok bool // out

	if _cret != 0 {
		_ok = true
	}

	return _ok
}

// StartActionWidget gets the widget shown before the tabs.
//
// The function returns the following values:
//
//   - widget (optional) shown before the tabs.
func (self *TabBar) StartActionWidget() gtk.Widgetter {
	var _arg0 *C.AdwTabBar // out
	var _cret *C.GtkWidget // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_start_action_widget(_arg0)
	runtime.KeepAlive(self)

	var _widget gtk.Widgetter // out

	if _cret != nil {
		{
			objptr := unsafe.Pointer(_cret)

			object := coreglib.Take(objptr)
			casted := object.WalkCast(func(obj coreglib.Objector) bool {
				_, ok := obj.(gtk.Widgetter)
				return ok
			})
			rv, ok := casted.(gtk.Widgetter)
			if !ok {
				panic("no marshaler for " + object.TypeFromInstance().String() + " matching gtk.Widgetter")
			}
			_widget = rv
		}
	}

	return _widget
}

// TabsRevealed gets whether the tabs are currently revealed.
//
// See tabbar:autohide.
//
// The function returns the following values:
//
//   - ok: whether the tabs are currently revealed.
func (self *TabBar) TabsRevealed() bool {
	var _arg0 *C.AdwTabBar // out
	var _cret C.gboolean   // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_tabs_revealed(_arg0)
	runtime.KeepAlive(self)

	var _ok bool // out

	if _cret != 0 {
		_ok = true
	}

	return _ok
}

// View gets the tab view self controls.
//
// The function returns the following values:
//
//   - tabView (optional): view self controls.
func (self *TabBar) View() *TabView {
	var _arg0 *C.AdwTabBar  // out
	var _cret *C.AdwTabView // in

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))

	_cret = C.adw_tab_bar_get_view(_arg0)
	runtime.KeepAlive(self)

	var _tabView *TabView // out

	if _cret != nil {
		_tabView = wrapTabView(coreglib.Take(unsafe.Pointer(_cret)))
	}

	return _tabView
}

// SetAutohide sets whether the tabs automatically hide.
//
// If set to TRUE, the tab bar disappears when tabbar:view has 0 or 1 tab,
// no pinned tabs, and no tab is being transferred.
//
// See tabbar:tabs-revealed.
//
// The function takes the following parameters:
//
//   - autohide: whether the tabs automatically hide.
func (self *TabBar) SetAutohide(autohide bool) {
	var _arg0 *C.AdwTabBar // out
	var _arg1 C.gboolean   // out

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))
	if autohide {
		_arg1 = C.TRUE
	}

	C.adw_tab_bar_set_autohide(_arg0, _arg1)
	runtime.KeepAlive(self)
	runtime.KeepAlive(autohide)
}

// SetEndActionWidget sets the widget to show after the tabs.
//
// The function takes the following parameters:
//
//   - widget (optional) to show after the tabs.
func (self *TabBar) SetEndActionWidget(widget gtk.Widgetter) {
	var _arg0 *C.AdwTabBar // out
	var _arg1 *C.GtkWidget // out

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))
	if widget != nil {
		_arg1 = (*C.GtkWidget)(unsafe.Pointer(coreglib.InternObject(widget).Native()))
	}

	C.adw_tab_bar_set_end_action_widget(_arg0, _arg1)
	runtime.KeepAlive(self)
	runtime.KeepAlive(widget)
}

// SetExpandTabs sets whether tabs expand to full width.
//
// If set to TRUE, the tabs will always vary width filling the whole width when
// possible, otherwise tabs will always have the minimum possible size.
//
// The function takes the following parameters:
//
//   - expandTabs: whether to expand tabs.
func (self *TabBar) SetExpandTabs(expandTabs bool) {
	var _arg0 *C.AdwTabBar // out
	var _arg1 C.gboolean   // out

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))
	if expandTabs {
		_arg1 = C.TRUE
	}

	C.adw_tab_bar_set_expand_tabs(_arg0, _arg1)
	runtime.KeepAlive(self)
	runtime.KeepAlive(expandTabs)
}

// SetExtraDragPreload sets whether drop data should be preloaded on hover.
//
// See gtk.DropTarget:preload.
//
// The function takes the following parameters:
//
//   - preload: whether to preload drop data.
func (self *TabBar) SetExtraDragPreload(preload bool) {
	var _arg0 *C.AdwTabBar // out
	var _arg1 C.gboolean   // out

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))
	if preload {
		_arg1 = C.TRUE
	}

	C.adw_tab_bar_set_extra_drag_preload(_arg0, _arg1)
	runtime.KeepAlive(self)
	runtime.KeepAlive(preload)
}

// SetInverted sets whether tabs tabs use inverted layout.
//
// If set to TRUE, non-pinned tabs will have the close button at the beginning
// and the indicator at the end rather than the opposite.
//
// The function takes the following parameters:
//
//   - inverted: whether tabs use inverted layout.
func (self *TabBar) SetInverted(inverted bool) {
	var _arg0 *C.AdwTabBar // out
	var _arg1 C.gboolean   // out

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))
	if inverted {
		_arg1 = C.TRUE
	}

	C.adw_tab_bar_set_inverted(_arg0, _arg1)
	runtime.KeepAlive(self)
	runtime.KeepAlive(inverted)
}

// SetStartActionWidget sets the widget to show before the tabs.
//
// The function takes the following parameters:
//
//   - widget (optional) to show before the tabs.
func (self *TabBar) SetStartActionWidget(widget gtk.Widgetter) {
	var _arg0 *C.AdwTabBar // out
	var _arg1 *C.GtkWidget // out

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))
	if widget != nil {
		_arg1 = (*C.GtkWidget)(unsafe.Pointer(coreglib.InternObject(widget).Native()))
	}

	C.adw_tab_bar_set_start_action_widget(_arg0, _arg1)
	runtime.KeepAlive(self)
	runtime.KeepAlive(widget)
}

// SetView sets the tab view self controls.
//
// The function takes the following parameters:
//
//   - view (optional): tab view.
func (self *TabBar) SetView(view *TabView) {
	var _arg0 *C.AdwTabBar  // out
	var _arg1 *C.AdwTabView // out

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))
	if view != nil {
		_arg1 = (*C.AdwTabView)(unsafe.Pointer(coreglib.InternObject(view).Native()))
	}

	C.adw_tab_bar_set_view(_arg0, _arg1)
	runtime.KeepAlive(self)
	runtime.KeepAlive(view)
}

// SetupExtraDropTarget sets the supported types for this drop target.
//
// Sets up an extra drop target on tabs.
//
// This allows to drag arbitrary content onto tabs, for example URLs in a web
// browser.
//
// If a tab is hovered for a certain period of time while dragging the content,
// it will be automatically selected.
//
// The tabbar::extra-drag-drop signal can be used to handle the drop.
//
// The function takes the following parameters:
//
//   - actions: supported actions.
//   - types (optional): all supported GTypes that can be dropped.
func (self *TabBar) SetupExtraDropTarget(actions gdk.DragAction, types []coreglib.Type) {
	var _arg0 *C.AdwTabBar    // out
	var _arg1 C.GdkDragAction // out
	var _arg2 *C.GType        // out
	var _arg3 C.gsize

	_arg0 = (*C.AdwTabBar)(unsafe.Pointer(coreglib.InternObject(self).Native()))
	_arg1 = C.GdkDragAction(actions)
	_arg3 = (C.gsize)(len(types))
	_arg2 = (*C.GType)(C.calloc(C.size_t(len(types)), C.size_t(C.sizeof_GType)))
	defer C.free(unsafe.Pointer(_arg2))
	{
		out := unsafe.Slice((*C.GType)(_arg2), len(types))
		for i := range types {
			out[i] = C.GType(types[i])
		}
	}

	C.adw_tab_bar_setup_extra_drop_target(_arg0, _arg1, _arg2, _arg3)
	runtime.KeepAlive(self)
	runtime.KeepAlive(actions)
	runtime.KeepAlive(types)
}

// TabBarClass: instance of this type is always passed by reference.
type TabBarClass struct {
	*tabBarClass
}

// tabBarClass is the struct that's finalized.
type tabBarClass struct {
	native *C.AdwTabBarClass
}

func (t *TabBarClass) ParentClass() *gtk.WidgetClass {
	valptr := &t.native.parent_class
	var _v *gtk.WidgetClass // out
	_v = (*gtk.WidgetClass)(gextras.NewStructNative(unsafe.Pointer(valptr)))
	return _v
}
