use hefesto_widgets::{BorderType, PopupSize};

#[derive(Clone, Default)]
pub struct PopupConfig {
    pub width: Option<u16>,
    pub height: Option<u16>,
    pub border_type: Option<BorderType>,
    pub header: bool,
}

impl PopupConfig {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn width(mut self, w: u16) -> Self {
        self.width = Some(w);
        self
    }

    pub fn height(mut self, h: u16) -> Self {
        self.height = Some(h);
        self
    }

    pub fn border_type(mut self, bt: BorderType) -> Self {
        self.border_type = Some(bt);
        self
    }

    pub fn header(mut self) -> Self {
        self.header = true;
        self
    }
}

pub trait PopupConfigurable<'a>: Sized {
    fn with_config(self, config: &PopupConfig) -> Self;
}

macro_rules! impl_configurable {
    ($ty:ty) => {
        impl<'a> PopupConfigurable<'a> for $ty {
            fn with_config(self, config: &PopupConfig) -> Self {
                let mut s = self;
                if let Some(w) = config.width {
                    s = s.width(PopupSize::Fixed(w));
                }
                if let Some(h) = config.height {
                    s = s.height(PopupSize::Fixed(h));
                }
                if let Some(bt) = config.border_type {
                    s = s.border_type(bt);
                }
                if config.header {
                    s = s.header();
                }
                s
            }
        }
    };
}

impl_configurable!(hefesto_widgets::ChoosePopup<'_>);
impl_configurable!(hefesto_widgets::ThemedConfirmationPopup<'_>);
impl_configurable!(hefesto_widgets::SpinPopup<'_>);
impl_configurable!(hefesto_widgets::TextInputPopup<'_>);
impl_configurable!(hefesto_widgets::TreePopup<'_>);

impl<'a> PopupConfigurable<'a> for hefesto_widgets::FileBrowserPopup {
    fn with_config(self, config: &PopupConfig) -> Self {
        let mut s = self;
        if let Some(w) = config.width { s = s.width(PopupSize::Fixed(w)); }
        if let Some(bt) = config.border_type { s = s.border_type(bt); }
        s
    }
}
