use adw::subclass::bin::BinImpl;
use glib::Properties;
use gtk::glib::prelude::*;
use gtk::prelude::*;
use gtk::subclass::prelude::*;
use std::cell::{Cell, RefCell};
use std::num::NonZeroU32;

#[derive(Properties)]
#[properties(wrapper_type = super::DynamicCol)]
pub struct DynamicCol {
    #[property(get, set)]
    pub(super) child: RefCell<Option<gtk::Paned>>,
    pub(super) ratio: RefCell<Option<f64>>,
    width: Cell<i32>,
    pub(super) start_width: Cell<Option<i32>>,
    pub(super) end_width: Cell<Option<i32>>,
}

impl Default for DynamicCol {
    fn default() -> Self {
        Self {
            child: RefCell::new(None),
            ratio: RefCell::new(None),
            width: Cell::new(0),
            start_width: Cell::new(None),
            end_width: Cell::new(None),
        }
    }
}

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

impl ObjectImpl for DynamicCol {

    fn constructed(&self) {
        self.parent_constructed();
    }

    fn dispose(&self) {
        if let Some(child) = self.child.borrow_mut().take() {
            child.unparent();
        }
    }
}

impl WidgetImpl for DynamicCol {
    fn measure(&self, orientation: gtk::Orientation, for_size: i32) -> (i32, i32, i32, i32) {
        let widget = self.obj();
        let child = self.child.borrow();
        let child = match child.as_ref() {
            Some(child) => child,
            None => return (0, 0, -1, -1),
        };

        child.measure(orientation, for_size)
    }

    fn size_allocate(&self, width: i32, height: i32, baseline: i32) {
        let widget = self.obj();
        let child = self.child.borrow();

        let child = match child.as_ref() {
            Some(child) => child,
            None => return,
        };
        child.size_allocate(&gtk::Allocation::new(0, 0, width, height), baseline);

        let ratio = self.ratio.borrow();

        let position = if let Some(ratio) = *ratio {
             (width as f64 * ratio) as i32
        } else {
             self.start_width.get().or(Some(width - self.end_width.get().unwrap())).unwrap()
        };

        child.set_position(position);

    }
}
