use freya_engine::prelude::{
    Canvas,
    FontCollection,
};
use freya_native_core::NodeId;
use torin::torin::Torin;
use winit::{
    event_loop::EventLoopProxy,
    window::Window,
};
use crate::{
    dom::FreyaDOM,
    prelude::{
        EventMessage,
        PlatformEvent,
    },
};
#[derive(Clone)]
pub struct PluginHandle {
    pub proxy: EventLoopProxy<EventMessage>,
}
impl PluginHandle {
    pub fn new(proxy: &EventLoopProxy<EventMessage>) -> Self {
        Self {
            proxy: proxy.clone(),
        }
    }
    pub fn send_platform_event(&self, event: PlatformEvent) {
        self.proxy
            .send_event(EventMessage::PlatformEvent(event))
            .ok();
    }
    pub fn send_event_loop_event(&self, event: EventMessage) {
        self.proxy.send_event(event).ok();
    }
}
#[derive(Default)]
pub struct PluginsManager {
    plugins: Vec<Box<dyn FreyaPlugin>>,
}
impl PluginsManager {
    pub fn add_plugin(&mut self, plugin: impl FreyaPlugin + 'static) {
        self.plugins.push(Box::new(plugin))
    }
    pub fn send(&mut self, event: PluginEvent, handle: PluginHandle) {
        for plugin in &mut self.plugins {
            plugin.on_event(&event, handle.clone())
        }
    }
}
pub enum PluginEvent<'a> {
    WindowCreated(&'a Window),
    BeforeRender {
        canvas: &'a Canvas,
        font_collection: &'a FontCollection,
        freya_dom: &'a FreyaDOM,
    },
    AfterRender {
        canvas: &'a Canvas,
        font_collection: &'a FontCollection,
        freya_dom: &'a FreyaDOM,
    },
    StartedLayout(&'a Torin<NodeId>),
    FinishedLayout(&'a Torin<NodeId>),
    StartedUpdatingDOM,
    FinishedUpdatingDOM,
}
pub trait FreyaPlugin {
    fn on_event(&mut self, event: &PluginEvent, handle: PluginHandle);
}