//! ecs_assets: the ECS door reaches asset parity (items 4, 6, 7).
//!
//! Everything here goes through the App builder - no Game trait: a texture
//! built and uploaded in `load_with`, the built-in font as a World resource
//! drawn by the engine's `render_text` system through a `Text` component,
//! and a beep played from a FILE (cached by the AudioModule) every time you
//! press Space.
//!
//! Run: cargo run --example ecs_assets   (from the repo root)

use mawida::{
    App, AppConfig, AudioModule, Color, InputState, Key, MonoFont, OrthographicCamera,
    PlaySoundFile, RenderQueue, Result, Sprite, Text, Transform, World,
};

/// A game-side component, as always: the engine never sees its type.
struct Tile {
    tex: mawida::TextureId,
    size: f32,
}

fn render_tiles(world: &mut World, _dt: f32) {
    let camera = *world.resource::<OrthographicCamera>();
    let mut frame = Vec::new();
    let (xforms, tiles) = world.columns_mut::<Transform, Tile>();
    for (t, tile) in xforms.iter().zip(tiles.iter()) {
        if let (Some(t), Some(tile)) = (t, tile) {
            frame.push((
                Sprite::new(tile.tex, t.translation.x, t.translation.y, tile.size, tile.size),
                camera,
            ));
        }
    }
    world.resource_mut::<RenderQueue>().sprites = frame;
}

/// Space -> spawn a PlaySoundFile request. The AudioModule drains it,
/// reads + caches assets/sounds/beep.wav once, and plays it.
fn beep_on_space(world: &mut World, _dt: f32) {
    let pressed = world.resource::<InputState>().just_pressed(Key::Space);
    if pressed {
        let e = world.spawn();
        world.insert(e, PlaySoundFile("sounds/beep.wav".to_string()));
    }
}

fn main() -> Result<()> {
    App::new(AppConfig {
        title: "Mawida - ecs_assets (assets, text, sound in the ECS door)".to_string(),
        ..Default::default()
    })
    .content_root("assets")
    .add_module(AudioModule::with_root("assets"))
    // item 4: assets load with the GPU up, handles land where you put them
    .load_with(|assets, world| {
        // a procedural checker texture, registered AND uploaded in one call
        let mut rgba = Vec::with_capacity(16 * 16 * 4);
        for y in 0..16u32 {
            for x in 0..16u32 {
                let on = (x / 4 + y / 4) % 2 == 0;
                rgba.extend_from_slice(if on {
                    &[90, 170, 255, 255]
                } else {
                    &[25, 40, 70, 255]
                });
            }
        }
        let tex = assets.insert_texture(16, 16, rgba);
        // the built-in font becomes a World resource for render_text
        if let Ok(font) = assets.builtin_font() {
            world.insert_resource::<MonoFont>(font);
        }

        // spawn straight from the loader: handles are just data
        for i in 0..5 {
            let e = world.spawn();
            world.insert(e, Transform::from_xy(80.0 + i as f32 * 130.0, 260.0));
            world.insert(e, Tile { tex, size: 96.0 });
        }
        // item 6: text as an entity
        let label = world.spawn();
        world.insert(label, Transform::from_xy(16.0, 16.0));
        world.insert(
            label,
            Text { content: "MAWIDA ECS DOOR\nSPACE = BEEP (FROM FILE)".to_string(), scale: 3.0, color: Color::WHITE },
        );
    })
    .add_system(beep_on_space)
    .add_system(render_tiles)
    .add_system(mawida::render_text) // AFTER the sprite system: it extends
    .run()
}
