// SPDX-License-Identifier: MIT

mod imp {
    use adw::glib;
    use adw::prelude::*;
    use adw::subclass::prelude::*;
    use adw::Application;

    use crate::startup_disk::startup_disk_library;
    use crate::window::StartupDiskWindow;

    #[derive(Default)]
    pub struct StartupDiskApplication;

    #[glib::object_subclass]
    impl ObjectSubclass for StartupDiskApplication {
        const NAME: &'static str = "StartupDiskApplication";
        type Type = super::StartupDiskApplication;
        type ParentType = Application;
    }

    impl ObjectImpl for StartupDiskApplication {
        fn constructed(&self) {
            self.parent_constructed();
            self.obj().setup_actions();
        }
    }

    impl ApplicationImpl for StartupDiskApplication {
        fn activate(&self) {
            let app = self.obj();

            let startup_disk_library = startup_disk_library();
            if let Some(window) = app.active_window() {
                window.present();
            } else {
                /* We start hidden to avoid confusing the using during the
                privilege escalation */
                StartupDiskWindow::new(&*app, startup_disk_library.is_supported());
            }
        }
    }

    impl GtkApplicationImpl for StartupDiskApplication {}
    impl AdwApplicationImpl for StartupDiskApplication {}
}

use adw::gio::{self, ActionEntry, ActionGroup, ActionMap};
use adw::glib;
use adw::gtk;
use adw::prelude::*;
use adw::{AboutDialog, Application};

use crate::config;

glib::wrapper! {
    pub struct StartupDiskApplication(ObjectSubclass<imp::StartupDiskApplication>)
        @extends Application, gtk::Application, gio::Application,
        @implements ActionGroup, ActionMap;
}

impl StartupDiskApplication {
    pub fn new() -> Self {
        glib::Object::builder()
            .property("application-id", config::APP_ID)
            .property("resource-base-path", config::RESOURCE_BASE)
            .build()
    }

    fn setup_actions(&self) {
        // About window action
        let about_action = ActionEntry::builder("about")
            .activate(move |app: &Self, _, _| app.show_about())
            .build();
        self.add_action_entries([about_action]);

        // Keyboard shortcuts
        self.set_accels_for_action("app.quit", &["<primary>q"]);
        self.set_accels_for_action("window.close", &["<primary>w"]);
    }

    fn show_about(&self) {
        let about_dialog = AboutDialog::from_appdata(
            &format!("{}/{}.metainfo.xml", config::RESOURCE_BASE, config::APP_ID),
            Some(config::APP_VERSION),
        );

        about_dialog.present(self.active_window().as_ref());
    }
}

impl Default for StartupDiskApplication {
    fn default() -> Self {
        Self::new()
    }
}
