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