use windows::core::*;
use windows::Win32::Foundation::HMODULE;
use windows::Win32::System::LibraryLoader::{GetProcAddress, LoadLibraryA};
//use windows::Win32::UI::Input::XboxController::XINPUT_STATE;



// ref: https://gist.github.com/robindegen/9446175
#[repr(C)]
#[derive(Debug,Default)]
#[allow(non_snake_case)]
struct XinputThing {
    dwPacketNumber: u32,
    wButtons: u16,
    bLeftTrigger: u8,
    bRightTrigger: u8,
    sThumbLX: u16,
    sThumbLY: u16,
    sThumbRX: u16,
    sThumbRY: u16,

}

fn main() {
    unsafe {
        let foo = LoadLibraryA(s!("xinput1_4.dll")).expect("couldn't find xinput1_4.dll :(");

        #[allow(non_snake_case)]
        let GetProcAddressOrdinal = std::mem::transmute::<
            unsafe fn(
                hmodule: HMODULE,
                lpprocname: PCSTR,
            ) -> Option<unsafe extern "system" fn() -> isize>,
            unsafe extern "system" fn(
                hmodule: HMODULE,
                lpprocname: i32,
            ) -> windows::Win32::Foundation::FARPROC,
        >(GetProcAddress);

        #[allow(non_snake_case)]
        let XInputGetStateEx = std::mem::transmute::<
            unsafe extern "system" fn() -> isize,
            unsafe extern "system" fn(index: i32, output: *mut XinputThing),
        >(GetProcAddressOrdinal(foo, 100).expect("couldn't resolve XInputGetStateEx :("));

        let mut out = XinputThing::default();
        XInputGetStateEx(0, &mut out);
        println!("state: {:?}", out);
    }
}