//! Widgets that can be placed in Menu and MenuItem.

use crate::widget::menu::Menu;
use std::iter::once;

#[cfg(windows)]
#[derive(Clone)]
pub struct MenuItem<'a> {
    menu: windows_sys::Win32::UI::WindowsAndMessaging::HMENU,
    title: &'a str,
}
#[cfg(windows)]
impl<'a> MenuItem<'a> {
    pub fn new(title: &'a str) -> Self {
        use windows_sys::Win32::UI::WindowsAndMessaging::CreatePopupMenu;
        unsafe {
            let menu = CreatePopupMenu();
            Self { menu, title }
        }
    }

    pub fn add_menuitem(&self, item: MenuItem) {
        use windows_sys::Win32::UI::WindowsAndMessaging::*;
        unsafe {
            AppendMenuW(
                self.menu,
                MFT_STRING,
                item.get_menu() as usize,
                item.get_title()
                    .encode_utf16()
                    .chain(once(0))
                    .collect::<Vec<u16>>()
                    .as_mut_ptr(),
            );
        }
    }

    pub fn add_menu(&self, item: Menu) {
        use windows_sys::Win32::UI::WindowsAndMessaging::*;
        unsafe {
            AppendMenuW(
                self.menu,
                MF_POPUP | MFT_STRING,
                item.get_menu() as usize,
                item.get_title()
                    .encode_utf16()
                    .chain(once(0))
                    .collect::<Vec<u16>>()
                    .as_mut_ptr(),
            );
        }
    }

    pub fn add_separator(&self) {
        use windows_sys::Win32::UI::WindowsAndMessaging::*;
        unsafe {
            AppendMenuA(self.menu, MFT_SEPARATOR, 0, "\0".as_ptr());
        }
    }

    pub fn get_menu(&self) -> windows_sys::Win32::UI::WindowsAndMessaging::HMENU {
        self.menu
    }

    pub fn get_title(self) -> &'a str {
        self.title
    }
}

#[cfg(unix)]
#[derive(Clone)]
pub struct MenuItem<'a> {
    menu: gtk::gio::MenuItem,
    title: &'a str,
}

#[cfg(unix)]
impl<'a> MenuItem<'a> {
    pub fn new(title: &'a str) -> Self {
        use gtk::gio::MenuItem;
        let menu = MenuItem::new(Some(title), Some("win"));
        Self { menu, title }
    }

    pub fn add_menuitem(&self, item: MenuItem) {
        use gtk::prelude::*;
        //self.menu.set_submenu(Some(&item.get_menu()));
    }

    pub fn add_menu(&self, item: Menu) {
        use gtk::prelude::*;
        self.menu.set_submenu(Some(&item.get_menu()));
    }

    pub fn add_separator(&self) {
        use gtk::prelude::*;
        // self.menu.add(&gtk::SeparatorMenuItem::new());
    }

    pub fn get_menu(self) -> gtk::gio::MenuItem {
        self.menu
    }

    pub fn get_title(self) -> &'a str {
        self.title
    }
}
