//! lua_fountain: a quad fountain driven entirely by fountain.lua (v0.2
//! step 13 milestone). Edit assets/scripts/fountain.lua while this runs;
//! it hot-reloads on save, no recompile.
//!
//! The Rust side is only plumbing: a movement system integrating the
//! script's Velocity into Transforms, and a render system recording Quads.
//! Every entity here is spawned, steered, and despawned by Lua, through
//! the same Command seam a TestHost proved in step 9.
//!
//! Run: RUST_LOG=info cargo run --features lua --example lua_fountain
//! (from the repo root, so assets/ resolves)

use mawida::content::ContentManager;
use mawida::script::lua_host::{LuaHost, Quad, Velocity};
use mawida::{
    App, AppConfig, OrthographicCamera, RenderQueue, Result, ScriptModule, Sprite, Transform,
    World,
};

/// Integrate the script's Velocity into Transforms: the step 7 movement
/// system, for the scripting API's velocity flavor.
fn movement(world: &mut World, dt: f32) {
    let (xforms, vels) = world.columns_mut::<Transform, Velocity>();
    for (t, v) in xforms.iter_mut().zip(vels.iter()) {
        if let (Some(t), Some(v)) = (t, v) {
            t.translation.x += v.x * dt;
            t.translation.y += v.y * dt;
        }
    }
}

/// Record every scripted Quad into the render queue (step 8's shape).
fn render_sprites(world: &mut World, _dt: f32) {
    let camera = *world.resource::<OrthographicCamera>();
    let mut frame = Vec::new();
    let (xforms, quads) = world.columns_mut::<Transform, Quad>();
    for (t, q) in xforms.iter().zip(quads.iter()) {
        if let (Some(t), Some(q)) = (t, q) {
            let s = Sprite::solid(q.color, t.translation.x, t.translation.y, q.w, q.h);
            frame.push((s, camera));
        }
    }
    world.resource_mut::<RenderQueue>().sprites = frame;
}

fn main() -> Result<()> {
    let content = ContentManager::with_root("assets");
    let host = LuaHost::new(&content, "scripts/fountain.lua")?;

    App::new(AppConfig {
        title: "Mawida - lua fountain (edit the script live!)".to_string(),
        ..Default::default()
    })
    .add_module(ScriptModule::new(host))
    .add_system(movement)
    .add_system(render_sprites)
    .run()
}
