use crate::model::Project;

pub fn euclidean_rhythm(pulses: usize, steps: usize, rotation: usize) -> Vec<bool> {
    if pulses == 0 || steps == 0 || pulses > steps {
        return vec![false; steps];
    }

    let mut pattern = vec![false; steps];
    for i in 0..pulses {
        let pos = (i * steps) / pulses;
        pattern[pos] = true;
    }

    if rotation > 0 {
        pattern.rotate_left(rotation % steps);
    }

    pattern
}

/// Applies euclidean distribution as linked steps from a source step.
/// Returns the indices of steps that were created (for compilation).
pub fn apply_distribution(
    project: &mut Project,
    bank: usize,
    pattern: usize,
    source_step: usize,
    pulses: usize,
    steps: usize,
    rotation: usize,
) -> Vec<usize> {
    let pat_len = project.pattern_at(bank, pattern).length;
    let rhythm = euclidean_rhythm(pulses, steps, rotation);

    let mut targets = Vec::new();
    for (i, &is_hit) in rhythm.iter().enumerate() {
        if !is_hit || i == 0 {
            continue;
        }

        let target = (source_step + i) % pat_len;
        if target == source_step {
            continue;
        }

        if let Some(step) = project.pattern_at_mut(bank, pattern).step_mut(target) {
            step.source = Some(source_step as u8);
            step.script.clear();
            step.active = true;
        }
        targets.push(target);
    }

    targets
}
