#![allow(dead_code)]
use core::f32;
use glam::{Mat2, Mat3, Mat3A, Mat4, Quat, Vec2, Vec3, Vec3A, Vec4};

pub struct PCG32 {
    state: u64,
    inc: u64,
}

impl Default for PCG32 {
    fn default() -> Self {
        PCG32::seed(0x853c49e6748fea9b, 0xda3e39cb94b95bdb)
    }
}

impl PCG32 {
    pub fn seed(initstate: u64, initseq: u64) -> Self {
        let mut rng = PCG32 {
            state: 0,
            inc: (initseq << 1) | 1,
        };
        rng.next_u32();
        rng.state = rng.state.wrapping_add(initstate);
        rng.next_u32();
        rng
    }

    pub fn next_u32(&mut self) -> u32 {
        let oldstate = self.state;
        self.state = oldstate
            .wrapping_mul(6364136223846793005)
            .wrapping_add(self.inc | 1);
        let xorshifted = ((oldstate >> 18) ^ oldstate) >> 27;
        let rot = oldstate >> 59;
        ((xorshifted >> rot) | (xorshifted << (rot.wrapping_neg() & 31))) as u32
    }

    pub fn next_f32(&mut self) -> f32 {
        (self.next_u32() & 0xffffff) as f32 / 16777216.0
    }
}

pub fn random_vec2(rng: &mut PCG32) -> Vec2 {
    Vec2::new(rng.next_f32(), rng.next_f32())
}

pub fn random_vec3(rng: &mut PCG32) -> Vec3 {
    Vec3::new(rng.next_f32(), rng.next_f32(), rng.next_f32())
}

pub fn random_vec3a(rng: &mut PCG32) -> Vec3A {
    Vec3A::new(rng.next_f32(), rng.next_f32(), rng.next_f32())
}

pub fn random_vec4(rng: &mut PCG32) -> Vec4 {
    Vec4::new(
        rng.next_f32(),
        rng.next_f32(),
        rng.next_f32(),
        rng.next_f32(),
    )
}

pub fn random_nonzero_vec2(rng: &mut PCG32) -> Vec2 {
    loop {
        let v = random_vec2(rng);
        if v.length_squared() > 0.01 {
            return v;
        }
    }
}

pub fn random_nonzero_vec3(rng: &mut PCG32) -> Vec3 {
    loop {
        let v = random_vec3(rng);
        if v.length_squared() > 0.01 {
            return v;
        }
    }
}

pub fn random_f32(rng: &mut PCG32) -> f32 {
    rng.next_f32()
}

pub fn random_radians(rng: &mut PCG32) -> f32 {
    -f32::consts::PI + rng.next_f32() * 2.0 * f32::consts::PI
}

pub fn random_quat(rng: &mut PCG32) -> Quat {
    let yaw = random_radians(rng);
    let pitch = random_radians(rng);
    let roll = random_radians(rng);
    Quat::from_euler(glam::EulerRot::YXZ, yaw, pitch, roll)
}

pub fn random_mat2(rng: &mut PCG32) -> Mat2 {
    Mat2::from_cols(random_vec2(rng), random_vec2(rng))
}

pub fn random_mat3(rng: &mut PCG32) -> Mat3 {
    Mat3::from_cols(random_vec3(rng), random_vec3(rng), random_vec3(rng))
}

pub fn random_srt_mat3(rng: &mut PCG32) -> Mat3 {
    Mat3::from_scale_angle_translation(
        random_nonzero_vec2(rng),
        random_radians(rng),
        random_vec2(rng),
    )
}

pub fn random_mat3a(rng: &mut PCG32) -> Mat3A {
    Mat3A::from_cols(random_vec3a(rng), random_vec3a(rng), random_vec3a(rng))
}

pub fn random_srt_mat3a(rng: &mut PCG32) -> Mat3A {
    Mat3A::from_scale_angle_translation(
        random_nonzero_vec2(rng),
        random_radians(rng),
        random_vec2(rng),
    )
}

pub fn random_srt_mat4(rng: &mut PCG32) -> Mat4 {
    Mat4::from_scale_rotation_translation(
        random_nonzero_vec3(rng),
        random_quat(rng),
        random_vec3(rng),
    )
}
