966907bb1a4aeb0676e542c388aff96eef9137b1
[taskasaur.git] / taskasaur.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <signal.h>
5 #include <unistd.h>
6 #include <ncurses.h>
7 #include <menu.h>
8
9 void winch_handler(int sig); 
10
11 char** read_todo(FILE* file, int* length);
12
13 WINDOW* create_win(int height, int width, int y, int x);
14 MENU* create_todo_menu(WINDOW* win, char** todo_list, int todo_length);
15
16 void on_select(char *item);
17
18 void free_todo(char** todo_list, int todo_length);
19
20 #include "config.h"
21
22 #define SELECTED_COLOR 1
23 #define NON_SELECTED_COLOR 2
24
25 int 
26 main(int argc, char** argv) 
27 {
28     int flag;
29     FILE* board_file;
30     char** todos;
31     int todo_length;
32
33     int height, width;
34     int ch;
35
36     WINDOW* todo_win;
37     MENU* todo_menu;
38
39     signal(SIGWINCH, winch_handler);
40
41     // read command line args
42     flag = getopt(argc, argv, "o:n:");
43     switch (flag) {
44         case 'o':
45
46             // read from task file (might need to check for read and write permissions)
47             board_file = fopen(optarg, "r");
48             if (!board_file) {
49                 printf("%s does not exist\n", optarg);
50                 return 1;
51             }   
52             
53             todos = read_todo(board_file, &todo_length);
54             fclose(board_file);
55
56             break;
57
58         case 'n':
59
60             // make sure file does not exist
61             // however, it maybe be possible that an different error has occured (besides the file not existing)
62             if (access(optarg, F_OK) == 0) { 
63                 printf("%s already exists\n", optarg);
64                 return 1;
65             }
66             // create a file here
67             board_file = fopen(optarg, "w");
68             // write init stuff here
69             fclose(board_file);
70             printf("Successfully created %s\n", optarg);
71
72             todos = malloc(0);
73             todo_length = 0;
74
75             break;
76
77         case -1:
78         case '?':
79             printf("Help string\n");
80             return 2;
81     }
82
83     // start ncurses 
84     initscr();
85     cbreak();
86     noecho();
87     curs_set(0);
88     keypad(stdscr, TRUE);
89     start_color();
90
91     /* colors */
92     init_pair(SELECTED_COLOR, selected_color, COLOR_BLACK);
93     init_pair(NON_SELECTED_COLOR, non_selected_color, COLOR_BLACK);
94
95     getmaxyx(stdscr, height, width);
96
97     todo_win = create_win(20, 40, 5, 5);
98     todo_menu = create_todo_menu(todo_win, todos, todo_length);
99     post_menu(todo_menu);
100     refresh();
101     wrefresh(todo_win);
102     
103     while ((ch = getch()) != BINDING_QUIT) {
104         
105         switch (ch) {
106             case BINDING_SCROLL_UP:
107                 menu_driver(todo_menu, REQ_UP_ITEM);
108                 break;
109             case BINDING_SCROLL_DOWN:
110                 menu_driver(todo_menu, REQ_DOWN_ITEM);
111                 break;
112             case BINDING_JUMP_TOP:
113                 menu_driver(todo_menu, REQ_FIRST_ITEM);
114                 break;
115             case BINDING_JUMP_BOTTOM:
116                 menu_driver(todo_menu, REQ_LAST_ITEM);
117                 break;
118             case BINDING_SELECT:
119                 break;
120         } 
121         wrefresh(todo_win);
122
123     }
124
125     endwin();
126
127     /* Free mem */
128     unpost_menu(todo_menu);
129     free_todo(todos, todo_length);
130
131     return 0;
132 }
133
134 void 
135 winch_handler(int sig) 
136 {
137     endwin();
138     refresh();
139 }
140
141 char**
142 read_todo(FILE* file, int* length) 
143 { // apparently getline isn't rly that portable, so consider other options
144     char** out_arr;
145     int out_len;
146     char* lineptr;
147     size_t len;
148     ssize_t nread;
149
150     out_arr = NULL;
151     out_len = 0;
152     lineptr = NULL;
153     len = 0;
154
155     while ((nread = getline(&lineptr, &len, file)) != -1) {
156         out_len++;
157         out_arr = realloc(out_arr, (sizeof(char*))*out_len); // bad to keep resizing?
158
159         lineptr[strcspn(lineptr, "\n")] = 0; // remove newline
160         out_arr[out_len-1] = lineptr;
161
162         lineptr = NULL;
163     }
164     
165     *length = out_len;
166     return out_arr;
167 }
168
169 WINDOW* 
170 create_win(int height, int width, int y, int x)
171 {
172     WINDOW* new_win = newwin(height, width, y, x);
173     wrefresh(new_win);
174     return new_win;
175 }
176
177 MENU*
178 create_todo_menu(WINDOW* win, char** todo_list, int todo_length)
179 {
180     MENU* todo_menu;
181     ITEM** item_list;
182     ITEM* cur_item;
183     int wheight, wwidth;
184
185     item_list = malloc((todo_length+1)*sizeof(ITEM*));
186     for (int i = 0; i < todo_length; i++) {
187         item_list[i] = new_item(todo_list[i], "");
188         set_item_userptr(item_list[i], on_select);
189     }
190     item_list[todo_length] = NULL; // last item needs to be a null pointer for some reason?
191
192     todo_menu = new_menu(item_list);
193
194     getmaxyx(win, wheight, wwidth);
195     set_menu_win(todo_menu, win);
196     set_menu_sub(todo_menu, derwin(win, wheight-2, wwidth-2, 1, 2));
197     set_menu_mark(todo_menu, "");
198     set_menu_spacing(todo_menu, 1, 2, 1);
199     set_menu_fore(todo_menu, COLOR_PAIR(SELECTED_COLOR));
200     set_menu_back(todo_menu, COLOR_PAIR(NON_SELECTED_COLOR));
201
202     box(win, 0, 0); //temp
203
204     return todo_menu;
205 }
206
207 void
208 on_select(char *item)
209 {
210     printf("lol");
211 }
212
213 void
214 free_todo(char** todo_list, int todo_length)
215 {
216     // probably check if list is too short or too long
217     for (int i = 0; i < todo_length; i++) {
218         free(todo_list[i]); 
219     }
220     free(todo_list);
221 }