use std::future;
use ratatui::{Frame, crossterm::event::Event};
use crate::navigation::Navigator;
pub trait ScreenState<S = ()>: Default {
type ID: Copy;
fn new(id: Self::ID) -> Self;
fn draw(&mut self, frame: &mut Frame, state: &S);
async fn on_event(&mut self, event: Event, navigator: Navigator<Self::ID>, state: &mut S);
async fn on_enter(&mut self, navigator: Navigator<Self::ID>, state: &mut S);
async fn on_exit(&mut self, navigator: Navigator<Self::ID>, state: &mut S);
async fn on_pause(&mut self, navigator: Navigator<Self::ID>, state: &mut S);
async fn on_resume(&mut self, navigator: Navigator<Self::ID>, state: &mut S);
async fn task(&mut self, navigator: Navigator<Self::ID>, state: &mut S);
}
pub trait Screen<ID>: Default {
fn draw(&mut self, frame: &mut Frame);
async fn on_event(&mut self, event: Event, navigator: Navigator<ID>) {}
async fn on_enter(&mut self, navigator: Navigator<ID>) {}
async fn on_exit(&mut self, navigator: Navigator<ID>) {}
async fn on_pause(&mut self, navigator: Navigator<ID>) {}
async fn on_resume(&mut self, navigator: Navigator<ID>) {}
async fn task(&mut self, navigator: Navigator<ID>) {
future::pending().await
}
}
pub trait ScreenWithState<ID, State> {
fn draw(&mut self, frame: &mut Frame, state: &State);
async fn on_event(&mut self, event: Event, navigator: Navigator<ID>, state: &mut State);
async fn on_enter(&mut self, navigator: Navigator<ID>, state: &mut State) {}
async fn on_exit(&mut self, navigator: Navigator<ID>, state: &mut State) {}
async fn on_pause(&mut self, navigator: Navigator<ID>, state: &mut State) {}
async fn on_resume(&mut self, navigator: Navigator<ID>, state: &mut State) {}
async fn task(&mut self, navigator: Navigator<ID>, state: &mut State) {
future::pending().await
}
}
impl<ID, T, S> ScreenWithState<ID, T> for S
where
S: Screen<ID>,
{
fn draw(&mut self, frame: &mut Frame, _state: &T) {
self.draw(frame);
}
async fn on_event(&mut self, event: Event, navigator: Navigator<ID>, _state: &mut T) {
self.on_event(event, navigator).await;
}
async fn on_enter(&mut self, navigator: Navigator<ID>, _state: &mut T) {
self.on_enter(navigator).await;
}
async fn on_exit(&mut self, navigator: Navigator<ID>, _state: &mut T) {
self.on_exit(navigator).await;
}
async fn on_pause(&mut self, navigator: Navigator<ID>, _state: &mut T) {
self.on_pause(navigator).await;
}
async fn on_resume(&mut self, navigator: Navigator<ID>, _state: &mut T) {
self.on_resume(navigator).await;
}
async fn task(&mut self, navigator: Navigator<ID>, _state: &mut T) {
self.task(navigator).await;
}
}