extern crate winapi;
extern crate log;
use std::ptr::null_mut;
use winapi::um::winuser::{
    GetCursorPos, GetSystemMetrics, SM_CXSCREEN, SM_CYSCREEN,
    FindWindowA, GetWindowRect
};
use winapi::shared::windef::{
    POINT,
    RECT,
};
use winapi::um::winuser::{GetForegroundWindow, GetWindowTextW, GetClassNameW, GetWindowThreadProcessId};
use std::ptr;
use std::ffi::{OsString, CString};
use std::os::windows::ffi::OsStringExt;
use winapi::um::processthreadsapi::{OpenProcess, GetProcessImageFileNameA};
use winapi::um::winnt::PROCESS_QUERY_INFORMATION;


pub fn screen_size() -> (i32, i32) {
    unsafe {
        let width = GetSystemMetrics(SM_CXSCREEN);
        let height = GetSystemMetrics(SM_CYSCREEN);
        (width, height)
    }
}

pub fn cursor_pos() -> (i32, i32) {
    let mut point = POINT { x: 0, y: 0 };
    unsafe {
        GetCursorPos(&mut point);
        let x = point.x;
        let y = point.y;
        (x, y)
    }
}

pub fn get_window_rect() -> Option<(i32, i32, i32, i32)> {
    unsafe {
        let h = GetForegroundWindow();

        let mut rect: RECT = std::mem::zeroed();
        if GetWindowRect(h, &mut rect) != 0 {
            Some((rect.left, rect.top, rect.right, rect.bottom))
        } else {
            None
        }
    }
}


pub fn get_foredround_window_name() {
    unsafe {
        let foreground_window = GetForegroundWindow();

        // let mut process_id = 0;
        // GetWindowThreadProcessId(foreground_window, &mut process_id);

        // let mut process_name: [u16; 1024] = [0; 1024];
        // GetWindowTextW(foreground_window, process_name.as_mut_ptr(), 1024);

        let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION, 0, pid);
        if process_handle.is_null() {
            return None;
        }

        let mut image_name = [0u8; 1024];
        let mut image_name_size = image_name.len() as u32;
        if GetProcessImageFileNameA(process_handle, image_name.as_mut_ptr() as *mut _, &mut image_name_size) == 0 {
            return None;
        }
    
        let mut class_name: [u16; 256] = [0; 256];
        GetClassNameW(foreground_window, class_name.as_mut_ptr(), 256);

        let mut process_name_str = OsString::from_wide(&process_name);
        let mut class_name_str = OsString::from_wide(&class_name);

        log::info!("Process Name: {}", process_name_str.to_string_lossy().to_string());
        log::info!("Class Name: {}", class_name_str.to_string_lossy().to_string());
    }
}


#[test]
fn test_screen_size() {
    let (width, height) = screen_size();
    assert!(width > 0);
    assert!(height > 0);
}
#[test]
fn test_get_window_rect() {
    let (x, y, width, height) = get_window_rect().unwrap();
    assert!(x >= 0);
    assert!(y >= 0);
    assert!(width > 0);
    assert!(height > 0);
}
#[test]
fn test_cursor_pos() {
    let (x, y) = cursor_pos();
    assert!(x >= 0);
    assert!(y >= 0);
}

#[test]
fn test_get_foredround_window_name() {
    env_logger::init();
    get_foredround_window_name();
}