use crate::calendar::{CalendarSelection, CalendarState, CalendarStyle, Month};
use chrono::NaiveDate;
use ratatui_core::buffer::Buffer;
use ratatui_core::layout::{Alignment, Direction, Rect};
use ratatui_core::style::Style;
use ratatui_core::widgets::StatefulWidget;
use ratatui_widgets::block::Block;
use std::collections::HashMap;
use std::marker::PhantomData;
use std::mem;
#[derive(Debug, Default)]
pub struct Calendar3<'a, Selection> {
direction: Direction,
months: [Month<'a, Selection>; 3],
phantom: PhantomData<Selection>,
}
impl<'a, Selection> Calendar3<'a, Selection> {
pub fn new() -> Self
where
Selection: Default,
{
Self::default()
}
#[inline]
pub fn locale(mut self, loc: chrono::Locale) -> Self {
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).locale(loc);
}
self
}
#[inline]
pub fn direction(mut self, direction: Direction) -> Self {
self.direction = direction;
self
}
#[inline]
pub fn show_weekdays(mut self) -> Self {
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).show_weekdays();
}
self
}
#[inline]
pub fn styles(mut self, s: CalendarStyle) -> Self {
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).styles(s.clone());
}
self
}
pub fn select_style(mut self, style: Style) -> Self {
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).select_style(style);
}
self
}
pub fn focus_style(mut self, style: Style) -> Self {
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).focus_style(style);
}
self
}
#[inline]
pub fn day_style(mut self, s: impl Into<Style>) -> Self {
let s = s.into();
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).day_style(s);
}
self
}
#[inline]
pub fn day_styles(mut self, styles: &'a HashMap<NaiveDate, Style>) -> Self {
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).day_styles(styles);
}
self
}
#[inline]
pub fn week_style(mut self, s: impl Into<Style>) -> Self {
let s = s.into();
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).week_style(s);
}
self
}
#[inline]
pub fn weekday_style(mut self, s: impl Into<Style>) -> Self {
let s = s.into();
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).weekday_style(s);
}
self
}
#[inline]
pub fn title_style(mut self, s: impl Into<Style>) -> Self {
let s = s.into();
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).title_style(s);
}
self
}
#[inline]
pub fn title_align(mut self, a: Alignment) -> Self {
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).title_align(a);
}
self
}
#[inline]
pub fn block(mut self, b: Block<'a>) -> Self {
for i in 0..3 {
self.months[i] = mem::take(&mut self.months[i]).block(b.clone());
}
self
}
}
impl<Selection> StatefulWidget for Calendar3<'_, Selection>
where
Selection: CalendarSelection,
{
type State = CalendarState<3, Selection>;
#[allow(deprecated)]
fn render(mut self, area: Rect, buf: &mut Buffer, state: &mut Self::State) {
state.area = area;
state.inner = area;
state.widget_area = area;
match self.direction {
Direction::Horizontal => {
let width = self.months[0].width();
let height = self
.months
.iter()
.enumerate()
.map(|(i, v)| v.height(&state.months[i]))
.max()
.expect("height");
let mut area = Rect::new(area.x, area.y, width, height);
for i in 0..3 {
mem::take(&mut self.months[i]).render(area, buf, &mut state.months[i]);
area.x += area.width + 2;
}
}
Direction::Vertical => {
let width = self.months[0].width();
let mut area = Rect::new(area.x, area.y, width, 0);
for i in 0..3 {
area.height = self.months[i].height(&state.months[0]);
mem::take(&mut self.months[i]).render(area, buf, &mut state.months[i]);
area.y += area.height + 1;
}
}
}
}
}