// Fragments - folder_page.rs
// Copyright (C) 2023  Felix Häcker <haeckerfelix@gnome.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

use std::cell::{Cell, OnceCell};

use adw::prelude::*;
use adw::subclass::prelude::*;
use glib::Properties;
use gtk::glib;
use transmission_gobject::TrFile;

use super::FrgFolderPageContents;
use crate::model::FrgFileSorter;

mod imp {
    use super::*;

    #[derive(Debug, Default, Properties)]
    #[properties(wrapper_type = super::FrgFolderPage)]
    pub struct FrgFolderPage {
        #[property(get, set, construct_only)]
        file: OnceCell<TrFile>,
        #[property(get, set, construct_only)]
        sorter: OnceCell<FrgFileSorter>,

        scroll_pos: Cell<f64>,
    }

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

    #[glib::derived_properties]
    impl ObjectImpl for FrgFolderPage {
        fn constructed(&self) {
            self.parent_constructed();

            let title = self.obj().file().title();
            self.obj().set_title(&title);
        }
    }

    impl WidgetImpl for FrgFolderPage {}

    impl NavigationPageImpl for FrgFolderPage {
        fn showing(&self) {
            let obj = self.obj();

            let contents =
                FrgFolderPageContents::new(&obj.file(), &obj.sorter(), self.scroll_pos.get());
            obj.set_child(Some(&contents));
        }

        fn hidden(&self) {
            let contents = self
                .obj()
                .child()
                .and_downcast::<FrgFolderPageContents>()
                .unwrap();
            self.scroll_pos.set(contents.scroll_pos());

            self.obj().set_child(gtk::Widget::NONE);
        }
    }
}

glib::wrapper! {
    pub struct FrgFolderPage(ObjectSubclass<imp::FrgFolderPage>)
        @extends gtk::Widget, adw::NavigationPage;
}

impl FrgFolderPage {
    pub fn new(file: &TrFile, sorter: &FrgFileSorter) -> Self {
        glib::Object::builder()
            .property("file", file)
            .property("sorter", sorter)
            .build()
    }
}
