mod app_page;
mod keybind_row;
mod keybinding_editor;
mod share_page;
mod shortcuts_page;
mod theme_tile;
mod views_page;

use self::{
    app_page::SettingsAppPage, share_page::SettingsSharePage, shortcuts_page::SettingsShortcutsPage,
    views_page::SettingsViewsPage,
};
use crate::{app::App, content_page::ContentPage, i18n::i18n};

use glib::{Object, prelude::*, subclass::*};
use gtk4::{Accessible, Buildable, CompositeTemplate, ConstraintTarget, Widget};
use libadwaita::{Dialog, PreferencesDialog, subclass::prelude::*};

mod imp {
    use super::*;

    #[derive(Debug, Default, CompositeTemplate)]
    #[template(file = "data/resources/ui_templates/settings/dialog.blp")]
    pub struct SettingsDialog {}

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

        fn class_init(klass: &mut Self::Class) {
            SettingsViewsPage::ensure_type();
            SettingsAppPage::ensure_type();
            SettingsShortcutsPage::ensure_type();
            SettingsSharePage::ensure_type();

            klass.bind_template();
            klass.bind_template_callbacks();
        }

        fn instance_init(obj: &InitializingObject<Self>) {
            obj.init_template();
        }
    }

    impl ObjectImpl for SettingsDialog {}

    impl WidgetImpl for SettingsDialog {}

    impl AdwDialogImpl for SettingsDialog {}

    impl PreferencesDialogImpl for SettingsDialog {}

    #[gtk4::template_callbacks]
    impl SettingsDialog {
        #[template_callback]
        fn on_closed(&self) {
            if let Err(error) = App::default().settings().write() {
                ContentPage::instance().simple_message(&i18n(&format!("Failed to write settings file: {error}")));
            }
        }
    }
}

glib::wrapper! {
    pub struct SettingsDialog(ObjectSubclass<imp::SettingsDialog>)
        @extends Widget, Dialog, PreferencesDialog,
        @implements Accessible, Buildable, ConstraintTarget;
}

impl Default for SettingsDialog {
    fn default() -> Self {
        Object::new::<Self>()
    }
}
