// 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 gdk_sys;
use glib::object::IsA;
use glib::translate::*;
use std::fmt;
use std::mem;
use AxisUse;
use Device;
use Display;
use EventType;
use ModifierType;
use Seat;
use Surface;

glib_wrapper! {
    pub struct Event(Object<gdk_sys::GdkEvent>);

    match fn {
        get_type => || gdk_sys::gdk_event_get_type(),
    }
}

pub const NONE_EVENT: Option<&Event> = None;

pub trait EventExt: 'static {
    fn get_axis(&self, axis_use: AxisUse) -> Option<f64>;

    fn get_device(&self) -> Option<Device>;

    fn get_display(&self) -> Option<Display>;

    fn get_event_type(&self) -> EventType;

    //fn get_history(&self) -> /*Ignored*/Vec<TimeCoord>;

    fn get_modifier_state(&self) -> ModifierType;

    fn get_pointer_emulated(&self) -> bool;

    fn get_position(&self) -> Option<(f64, f64)>;

    fn get_seat(&self) -> Option<Seat>;

    fn get_surface(&self) -> Option<Surface>;

    fn get_time(&self) -> u32;

    fn triggers_context_menu(&self) -> bool;
}

impl<O: IsA<Event>> EventExt for O {
    fn get_axis(&self, axis_use: AxisUse) -> Option<f64> {
        unsafe {
            let mut value = mem::MaybeUninit::uninit();
            let ret = from_glib(gdk_sys::gdk_event_get_axis(
                self.as_ref().to_glib_none().0,
                axis_use.to_glib(),
                value.as_mut_ptr(),
            ));
            let value = value.assume_init();
            if ret {
                Some(value)
            } else {
                None
            }
        }
    }

    fn get_device(&self) -> Option<Device> {
        unsafe {
            from_glib_none(gdk_sys::gdk_event_get_device(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn get_display(&self) -> Option<Display> {
        unsafe {
            from_glib_none(gdk_sys::gdk_event_get_display(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn get_event_type(&self) -> EventType {
        unsafe {
            from_glib(gdk_sys::gdk_event_get_event_type(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    //fn get_history(&self) -> /*Ignored*/Vec<TimeCoord> {
    //    unsafe { TODO: call gdk_sys:gdk_event_get_history() }
    //}

    fn get_modifier_state(&self) -> ModifierType {
        unsafe {
            from_glib(gdk_sys::gdk_event_get_modifier_state(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn get_pointer_emulated(&self) -> bool {
        unsafe {
            from_glib(gdk_sys::gdk_event_get_pointer_emulated(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn get_position(&self) -> Option<(f64, f64)> {
        unsafe {
            let mut x = mem::MaybeUninit::uninit();
            let mut y = mem::MaybeUninit::uninit();
            let ret = from_glib(gdk_sys::gdk_event_get_position(
                self.as_ref().to_glib_none().0,
                x.as_mut_ptr(),
                y.as_mut_ptr(),
            ));
            let x = x.assume_init();
            let y = y.assume_init();
            if ret {
                Some((x, y))
            } else {
                None
            }
        }
    }

    fn get_seat(&self) -> Option<Seat> {
        unsafe { from_glib_none(gdk_sys::gdk_event_get_seat(self.as_ref().to_glib_none().0)) }
    }

    fn get_surface(&self) -> Option<Surface> {
        unsafe {
            from_glib_none(gdk_sys::gdk_event_get_surface(
                self.as_ref().to_glib_none().0,
            ))
        }
    }

    fn get_time(&self) -> u32 {
        unsafe { gdk_sys::gdk_event_get_time(self.as_ref().to_glib_none().0) }
    }

    fn triggers_context_menu(&self) -> bool {
        unsafe {
            from_glib(gdk_sys::gdk_event_triggers_context_menu(
                self.as_ref().to_glib_none().0,
            ))
        }
    }
}

impl fmt::Display for Event {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "Event")
    }
}
