#[derive(Debug, Default, Clone, Copy)]
pub struct PointsCounter {
    total_points: f64,
    last_best_dist: f64,
    delta_acc: f64,
    delta_total: f64,
}

const INSTANT_SPEED_WEIGHT: f64 = 3.0;
const AVERAGE_SPEED_WEIGHT: f64 = 1.0;

impl PointsCounter {
    pub fn new() -> PointsCounter {
        PointsCounter::default()
    }

    pub fn process(&mut self, delta: f64, dist: f64) {
        if delta <= 0.0 {
            return;
        }
        self.delta_acc += delta;
        self.delta_total += delta;
        if self.delta_acc <= 0.0 || self.delta_total <= 0.0 {
            return;
        }
        let delta_dist = dist - self.last_best_dist;
        if delta_dist > 0.0 {
            let average_speed = dist / self.delta_total;
            self.total_points += AVERAGE_SPEED_WEIGHT * delta * average_speed;
            let instant_speed = delta_dist / self.delta_acc;
            self.total_points += INSTANT_SPEED_WEIGHT * delta_dist * instant_speed;

            self.delta_acc = 0.0;
            self.last_best_dist = dist;
        }
    }

    pub fn score(&self) -> i32 {
        let tmp: f64 = self.total_points;
        tmp as i32
    }

    pub fn best_row(&self) -> isize {
        self.last_best_dist.round() as isize
    }

    pub fn best_dist(&self) -> f64 {
        self.last_best_dist
    }
}
