use crate::SomeResult;

use super::{base_object::BaseObject, wrapper::BaseObjectWrapper};

pub trait BasePtr {
    fn base_ptr(&self) -> SomeResult<altv_sdk::BaseObjectMutPtr>;
    fn raw_base_ptr(&self) -> SomeResult<altv_sdk::BaseObjectRawMutPtr>;
}

impl<T, InheritPtrs: Clone> BasePtr for BaseObject<T, InheritPtrs> {
    fn base_ptr(&self) -> SomeResult<altv_sdk::BaseObjectMutPtr> {
        self.base_ptr.ok_or(anyhow::anyhow!(
            "Base object is destroyed and cannot be used anymore (base_ptr is none)"
        ))
    }

    fn raw_base_ptr(&self) -> SomeResult<altv_sdk::BaseObjectRawMutPtr> {
        Ok(self.base_ptr()?.as_ptr())
    }
}

impl<T, InheritPtrs: Clone> BasePtr for BaseObjectWrapper<T, InheritPtrs> {
    fn base_ptr(&self) -> SomeResult<altv_sdk::BaseObjectMutPtr> {
        self.value.try_borrow()?.base_ptr()
    }

    fn raw_base_ptr(&self) -> SomeResult<altv_sdk::BaseObjectRawMutPtr> {
        self.value.try_borrow()?.raw_base_ptr()
    }
}
