use myth::prelude::*;

/// 带纹理的旋转立方体 + 轨道控制器
struct TexturedBox {
    controls: OrbitControls,
}

impl AppHandler for TexturedBox {
    fn init(engine: &mut Engine, _window: &dyn Window) -> Self {
        let image_handle = engine.assets.images.add(Image::checkerboard(512, 512, 64));
        let tex_handle = engine
            .assets
            .textures
            .add(Texture::new_2d(Some("checker"), image_handle));

        let scene = engine.scene_manager.create_active();

        // spawn + builder material
        let mat = UnlitMaterial::new(Vec4::ONE).with_map(tex_handle);
        let cube_node_id = scene.spawn_box(2.0, 2.0, 2.0, mat, &engine.assets);

        let cam_node_id = scene.add_camera(Camera::new_perspective(45.0, 1280.0 / 720.0, 0.1));
        scene
            .node(&cam_node_id)
            .set_position(0.0, 3.0, 10.0)
            .look_at(Vec3::ZERO);
        scene.active_camera = Some(cam_node_id);

        let controls = OrbitControls::new(Vec3::new(0.0, 3.0, 10.0), Vec3::ZERO);

        scene.on_update(move |scene, _input, _dt| {
            // 旋转立方体
            if let Some(node) = scene.get_node_mut(cube_node_id) {
                let rot_y = Quat::from_rotation_y(0.02);
                let rot_x = Quat::from_rotation_x(0.01);
                node.transform.rotation = node.transform.rotation * rot_y * rot_x;
            }
        });

        Self { controls }
    }

    fn update(&mut self, engine: &mut Engine, _window: &dyn Window, frame: &FrameState) {
        let scene = engine.scene_manager.active_scene_mut().unwrap();
        // 轨道控制器
        if let Some((transform, camera)) = scene.query_main_camera_bundle() {
            self.controls
                .update(transform, &engine.input, camera.fov(), frame.dt);
        }
    }
}

fn main() -> myth::Result<()> {
    env_logger::init();
    App::new().run::<TexturedBox>()
}
