use tracing_subscriber::EnvFilter;
use winit::{
    event::{Event, WindowEvent},
    event_loop::EventLoop,
    window::WindowBuilder,
};

mod graphics;

fn main() -> color_eyre::Result<()> {
    tracing_subscriber::fmt()
        .pretty()
        .with_env_filter(EnvFilter::from_default_env())
        .init();
    color_eyre::install()?;

    let event_loop = EventLoop::new()?;
    let mut context = graphics::Context::default();

    event_loop.run(move |event, target| {
        if let Event::WindowEvent {
            window_id: _,
            event,
        } = event
        {
            match event {
                WindowEvent::Resized(new_size) => {
                    context.resize(new_size);
                    context.on_window(|window| {
                        window.request_redraw();
                    });
                }
                WindowEvent::CloseRequested => {
                    target.exit();
                }
                WindowEvent::RedrawRequested => match context.render() {
                    Err(wgpu::SurfaceError::OutOfMemory) => {
                        target.exit();
                    }
                    Err(wgpu::SurfaceError::Lost) => {
                        if let Some(size) = context.on_window(|win| win.inner_size()) {
                            context.resize(size);
                        }
                    }
                    Ok(()) => {}
                    Err(e) => {
                        tracing::error!("Surface error: {e}");
                    }
                },
                _ => {}
            }
        } else {
            match event {
                Event::Resumed => {
                    let window = WindowBuilder::new()
                        .with_title("Rexi Pixel Editor")
                        .build(target)
                        .expect("Failed to create window");
                    pollster::block_on(context.initialize(window))
                        .expect("Failed to resume window");
                }
                Event::LoopExiting => {
                    tracing::warn!("Exiting!");
                }
                _ => {}
            }
        }
    })?;
    Ok(())
}