87326787fce1dee1195c9cce1ac0b45cec79d0e9
[taskasaur.git] / taskasaur.c
1
2 #include "headers/parser.h"
3 #include "headers/render.h"
4 #include "headers/menu.h"
5 #include "headers/utils.h"
6 #include "config.h"
7
8 // this is temp
9 #define MENU_WIDTH 40
10
11 typedef struct BoardMenu {
12     Menu** menu_list;
13     int menu_count;
14     int selected;
15 } BoardMenu;
16
17 BoardMenu* create_board_menu(Board* board);
18 int set_selected_menu(BoardMenu* boardmenu, int index);
19
20 MenuItem** todolist_to_menuitem(TodoItem** item_list, int list_length);
21 Menu** make_menus(Board* board, int todolist_length);
22 int swap_menu(BoardMenu* boardmenu, int src_index, int dest_index);
23
24 int
25 main(int argc, char** argv)
26 {
27     /* read from todo file */
28     Board* board;
29     board = begin_parse("test_board.md");
30     /* log_todo(board); */
31
32     /* init curses */
33     init_tscurses();
34
35     BoardMenu* boardmenu;
36     boardmenu = create_board_menu(board);
37
38     // this is temp
39     for (int i = 0; i < boardmenu->menu_count; i++) {
40         render_menu(boardmenu->menu_list[i]);
41     }
42
43     char ch;
44     while ((ch = getch()) != BINDING_QUIT) {
45
46         Menu* active_menu;
47         active_menu = boardmenu->menu_list[boardmenu->selected];
48
49         switch (ch) {
50
51             case BINDING_SCROLL_UP:
52                 menu_driver(active_menu, MENU_UP);
53                 break;
54             case BINDING_SCROLL_DOWN:
55                 menu_driver(active_menu, MENU_DOWN);
56                 break;
57             case BINDING_SCROLL_LEFT:
58                 if (boardmenu->selected-1 < 0) break;
59                 set_selected_menu(boardmenu, boardmenu->selected-1);
60                 break;
61             case BINDING_SCROLL_RIGHT:
62                 if (boardmenu->selected+1 > boardmenu->menu_count-1) break;
63                 set_selected_menu(boardmenu, boardmenu->selected+1);
64                 break;
65             case BINDING_JUMP_TOP:
66                 menu_driver(active_menu, MENU_TOP);
67                 break;
68             case BINDING_JUMP_BOTTOM:
69                 menu_driver(active_menu, MENU_BOTTOM);
70                 break;
71             case BINDING_MOVE_ITEM_UP:
72                 menu_driver(active_menu, MENU_MOVE_UP);
73                 break;
74             case BINDING_MOVE_ITEM_DOWN:
75                 menu_driver(active_menu, MENU_MOVE_DOWN);
76                 break;
77             case BINDING_MOVE_ITEM_LEFT:
78                 if (boardmenu->selected-1 < 0) break;
79                 {
80                     Menu* from_menu;
81                     Menu* to_menu;
82
83                     from_menu = boardmenu->menu_list[boardmenu->selected],
84                     to_menu = boardmenu->menu_list[boardmenu->selected-1],
85
86                     insert_item(
87                         to_menu,
88                         get_menu_item(
89                             from_menu,
90                             get_selected_item(from_menu)
91                         ),
92                         min(
93                             get_selected_item(from_menu),
94                             get_menu_length(to_menu)
95                         )
96                     );
97                     delete_item(
98                         from_menu,
99                         get_selected_item(from_menu) 
100                     );
101                     set_selected_menu(boardmenu, boardmenu->selected-1);
102                 }
103
104                 break;
105             case BINDING_MOVE_ITEM_RIGHT:
106                 if (boardmenu->selected >= boardmenu->menu_count-1) break;
107                 // this is legit cpy paste please fix this
108                 {
109                     Menu* from_menu;
110                     Menu* to_menu;
111
112                     from_menu = boardmenu->menu_list[boardmenu->selected],
113                     to_menu = boardmenu->menu_list[boardmenu->selected+1],
114
115                     insert_item(
116                         to_menu,
117                         get_menu_item(
118                             from_menu,
119                             get_selected_item(from_menu)
120                         ),
121                         min(
122                             get_selected_item(from_menu),
123                             get_menu_length(to_menu)
124                         )
125                     );
126                     delete_item(
127                         from_menu,
128                         get_selected_item(from_menu) 
129                     );
130                     set_selected_menu(boardmenu, boardmenu->selected+1);
131                 }
132
133                 break;
134             case BINDING_DELETE_ITEM:
135                 menu_driver(active_menu, MENU_DELETE);
136                 break;
137             case BINDING_APPEND_ITEM:
138                 menu_driver(active_menu, MENU_APPEND);
139                 break;
140             case BINDING_INSERT_ABOVE:
141                 menu_driver(active_menu, MENU_INSERT_ABOVE);
142                 break;
143             case BINDING_INSERT_BELOW:
144                 menu_driver(active_menu, MENU_INSERT_BELOW);
145                 break;
146             /* case BINDING_MOVE_MENU_LEFT: */
147             /*     if (boardmenu->selected-1 < 0) break; */
148
149             /*     swap_menu(boardmenu, boardmenu->selected, boardmenu->selected-1); */
150                 /* boardmenu->selected -= 1; */
151                 /* set_selected_menu(boardmenu, boardmenu->selected); */
152
153 /*                 break; */
154 /*             case BINDING_MOVE_MENU_RIGHT: */
155 /*                 if (boardmenu->selected >= boardmenu->menu_count-1) break; */
156 /*                 swap_menu(boardmenu, boardmenu->selected, boardmenu->selected+1); */
157                 /* boardmenu->selected += 1; */
158                 /* set_selected_menu(boardmenu, boardmenu->selected); */
159
160                 break;
161             case BINDING_EDIT_ITEM:
162                 menu_driver(active_menu, MENU_EDIT);
163                 break;
164         }
165
166         for (int i = 0; i < boardmenu->menu_count; i++) {
167             render_menu(boardmenu->menu_list[i]);
168         }
169
170
171     }
172
173     exit_tscurses();
174     return 0;    
175 }
176
177 BoardMenu*
178 create_board_menu(Board* board)
179 {
180     BoardMenu* new_boardmenu;
181
182     new_boardmenu = malloc(sizeof(BoardMenu));
183
184     new_boardmenu->menu_list = make_menus(board, board->todolist_count);
185     new_boardmenu->menu_count = board->todolist_count;
186     new_boardmenu->selected = 0;
187
188     return new_boardmenu;
189 }
190
191 int
192 set_selected_menu(BoardMenu* boardmenu, int index)
193 {
194     Menu* old_menu;
195     Menu* new_menu;
196     int new_pos;
197     
198     old_menu = boardmenu->menu_list[boardmenu->selected];
199     new_menu = boardmenu->menu_list[index];
200
201     set_menu_focus(old_menu, false);
202     set_menu_focus(new_menu, true);
203
204     /* also try to jump to a similar position if possible */
205     /* rn theres a bug if old menu is empty */
206     new_pos = min(get_selected_item(old_menu), get_menu_length(new_menu)-1);
207     set_selected_item(new_menu, new_pos);
208
209     boardmenu->selected = index;
210
211     return 0;
212 }
213
214 MenuItem** 
215 todolist_to_menuitem(TodoItem** item_list, int list_length)
216 {
217     MenuItem** items;
218
219     items = malloc((list_length+1)*sizeof(MenuItem*));
220     for (int i = 0; i < list_length; i++) {
221         items[i] = create_menuitem(item_list[i]->item_name);
222     }
223
224     items[list_length] = 0; //null terminate
225     return items;
226 }
227
228 Menu**
229 make_menus(Board* board, int todolist_length)
230 {
231
232     Menu** menu_list;
233
234     menu_list = malloc(todolist_length*sizeof(Menu*));
235
236     for (int i = 0; i < todolist_length; i++) {
237
238         /* read from parsed */
239         TodoList* todo_list = board->todolist_list[i];
240         MenuItem** item_list = todolist_to_menuitem(todo_list->item_list, todo_list->item_count);
241
242         Menu* new_menu = create_menu(todo_list->list_name, item_list);
243
244         /* make window */
245         WINDOW* win = newwin(20, MENU_WIDTH, 1, 1+MENU_WIDTH*i);
246         box(win, 0, 0);
247
248         /* some menu settings */
249         set_menu_win(new_menu, win);
250         set_menu_focus(new_menu, i == 0); // make first win focused
251
252         /* refresh */
253         refresh();
254         wrefresh(win);
255
256         menu_list[i] = new_menu;
257     }
258
259     return menu_list;
260 }
261
262 int
263 swap_menu(BoardMenu* boardmenu, int src_index, int dest_index)
264 {
265     /* reposition menus */
266     mvwin(get_menu_win(boardmenu->menu_list[src_index]),
267         1, 1+MENU_WIDTH*dest_index
268     );
269     mvwin(get_menu_win(boardmenu->menu_list[dest_index]),
270         1, 1+MENU_WIDTH*src_index
271     );
272     wrefresh(get_menu_win(boardmenu->menu_list[src_index]));
273     wrefresh(get_menu_win(boardmenu->menu_list[dest_index]));
274     /* wclear(get_menu_win(boardmenu->menu_list[src_index])); */
275     /* wclear(get_menu_win(boardmenu->menu_list[dest_index])); */
276     /* touchwin(get_menu_win(boardmenu->menu_list[src_index])); */
277     /* touchwin(get_menu_win(boardmenu->menu_list[dest_index])); */
278     clear();
279
280     /* swap in array */
281     ar_swap_item(boardmenu->menu_list, src_index, dest_index);
282
283     return 0;
284 }
285