use crate::{analysis::SkillCurve, Segment, Time, TimeSpan, TimingMethod};
pub const NAME: &str = "Goal";
pub(crate) fn determine_percentile(
offset: TimeSpan,
segments: &[Segment],
method: TimingMethod,
goal_time: Option<TimeSpan>,
skill_curve: &mut SkillCurve,
) -> f64 {
skill_curve.for_segments(segments, method);
let goal_time = if let Some(goal_time) = goal_time {
goal_time
} else {
let (new_len, goal_time) = segments[..skill_curve.len()]
.iter()
.enumerate()
.rev()
.find_map(|(i, s)| s.personal_best_split_time()[method].map(|t| (i + 1, t)))
.unwrap_or_default();
skill_curve.truncate(new_len);
goal_time
};
skill_curve.find_percentile_for_time(offset, goal_time)
}
pub(super) fn generate_for_timing_method_with_buf(
segments: &mut [Segment],
method: TimingMethod,
goal_time: Option<TimeSpan>,
comparison: &str,
skill_curve: &mut SkillCurve,
) {
let percentile =
determine_percentile(TimeSpan::zero(), segments, method, goal_time, skill_curve);
let mut segments = segments.iter_mut();
for (segment, val) in segments
.by_ref()
.zip(skill_curve.iter_split_times_at_percentile(percentile, TimeSpan::zero()))
{
segment.comparison_mut(comparison)[method] = Some(val);
}
for segment in segments {
segment.comparison_mut(comparison)[method] = None;
}
}
pub fn generate_for_timing_method(
segments: &mut [Segment],
method: TimingMethod,
goal_time: TimeSpan,
comparison: &str,
) {
let mut skill_curve = SkillCurve::new();
generate_for_timing_method_with_buf(
segments,
method,
Some(goal_time),
comparison,
&mut skill_curve,
);
}
pub fn generate(segments: &mut [Segment], goal_time: Time, comparison: &str) {
let mut skill_curve = SkillCurve::new();
if let Some(real_time) = goal_time.real_time {
generate_for_timing_method_with_buf(
segments,
TimingMethod::RealTime,
Some(real_time),
comparison,
&mut skill_curve,
);
} else {
for segment in &mut *segments {
segment.comparison_mut(comparison).real_time = None;
}
}
if let Some(game_time) = goal_time.game_time {
generate_for_timing_method_with_buf(
segments,
TimingMethod::GameTime,
Some(game_time),
comparison,
&mut skill_curve,
);
} else {
for segment in &mut *segments {
segment.comparison_mut(comparison).game_time = None;
}
}
}