use crate::{
clock_display::{ClockDisplay, DisplayPart},
clock_state::ClockState,
};
use stm32f1xx_hal::timer;
#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(usize)]
pub enum DisplayView {
ClockView = 0,
ClockSecondsView = 1,
ClockDateView = 2,
DateView = 3,
}
impl TryFrom<usize> for DisplayView {
fn try_from(value: usize) -> Result<Self, ()> {
if value <= DisplayView::DateView as usize {
unsafe { core::mem::transmute(value) }
} else {
Err(())
}
}
type Error = ();
}
#[derive(Copy, Clone, PartialEq, Eq)]
#[repr(usize)]
#[derive(core::marker::ConstParamTy)]
pub enum ClockPart {
Hours = 0,
Minutes = 1,
Seconds = 2,
Year = 3,
Month = 4,
Day = 5,
}
impl TryFrom<usize> for ClockPart {
fn try_from(value: usize) -> Result<Self, ()> {
if value <= ClockPart::Day as usize {
unsafe { core::mem::transmute(value) }
} else {
Err(())
}
}
type Error = ();
}
pub struct ClockDisplayViewer {
clock_display: ClockDisplay,
parts: [bool; core::mem::variant_count::<ClockPart>()],
}
impl ClockDisplayViewer {
pub fn new(clock_display: ClockDisplay) -> Self {
Self {
clock_display,
parts: [false; core::mem::variant_count::<ClockPart>()],
}
}
pub fn show(&mut self, part: ClockPart) {
self.parts[part as usize] = true;
}
pub fn hide(&mut self, part: ClockPart) {
self.parts[part as usize] = false;
}
pub fn hide_all(&mut self) {
for part in self.parts.iter_mut() {
*part = false;
}
}
pub fn clock_display(&mut self) -> &mut ClockDisplay {
&mut self.clock_display
}
pub fn set_current_view(&mut self, view: DisplayView) {
self.hide_all();
match view {
DisplayView::ClockView => {
self.show(ClockPart::Hours);
self.show(ClockPart::Minutes);
}
DisplayView::ClockSecondsView => {
self.show(ClockPart::Hours);
self.show(ClockPart::Minutes);
self.show(ClockPart::Seconds);
}
DisplayView::ClockDateView => {
self.show(ClockPart::Hours);
self.show(ClockPart::Minutes);
self.show(ClockPart::Day);
self.show(ClockPart::Month);
}
DisplayView::DateView => {
self.show(ClockPart::Day);
self.show(ClockPart::Month);
self.show(ClockPart::Year);
}
}
}
pub fn update(&mut self, state: &ClockState) -> nb::Result<(), timer::Error> {
self.clock_display.update()?;
for (i, show) in self.parts.iter().enumerate().filter(|(_, x)| **x) {
if !show {
continue;
}
let part: ClockPart = ClockPart::try_from(i).unwrap();
match part {
ClockPart::Day => {
self.clock_display
.show_ordinal(
DisplayPart::SideDisplay1,
state.calendar().day() as u32,
true,
)
.unwrap();
}
ClockPart::Month => {
self.clock_display
.show_ordinal(
DisplayPart::SideDisplay2,
state.calendar().month() as u32,
true,
)
.unwrap();
}
ClockPart::Year => {
self.clock_display
.show_number(
DisplayPart::MainDisplay,
state.calendar().year() as u32,
true,
)
.unwrap();
}
ClockPart::Hours => {
self.clock_display
.show_number_at(
ClockDisplay::get_part_offset(DisplayPart::MainDisplay),
2,
state.calendar().hours() as u32,
true,
)
.unwrap();
}
ClockPart::Minutes => {
self.clock_display
.show_number_at(
ClockDisplay::get_part_offset(DisplayPart::MainDisplay) + 2,
2,
state.calendar().minutes() as u32,
true,
)
.unwrap();
}
ClockPart::Seconds => {
self.clock_display
.show_number(
DisplayPart::SideDisplay2,
state.calendar().seconds() as u32,
true,
)
.unwrap();
}
}
}
if !self.parts[ClockPart::Day as usize] {
self.clock_display.hide(DisplayPart::SideDisplay1);
}
if !self.parts[ClockPart::Month as usize] && !self.parts[ClockPart::Seconds as usize] {
self.clock_display.hide(DisplayPart::SideDisplay2);
}
if !self.parts[ClockPart::Hours as usize] && !self.parts[ClockPart::Year as usize] {
self.clock_display.hide_at(ClockDisplay::get_part_offset(DisplayPart::MainDisplay), 2);
}
if !self.parts[ClockPart::Minutes as usize] && !self.parts[ClockPart::Year as usize] {
self.clock_display.hide_at(ClockDisplay::get_part_offset(DisplayPart::MainDisplay) + 2, 2);
}
if self.parts[ClockPart::Hours as usize] && self.parts[ClockPart::Minutes as usize] {
self.clock_display
.set_colon(state.calendar().seconds() % 2 == 0);
} else {
self.clock_display.set_colon(false);
}
Ok(())
}
}