//! Buttons.

use crate::graphic::font::Font;
use crate::messagebox::MessageBox;
use crate::natives_and_messaging::*;
use crate::window::{Attributes, Frame};

#[cfg(windows)]
pub struct Button {
    pub handle: windows_sys::Win32::Foundation::HWND,
}

#[cfg(windows)]
impl Button {
    pub fn new(attributes: Attributes, frame: &Frame) -> Self {
        use windows_sys::Win32::UI::WindowsAndMessaging::*;
        use windows_sys::Win32::Foundation::WPARAM;
        use windows_sys::Win32::Graphics::Gdi::OUT_DEFAULT_PRECIS;
        use windows_sys::Win32::Graphics::Gdi::{CLIP_DEFAULT_PRECIS, CreateFontA, DEFAULT_QUALITY, FF_ROMAN, FW_NORMAL, HFONT, SHIFTJIS_CHARSET, VARIABLE_PITCH};

        unsafe {
            let handle = CreateWindowExA(
                0,
                "BUTTON\0".as_ptr(),
                format!("{}\0", attributes.title).as_ptr(),
                WS_CHILD,
                attributes.x,
                attributes.y,
                attributes.width,
                attributes.height,
                frame.get_window(),
                0,
                0,
                std::ptr::null_mut(),
            );
            if handle == 0 {
                match MessageBox::new("NXUI Warning", "NXUI Warning - Code 0002\rWidget could not be initialized\rRunning it as is may disrupt the UI\rPress Yes to continue program execution\r \rDetailed information:\rPanicked at nxui::widget::button\rTo resolve this error, contact the application developer or\rPlease report at https://github.com/LatteSyobon/nxui/issues", DS_WARNING, BS_YESNO).show(Frame::default())
                {
                    DR_NO => {
                        panic!("Exit request from user");
                    }
                    _ => {}
                };
            }
            SendMessageA(handle, WM_SETFONT, CreateFontA(26, 0, 0, 0, FW_NORMAL as i32, 0, 0, 0, SHIFTJIS_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, VARIABLE_PITCH | FF_ROMAN, "Yu Gothic".as_ptr()) as WPARAM, 1);
            info!("Button has been created. handle: {}", handle);
            Self { handle }
        }
    }

    pub fn set_font(&self,font: Font) {
        use windows_sys::Win32::Foundation::WPARAM;
        use windows_sys::Win32::Graphics::Gdi::OUT_DEFAULT_PRECIS;
        use windows_sys::Win32::Graphics::Gdi::{CLIP_DEFAULT_PRECIS, CreateFontA, DEFAULT_QUALITY, FF_ROMAN, FW_NORMAL, HFONT, SHIFTJIS_CHARSET, VARIABLE_PITCH};
        use windows_sys::Win32::UI::WindowsAndMessaging::*;
        unsafe {
            SendMessageA(self.handle, WM_SETFONT, font.get_font() as WPARAM, 1);
        }
    }

    pub fn get_widget(&self) -> windows_sys::Win32::Foundation::HWND {
        self.handle
    }

    pub fn show(&self) {
        use windows_sys::Win32::UI::WindowsAndMessaging::ShowWindow;
        use windows_sys::Win32::UI::WindowsAndMessaging::SW_SHOWNORMAL;
        unsafe {
            ShowWindow(self.handle, SW_SHOWNORMAL);
            info!("handle: {}", self.handle);
        }
    }
}

#[cfg(unix)]
pub struct Button {
    pub handle: gtk::Button,
}

#[cfg(unix)]
impl Button {
    pub fn new(attributes: Attributes, frame: &Frame) -> Self {
        use gtk::prelude::*;
        let handle = gtk::Button::with_label(&*attributes.title);
        handle.set_height_request(attributes.height / 10);
        handle.set_width_request(attributes.width / 10);
        handle.set_margin_top(attributes.y);
        handle.set_margin_start(attributes.x);
        frame.get_window().add(&handle);
        Self { handle }
    }

    pub fn show(&self) {
        use gtk::prelude::*;
        self.handle.show();
    }
}
