use std::io::{Write, Read};
use ncurses::*;
const REGULAR_PAIR: i16 = 0;
const HIGHLIGHTED_PAIR: i16 = 1;
#[derive(Default)]
struct Manage {
todos: Vec<String>,
dones: Vec<String>
}
impl Manage {
fn initialize(&mut self) {
let mut file = match std::fs::File::open("TO-DO") {
Ok(file) => file,
Err(_) => return
};
let mut contents = String::new();
file.read_to_string(&mut contents).expect("Failed to read");
for line in contents.lines() {
if line == "" { continue; }
let line = line.to_string();
if line.starts_with("TODO:") {
self.todos.push(line[6..].to_string());
} else {
self.dones.push(line[6..].to_string());
}
};
}
fn make_frame(&mut self, tab: bool, highlight: usize) {
clear();
if tab {
addstr("[TODO] DONE ");
for (index, todo) in self.todos.iter().enumerate() {
let pair = if highlight == index {HIGHLIGHTED_PAIR}
else {REGULAR_PAIR};
mv((index+1).try_into().unwrap(), 0);
attr_on(COLOR_PAIR(pair));
addstr("[ ] - ");
addstr(todo);
attr_off(COLOR_PAIR(pair));
}
mv((self.todos.len() + 1).try_into().unwrap(), 0);
addstr("------------------------------");
mv((self.todos.len() + 2).try_into().unwrap(), 0);
addstr("Add new task (a): ");
} else {
addstr(" TODO [DONE]");
for (index, done) in self.dones.iter().enumerate() {
let pair = if highlight == index {HIGHLIGHTED_PAIR}
else {REGULAR_PAIR};
mv((index+1).try_into().unwrap(), 0);
attr_on(COLOR_PAIR(pair));
addstr("[*] - ");
addstr(done);
attr_off(COLOR_PAIR(pair));
}
}
}
fn swap(&mut self, tab: bool, highlight: usize) {
if tab {
if self.todos.len() > 0 {
self.dones.push(self.todos.get(highlight).unwrap().to_string());
self.todos.swap_remove(highlight);
}
} else {
if self.dones.len() > 0 {
self.todos.push(self.dones.get(highlight).unwrap().to_string());
self.dones.swap_remove(highlight);
}
}
}
fn add_task(&mut self) {
curs_set(CURSOR_VISIBILITY::CURSOR_VISIBLE);
mv((self.todos.len() + 2).try_into().unwrap(), 18);
let mut new_task = String::new();
getstr(&mut new_task);
self.todos.push(new_task);
curs_set(CURSOR_VISIBILITY::CURSOR_INVISIBLE);
}
fn delete(&mut self, highlight: usize) {
self.todos.swap_remove(highlight);
}
fn end(&mut self) {
let mut file = std::fs::File::create("TO-DO")
.expect("Create Failed");
for todo in self.todos.iter(){
file.write_all(format!("TODO: {}\n", todo).as_bytes())
.expect("Write Failed");
}
for done in self.dones.iter(){
file.write_all(format!("DONE: {}\n", done).as_bytes())
.expect("Write Failed");
}
}
}
fn main() {
let mut ui = Manage::default();
ui.initialize();
initscr();
start_color();
curs_set(CURSOR_VISIBILITY::CURSOR_INVISIBLE);
init_pair(REGULAR_PAIR, COLOR_WHITE, COLOR_BLACK);
init_pair(HIGHLIGHTED_PAIR, COLOR_BLACK, COLOR_WHITE);
let mut quit = false;
let mut tab = true;
let mut curr_high = 0;
while !quit {
ui.make_frame(tab, curr_high);
refresh();
let key = getch();
match key as u8 as char {
'q' => quit = true,
'\t' => if tab{tab = false; curr_high = 0}
else {tab = true; curr_high = 0;},
'w' => if curr_high > 0 { curr_high -= 1; },
's' => if tab {
if curr_high < ui.todos.len() - 1 {curr_high += 1;}
} else {
if curr_high < ui.dones.len() - 1 { curr_high += 1;}
},
'\n' => {
ui.swap(tab, curr_high);
if curr_high > 0 {
curr_high -= 1;
}
},
'a' => if tab { ui.add_task() },
'd' => if tab {
ui.delete(curr_high);
if curr_high > 0 {
curr_high -= 1;
}
},
_ => {}
}
}
ui.end();
curs_set(CURSOR_VISIBILITY::CURSOR_VISIBLE);
endwin();
}