use super::SkillCurve;
use crate::{comparison, timing::Snapshot, Run, Segment, TimeSpan, TimingMethod};
#[cfg(test)]
mod tests;
fn calculate(segments: &[Segment], method: TimingMethod, offset: TimeSpan) -> f64 {
if segments
.last()
.and_then(|s| s.personal_best_split_time()[method])
.is_none()
{
return 1.0;
}
comparison::goal::determine_percentile(offset, segments, method, None, &mut SkillCurve::new())
}
pub fn for_run(run: &Run, method: TimingMethod) -> f64 {
calculate(run.segments(), method, TimeSpan::zero())
}
pub fn for_timer(timer: &Snapshot<'_>) -> (f64, bool) {
let method = timer.current_timing_method();
let all_segments = timer.run().segments();
let is_live =
super::check_live_delta(timer, false, comparison::personal_best::NAME, method).is_some();
let (segments, current_time) = if is_live {
(
&all_segments[timer.current_split_index().unwrap() + 1..],
timer.current_time()[method].unwrap_or_default(),
)
} else if let Some((index, time)) = all_segments
.iter()
.enumerate()
.rev()
.find_map(|(i, s)| Some((i, s.split_time()[method]?)))
{
(&all_segments[index + 1..], time)
} else {
(all_segments, TimeSpan::zero())
};
let chance = if segments.is_empty() {
let beat_pb = all_segments
.last()
.and_then(|s| s.personal_best_split_time()[method])
.map_or(true, |pb| current_time < pb);
if beat_pb {
1.0
} else {
0.0
}
} else {
calculate(segments, method, current_time)
};
(chance, is_live && timer.current_phase().is_running())
}