use bevy::{
    ecs::schedule::StageLabel,
    prelude::{ResMut, SystemLabel, Vec3, Windows},
};

pub mod action;
pub mod bike;
pub mod camera;
pub mod glamor;
pub mod input;
pub mod lights;
pub mod planet;
pub mod ui;

#[derive(Clone, Debug, Hash, PartialEq, Eq, SystemLabel, StageLabel)]
pub enum Label {
    Geometry,
    Glamor,
    Input,
    Action,
}

pub fn disable_mouse_trap(mut windows: ResMut<Windows>) {
    let window = windows.get_primary_mut().unwrap();
    window.set_cursor_grab_mode(bevy::window::CursorGrabMode::None);
    window.set_cursor_visibility(true);
}

pub fn random_unit_vec(r: &mut impl rand::prelude::Rng) -> Vec3 {
    // https://mathworld.wolfram.com/SpherePointPicking.html
    // Marsaglia (1972) for picking x1 and x2 from (-1, 1) and generating surface
    // points directly if their sum is less than 1.

    let mut x1: f32 = 0.0;
    let mut x2: f32 = 0.0;
    let mut ssum = std::f32::MAX;
    while ssum >= 1.0 {
        x1 = r.gen_range(-1.0..=1.0);
        x2 = r.gen_range(-1.0..=1.0);
        ssum = x1.powi(2) + x2.powi(2);
    }
    let sqrt = (1.0 - ssum).sqrt();
    let x = 2.0 * x1 * sqrt;
    let y = 2.0 * x2 * sqrt;
    let z = 1.0 - 2.0 * ssum;
    Vec3::new(x, y, z).normalize()
}
