//! Types related to the DOM events.

use std::sync::Arc;

use crate::dom::element::DomElement;
use crate::ComponentImports;

/// A DOM event.
#[derive(Clone)]
pub struct DomEvent {
    inner: Arc<DomEventInner>,
}
struct DomEventInner {
    event: i64,
    imports: &'static ComponentImports,
}
impl DomEvent {
    // PRIVATE: Used by the `handle_events_using_callback` macro.
    #[doc(hidden)]
    pub fn _private_new(event_handle: i64, imports: &'static ComponentImports) -> Self {
        Self {
            inner: Arc::new(DomEventInner {
                event: event_handle,
                imports,
            }),
        }
    }

    /// Get the event's target element.
    pub fn target(&self) -> Option<DomElement> {
        let element = unsafe {
            afia_component_sys::dom_event_target(
                self.inner.imports.component_imports_ptr,
                self.inner.event,
            )
        };

        DomElement::maybe_new(element, self.inner.imports.clone())
    }

    /// Prevent the browser's default handling of the event.
    pub fn prevent_default(&self) {
        unsafe {
            afia_component_sys::dom_event_prevent_default(
                self.inner.imports.component_imports_ptr,
                self.inner.event,
            )
        }
    }

    /// Will be deleted once we stop using it.
    pub fn temporary_way_to_get_i64(&self) -> i64 {
        self.inner.event
    }
}
impl Drop for DomEventInner {
    fn drop(&mut self) {
        // TODO: Call a function to free the `self.event`
    }
}
