from .ffi import (
    CData,
    CharCData,
    DispatcherFunc,
    EventLoopFdFunc,
    EventLoopIdleFunc,
    EventLoopSignalFunc,
    EventLoopTimerFunc,
    GlobalBindFunc,
    NotifyFunc,
    ResourceDestroyFunc,
    WlArgument,
    WlClient,
    WlDisplay,
    WlEventLoop,
    WlEventSource,
    WlGlobal,
    WlInterface,
    WlList,
    WlListener,
    WlProxy,
    WlQueue,
    WlResource,
    WlSignal,
)

###############################################################################
# wayland-version.h
###############################################################################

WAYLAND_VERSION_MAJOR: int
WAYLAND_VERSION_MINOR: int
WAYLAND_VERSION_MICRO: int

###############################################################################
# wayland-util.h
###############################################################################

# wl_fixed_t methods
def wl_fixed_to_double(f: int) -> float: ...
def wl_fixed_from_double(d: float) -> int: ...
def wl_fixed_from_int(i: int) -> int: ...

# wl_list methods
def wl_list_init(list: WlList) -> None: ...
def wl_list_insert(list: WlList, elm: WlList) -> None: ...
def wl_list_remove(list: WlList) -> None: ...

###############################################################################
# wayland-client-core.h
###############################################################################

# wl_event_queue methods
def wl_event_queue_destroy(queue: WlQueue) -> None: ...

# wl_proxy methods
def wl_proxy_marshal_array(
    proxy: WlProxy, opcode: int, args_ptr: WlArgument
) -> None: ...
def wl_proxy_marshal_array_constructor(
    proxy: WlProxy, opcode: int, args_ptr: WlArgument, interface_ptr: WlInterface
) -> WlProxy: ...
def wl_proxy_destroy(proxy: WlProxy) -> None: ...
def wl_proxy_add_dispatcher(
    proxy: WlProxy, dispatcher_func: DispatcherFunc, dispatcher_data: CData, data: CData
) -> int: ...

# wl_display methods
def wl_display_connect(name: bytes | CharCData) -> WlDisplay: ...
def wl_display_connect_to_fd(fd: int) -> WlDisplay: ...
def wl_display_disconnect(display: WlDisplay) -> None: ...
def wl_display_get_fd(display: WlDisplay) -> int: ...
def wl_display_dispatch(display: WlDisplay) -> int: ...
def wl_display_dispatch_queue(display: WlDisplay, queue: WlQueue) -> int: ...
def wl_display_dispatch_queue_pending(display: WlDisplay, queue: WlQueue) -> int: ...
def wl_display_dispatch_pending(display: WlDisplay) -> int: ...
def wl_display_get_error(display: WlDisplay) -> int: ...
def wl_display_flush(display: WlDisplay) -> int: ...
def wl_display_roundtrip_queue(display: WlDisplay, queue: WlQueue) -> int: ...
def wl_display_roundtrip(display: WlDisplay) -> int: ...
def wl_display_create_queue(display: WlDisplay) -> WlQueue: ...
def wl_display_prepare_read_queue(display: WlDisplay, queue: WlQueue) -> int: ...
def wl_display_prepare_read(display: WlDisplay) -> int: ...
def wl_display_read_events(display: WlDisplay) -> int: ...

###############################################################################
# wayland-server-core.h
###############################################################################

# event kind enum
WL_EVENT_READABLE: int
WL_EVENT_WRITABLE: int
WL_EVENT_HANGUP: int
WL_EVENT_ERROR: int

# wl_signal methods
def wl_signal_init(ptr: WlSignal) -> None: ...
def wl_signal_add(ptr: WlSignal, listener: WlListener) -> None: ...
def wl_signal_emit(ptr: WlSignal, data: CData) -> None: ...

# wl_event_loop methods
def wl_event_loop_create() -> WlEventLoop: ...
def wl_event_loop_destroy(event_loop: WlEventLoop) -> None: ...
def wl_event_loop_add_fd(
    ptr: WlEventLoop,
    fd: int,
    mask: int,
    event_loop_fd_func: EventLoopFdFunc,
    data: CData,
) -> WlEventSource: ...
def wl_event_loop_add_timer(
    ptr: WlEventLoop, event_loop_timer_func: EventLoopTimerFunc, data: CData
) -> WlEventSource: ...
def wl_event_loop_add_signal(
    ptr: WlEventLoop,
    signal: int,
    event_loop_signal_func: EventLoopSignalFunc,
    data: CData,
) -> WlEventSource: ...
def wl_event_loop_dispatch(ptr: WlEventLoop, timeout: int) -> int: ...
def wl_event_loop_dispatch_idle(ptr: WlEventLoop) -> None: ...
def wl_event_loop_add_idle(
    ptr: WlEventLoop, event_loop_idle_func: EventLoopIdleFunc, data: CData
) -> WlEventSource: ...
def wl_event_loop_add_destroy_listener(
    ptr: WlEventLoop, listener: WlListener
) -> None: ...

# wl_event_source methods
def wl_event_source_timer_update(ptr: WlEventSource, ms_delay: int) -> int: ...
def wl_event_source_remove(ptr: WlEventSource) -> int: ...
def wl_event_source_check(ptr: WlEventSource) -> None: ...

# wl_display methods
def wl_display_create() -> WlDisplay: ...
def wl_display_destroy(display: WlDisplay) -> None: ...
def wl_display_get_event_loop(display: WlDisplay) -> WlEventLoop: ...
def wl_display_add_socket(display: WlDisplay, name: bytes | CharCData) -> int: ...
def wl_display_add_socket_auto(display: WlDisplay) -> CharCData: ...
def wl_display_terminate(display: WlDisplay) -> None: ...
def wl_display_run(display: WlDisplay) -> None: ...
def wl_display_flush_clients(display: WlDisplay) -> None: ...
def wl_display_destroy_clients(display: WlDisplay) -> None: ...
def wl_display_get_serial(display: WlDisplay) -> int: ...
def wl_display_next_serial(display: WlDisplay) -> int: ...
def wl_display_init_shm(display: WlDisplay) -> int: ...
def wl_display_add_shm_format(display: WlDisplay, format: int) -> CData: ...

# wl_global methods
def wl_global_create(
    display: WlDisplay,
    interface: WlInterface,
    version: int,
    data: CData,
    global_bind_func: GlobalBindFunc,
) -> WlGlobal: ...
def wl_global_destroy(data: WlGlobal) -> None: ...

# wl_client methods
def wl_client_create(display: WlDisplay, fd: int) -> WlClient: ...
def wl_client_destroy(client: WlClient) -> None: ...
def wl_client_flush(client: WlClient) -> None: ...
def wl_client_get_credentials(
    client: WlClient, pid: CData, uid: CData, gid: CData
) -> None: ...
def wl_client_add_destroy_listener(client: WlClient, listener: WlListener) -> None: ...
def wl_client_get_object(client: WlClient, id: int) -> WlResource: ...

# wl_resource methods
def wl_resource_post_event_array(
    resource: WlResource, opcode: int, args: WlArgument
) -> None: ...
def wl_resource_post_error(
    resource: WlResource, code: int, msg: bytes | CharCData
) -> None: ...
def wl_resource_create(
    client: WlClient, interface: WlInterface, version: int, id: int
) -> WlResource: ...
def wl_resource_set_dispatcher(
    resource: WlResource,
    dispatcher_func: DispatcherFunc,
    implementation: CData,
    data: CData,
    resource_destroy_func: ResourceDestroyFunc,
) -> None: ...
def wl_resource_destroy(resource: WlResource) -> None: ...
def wl_resource_get_id(resource: WlResource) -> int: ...
def wl_resource_get_client(resource: WlResource) -> WlClient: ...
def wl_resource_get_user_data(resource: WlResource) -> CData: ...
def wl_resource_add_destroy_listener(
    resource: WlResource, listener: WlListener
) -> None: ...

# anonymous file methods
def os_create_anonymous_file(size: int) -> int: ...

# cffi callback functions
dispatcher_func: DispatcherFunc
resource_destroy_func: ResourceDestroyFunc
event_loop_fd_func: EventLoopFdFunc
event_loop_signal_func: EventLoopSignalFunc
event_loop_timer_func: EventLoopTimerFunc
event_loop_idle_func: EventLoopIdleFunc
global_bind_func: GlobalBindFunc
notify_func: NotifyFunc
