mod sm2;
mod records;
mod slide;
mod events;
mod cards;
pub mod errors;
use records::*;
use slide::Slide;
use std::io;
use termion::raw::IntoRawMode;
use termion::event::Key;
use tui::Terminal;
use tui::backend::TermionBackend;
use tui::layout::{Constraint,Direction,Layout};
use events::Event;
use errors::Res;
const DEFAULT: usize = 20;
pub fn start_tui(file : &str, num: Option<usize>) -> Res<()> {
let stdout = io::stdout().into_raw_mode()?;
let backend = TermionBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let events = events::setup_events();
let records = Records::read_file(file)?.records();
let num = num.unwrap_or(DEFAULT);
let mut cards = cards::Cards::from(records).select(num);
terminal.clear()?;
while let Some(_) = cards.next() {
let record = cards.current_record();
let mut slide = Slide::default().record(record);
let mut exit_called = false;
let mut exit = || exit_called = true;
while let Some(step) = slide.step() {
let final_step = step == 2;
let record = slide.clone();
terminal.draw(|f| {
let h2 = 3u16;
let h1 = f.size().height - h2;
let section = Layout::default()
.direction(Direction::Vertical)
.constraints(
[
Constraint::Length(h1),
Constraint::Length(h2),
]
).split(f.size());
f.render_widget(record.clone(),section[0]);
f.render_widget(cards.status(),section[1]);
})?;
match events.recv().unwrap() {
Event::Refresh => (),
Event::Key(key) => match key {
Key::Char(' ') => if !final_step { slide.cont() },
Key::Char('\n') => if final_step { slide.cont() },
Key::Char('l') | Key::Right => if final_step {slide.next()},
Key::Char('h') | Key::Left => if final_step {slide.prev()},
Key::Char('q') | Key::Esc => { exit(); break },
Key::Ctrl('c') | Key::Ctrl('d') => { exit(); break },
_ => (),
},
};
}
if exit_called { break }
let rating = slide.rating();
cards.review_current_card(rating);
};
let records = cards.records();
let records = Records::from(records);
records.write_to_file(file)?;
terminal.clear()?;
Ok(())
}
pub fn generate_sample() -> Res<()> {
let sample =
r#"
# Structure each new card in the format below.
# Deckster will generate additional metadata for each
# card and store it in this file. Avoid editing
# the metadata.
#
# Uncomment the block below to begin.
#
# [[card]]
# question = 'question 1'
# answer = 'answer 1'
"#;
println!("{}",sample);
Ok(())
}