#[allow(unused_imports)]
use crate::{Region, Share, Tone};
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
#[non_exhaustive]
pub enum Unit {
#[default]
Minutes,
Days,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Span {
from: u16,
to: u16,
}
impl Span {
pub const DAY: Self = Self { from: 0, to: 1440 };
#[must_use]
pub const fn new(from: u16, to: u16) -> Self {
Self {
from,
to: if to > from { to } else { from + 1 },
}
}
#[must_use]
pub const fn from(self) -> u16 {
self.from
}
#[must_use]
pub const fn to(self) -> u16 {
self.to
}
#[must_use]
pub const fn length(self) -> u16 {
self.to - self.from
}
#[must_use]
pub const fn holds(self, minute: u16) -> bool {
minute >= self.from && minute < self.to
}
}
impl Default for Span {
fn default() -> Self {
Self::DAY
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Placement {
at: u16,
length: u16,
}
impl Placement {
#[must_use]
pub const fn new(at: u16, length: u16) -> Self {
Self {
at,
length: if length == 0 { 1 } else { length },
}
}
#[must_use]
pub const fn at(self) -> u16 {
self.at
}
#[must_use]
pub const fn length(self) -> u16 {
self.length
}
#[must_use]
pub const fn end(self) -> u16 {
self.at + self.length
}
#[must_use]
pub const fn overlaps(self, other: Self) -> bool {
self.at < other.end() && other.at < self.end()
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct Track {
pub span: Span,
pub slot: u16,
pub tick: u16,
pub unit: Unit,
}
impl Track {
pub const DAY: Self = Self {
span: Span::DAY,
slot: 15,
tick: 60,
unit: Unit::Minutes,
};
#[must_use]
pub const fn over(span: Span) -> Self {
Self {
span,
slot: 15,
tick: 60,
unit: Unit::Minutes,
}
}
#[must_use]
pub const fn days(span: Span) -> Self {
Self {
span,
slot: 1,
tick: 7,
unit: Unit::Days,
}
}
#[must_use]
pub const fn slots(self) -> u16 {
if self.slot == 0 {
1
} else {
self.span.length().div_ceil(self.slot)
}
}
#[must_use]
pub fn fraction(self, minute: u16) -> f32 {
let span = f32::from(self.span.length());
let offset = f32::from(minute.saturating_sub(self.span.from()));
(offset / span).clamp(0.0, 1.0)
}
}
impl Default for Track {
fn default() -> Self {
Self::DAY
}
}