use gtk::{glib, prelude::*, subclass::prelude::*};

use crate::{
    systemd::{data::UnitInfo, errors::SystemdErrors},
    widget::InterPanelMessage,
};
use base::enums::UnitDBusLevel;

use super::UnitControlPanel;

mod imp;

glib::wrapper! {
    pub struct SideControlPanel(ObjectSubclass<imp::SideControlPanelImpl>)
    @extends gtk::Box, gtk::Widget,
    @implements gtk::Accessible, gtk::Buildable, gtk::ConstraintTarget, gtk::Orientable;
}

impl SideControlPanel {
    pub fn new(unit_control_panel: &UnitControlPanel) -> Self {
        let obj: SideControlPanel = glib::Object::new();
        obj.imp().init(unit_control_panel);
        obj
    }

    pub fn unlink_child(&self, is_signal: bool) {
        self.imp().unlink_child(is_signal);
    }

    pub fn set_inter_message(&self, action: &InterPanelMessage) {
        self.imp().set_inter_message(action);
    }

    pub fn add_toast_message(&self, message: &str, use_markup: bool) {
        if let Some(parent) = self.imp().control_panel() {
            parent.add_toast_message(message, use_markup);
        }
    }

    pub fn call_method(
        &self,
        method_name: &str,
        need_selected_unit: bool,
        button: &impl IsA<gtk::Widget>,
        systemd_method: impl Fn(Option<(UnitDBusLevel, String)>) -> Result<(), SystemdErrors>
        + std::marker::Send
        + 'static,
        return_handle: impl Fn(&str, Option<&UnitInfo>, Result<(), SystemdErrors>, &UnitControlPanel)
        + 'static,
    ) {
        if let Some(parent) = self.imp().control_panel() {
            parent.call_method(
                method_name,
                need_selected_unit,
                button,
                systemd_method,
                return_handle,
            );
        }
    }

    pub fn more_action_popover_shown(&self) {
        self.imp().more_action_popover_shown();
    }
}
