use crate::window::Instruction;
use strafesnet_common::integer;
use strafesnet_common::instruction::TimedInstruction;
use strafesnet_common::session::Time as SessionTime;

pub struct App<'a>{
	root_time:std::time::Instant,
	window_thread:crate::compat_worker::QNWorker<'a,TimedInstruction<Instruction,SessionTime>>,
}
impl<'a> App<'a>{
	pub fn new(
		root_time:std::time::Instant,
		window_thread:crate::compat_worker::QNWorker<'a,TimedInstruction<Instruction,SessionTime>>,
	)->App<'a>{
		Self{
			root_time,
			window_thread,
		}
	}
	fn send_timed_instruction(&mut self,instruction:Instruction){
		let time=integer::Time::from_nanos(self.root_time.elapsed().as_nanos() as i64);
		self.window_thread.send(TimedInstruction{time,instruction}).unwrap();
	}
}
impl winit::application::ApplicationHandler for App<'_>{
	fn resumed(&mut self,_event_loop:&winit::event_loop::ActiveEventLoop){
		//
	}

	fn window_event(
		&mut self,
		event_loop:&winit::event_loop::ActiveEventLoop,
		_window_id:winit::window::WindowId,
		event:winit::event::WindowEvent,
	){
		match event{
			winit::event::WindowEvent::KeyboardInput{
				event:winit::event::KeyEvent{
					logical_key:winit::keyboard::Key::Named(winit::keyboard::NamedKey::Escape),
					state:winit::event::ElementState::Pressed,
					..
				},
				..
			}
			|winit::event::WindowEvent::CloseRequested=>{
				event_loop.exit();
			},
			_=>(),
		}
		self.send_timed_instruction(Instruction::WindowEvent(event));
	}

	fn device_event(
		&mut self,
		_event_loop:&winit::event_loop::ActiveEventLoop,
		_device_id:winit::event::DeviceId,
		event:winit::event::DeviceEvent,
	){
		self.send_timed_instruction(Instruction::DeviceEvent(event));
	}

	fn about_to_wait(
		&mut self,
		_event_loop:&winit::event_loop::ActiveEventLoop
	){
		self.send_timed_instruction(Instruction::WindowEvent(winit::event::WindowEvent::RedrawRequested));
	}
}
