use std::error::Error;

use ruin_ui::{Color, Rect, SceneSnapshot, UiSize, WindowSpec};
use ruin_ui_platform_wayland::WaylandWindow;
use ruin_ui_renderer_wgpu::{RenderError, WgpuSceneRenderer};

fn build_demo_scene() -> SceneSnapshot {
    let mut scene = SceneSnapshot::new(1, UiSize::new(800.0, 500.0));
    scene.push_quad(
        Rect::new(0.0, 0.0, 800.0, 500.0),
        Color::rgb(0x10, 0x14, 0x24),
    );
    scene.push_quad(
        Rect::new(32.0, 32.0, 736.0, 72.0),
        Color::rgb(0x2D, 0x3E, 0x68),
    );
    scene.push_quad(
        Rect::new(32.0, 136.0, 352.0, 300.0),
        Color::rgb(0x6A, 0x3D, 0x3D),
    );
    scene.push_quad(
        Rect::new(416.0, 136.0, 352.0, 300.0),
        Color::rgb(0x3A, 0x5E, 0x49),
    );
    scene
}

fn main() -> Result<(), Box<dyn Error>> {
    let scene = build_demo_scene();
    let mut window = WaylandWindow::open(
        WindowSpec::new("RUIN Wayland / wgpu demo")
            .app_id("dev.ruin.prototype")
            .requested_inner_size(scene.logical_size),
    )?;
    let mut renderer = WgpuSceneRenderer::new(
        window.surface_target(),
        scene.logical_size.width as u32,
        scene.logical_size.height as u32,
        ruin_ui::Color::rgb(0x08, 0x0C, 0x14),
    )?;

    println!("Opening RUIN Wayland / wgpu demo window...");
    while window.is_running() {
        window.dispatch()?;
        if let Some(frame) = window.prepare_frame() {
            if frame.resized {
                renderer.resize(frame.width, frame.height);
            }
            match renderer.render(&scene) {
                Ok(()) => {}
                Err(RenderError::Lost | RenderError::Outdated) => {
                    renderer.resize(frame.width, frame.height);
                    window.request_redraw();
                }
                Err(RenderError::Timeout | RenderError::Occluded | RenderError::Validation) => {
                    window.request_redraw();
                }
            }
        }
    }

    Ok(())
}
